91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++ OpenCV怎么實現卡片截取功能

發布時間:2021-11-26 10:47:44 來源:億速云 閱讀:121 作者:小新 欄目:大數據

這篇文章將為大家詳細講解有關C++ OpenCV怎么實現卡片截取功能,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

實現效果

今天我照了一張自己健身卡的圖片,然后想到實現整體切邊的效果,先上一下源圖

C++ OpenCV怎么實現卡片截取功能

最終我們想到實現在照片中只保留卡這塊的部分。

代碼演示

我們再新建一個項目名為opencv--qiebian,按照配置屬性(VS2017配置OpenCV通用屬性),然后在源文件寫入#include和main方法.

C++ OpenCV怎么實現卡片截取功能

上面我們把加載出來的圖片用resize來調整了一下大小,一開始加載出來超過滿屏了,不方便我們處理。


第一步   先把圖片轉為灰度圖

C++ OpenCV怎么實現卡片截取功能

顯示效果為

C++ OpenCV怎么實現卡片截取功能


第二步   用Canny邊緣提取

C++ OpenCV怎么實現卡片截取功能

我們來看看顯示效果

C++ OpenCV怎么實現卡片截取功能

可以看到右邊就是我們通過邊緣提取后的圖片效果


第三步   發現尋找輪廓

C++ OpenCV怎么實現卡片截取功能

運行后再看看效果

C++ OpenCV怎么實現卡片截取功能

可以看出來,我們邊緣提取后找到了1332個輪廓,這個輪廓中我們只需要找到我們想到的卡信息,所以我們就來到下一步


第四步   定義最小的輪廓寬高,畫出想要的輪廓

可以看到圖中卡片占了圖片一半以上,所以我們可以直接考慮輪廓的大小大于源圖像一半就是我們要少的輪廓了,其余的輪廓就可以忽略了,這樣可以節省很多時間,代碼如下:

C++ OpenCV怎么實現卡片截取功能

C++ OpenCV怎么實現卡片截取功能

然后我們看看運行效果

C++ OpenCV怎么實現卡片截取功能

可以看出,我們要找到矩形完全不是我們想要的結果,在紅色的輪廓里面發現卡片和桌面上的紋理連到一起了,說明我們在Canny邊緣提取的時候需要進行二值化處理,去掉一些不用的結果


第五步   對源圖像進行Canny閾值重新修改看看

我們回到Canny邊緣提取那,把邊緣提取的閾值重修改一下

C++ OpenCV怎么實現卡片截取功能

然后我們重新運行起來看看什么效果

C++ OpenCV怎么實現卡片截取功能

發現右邊通過賦值后不像原來桌面上那么多紋理了,但是從左邊獲取的矩形框后發現也完全不是我們想要的東西。要怎么解決這個問題呢?

一開始我想過了在Canny邊緣提取前先二值化操作一下,最終倒是實現了,但是這個要不停的修改閾值參數,不太方便,還有別的什么辦法呢?這時候我想起來,剛開始學最基本的形態學操作的時候用到的,開操作和閉操作。我們這就來試一下,根據上面的情況,我選擇的閉操作,也就是先膨脹后腐蝕的效果

C++ OpenCV怎么實現卡片截取功能

然后我們再來看看運行的效果

C++ OpenCV怎么實現卡片截取功能

經過閉操作后,可以看出右邊的圖我們過濾掉了非常多沒有必要的東西,也獲取到了最后我們的綠色畫出的矩形框,自我滿足了一下!!!!


第六步   提取到我們要的圖像

我們先修改一下上面定義的參數,這樣下在我們截取的時候就可以用到這個矩形了,下面是我們在復制一份src_gray,因為原圖中src我們已經畫上紅色和綠色線了,畫之前先存一個備份到src_gray里。

C++ OpenCV怎么實現卡片截取功能

然后我們提取最后生成的矩形

C++ OpenCV怎么實現卡片截取功能

最后我們看看生成的結果

C++ OpenCV怎么實現卡片截取功能

右邊就是我們完美截取的卡片圖像,成功~~~~


總結一下實現流程

  1. 加載圖片

  2. 轉為灰度圖

  3. 圖像高斯模糊

  4. 進行閉操作(先膨脹后腐蝕)

  5. Canny邊緣提取

  6. 尋找輪廓

  7. 輪廓中查找符合要求的項

  8. 獲取上一步中對應項的最小矩形

  9. 從源圖像中截取最小矩形生成新圖片

以上是我自己實驗生成的效果,如果有更好的方法請消息我,畢竟我也是初學者~~


main單元代碼

#include <opencv2\opencv.hpp>
#include <iostream>

cv::Mat src, src_gray, dst;
const char* imgsrc = "源圖"; const char* imgdst = "結果圖";
int main(int argc, char** argv) {
    src = cv::imread("E:/DCIM/testcard.jpg");
    if (src.empty()) {
        printf("could not read image....\n");
        getchar();
        return -1;
    }
    //由于加載圖像有點大,我們先調整圖像的大小為寬500,高300
    cv::resize(src, src, cv::Size(500, 300));
    cv::imshow(imgsrc, src);
    //把源圖轉為灰度圖
    cv::cvtColor(src, src_gray, CV_BGR2GRAY);
    cv::imshow(imgdst, src_gray);

    //高斯模糊后加Canny邊緣提取
    cv::GaussianBlur(src_gray, dst, cv::Size(3, 3), 0.5, 0.5, 4);

    //定義結構元素
    cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,
        cv::Size(5, 5), cv::Point(-1, -1));
    //閉操作
    cv::morphologyEx(dst, dst, CV_MOP_CLOSE, element);

    //Canny邊緣提取
    cv::Canny(dst, dst, 120, 255);

    //定義輪廓點及查找輪廓
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;
    //尋找輪廓
    cv::findContours(dst, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
    //打印出一共找到了多少個輪廓
    printf("contours count:%d\n", contours.size());

    //定義要找的輪廓最小的寬高
    int minw = dst.cols*0.5;
    int minh = dst.rows*0.5;
    //定義矩形的四個點
    cv::RotatedRect minRect;
    cv::Point2f vertices[4];
    for (size_t t = 0; t < contours.size(); t++) {
        //尋找最小矩形
        minRect = cv::minAreaRect(contours[t]);
        //獲取傾斜角度
        double degree = abs(minRect.angle);
        //判斷最小矩形太于我們設置的最小寬和高在獲取數據
        if (minRect.size.width > minw && minRect.size.height > minh) {
            printf("current rect: %d\n", t);
            printf("current angle : %f\n", degree);

            //在源圖像上用紅色畫出輪廓樣
            src.copyTo(src_gray);//先復制一份src到src_gray里面,下面備用
            cv::drawContours(src, contours, t, cv::Scalar(0, 0, 255),
                1,8,hierarchy,0);

            //在源圖像上用綠色畫出矩形框,定義了4個點,然后用直線畫4個點
            minRect.points(vertices);
            for (int i = 0; i < 4; i++) {
                cv::line(src, vertices[i], vertices[(i + 1) % 4],
                    cv::Scalar(0, 255, 0));
            }
            break;
        }
    }
    cv::imshow(imgsrc, src);

    //根據獲取的最小矩形截取出圖像顯示出來
    cv::Rect rect = minRect.boundingRect();
    dst = src_gray(rect);

    cv::imshow(imgdst, dst);

    cv::waitKey(0);
    return 0;
}

關于“C++ OpenCV怎么實現卡片截取功能”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

遂川县| 齐河县| 青河县| 桦川县| 金乡县| 广水市| 辉南县| 汶川县| 阜新| 福鼎市| 息烽县| 巴林左旗| 佛学| 全南县| 米林县| 新竹市| 乌兰察布市| 克拉玛依市| 莆田市| 西平县| 霍邱县| 庐江县| 蒙阴县| 乾安县| 山西省| 临漳县| 保定市| 富宁县| 获嘉县| 民县| 堆龙德庆县| 墨江| 河南省| 宁陕县| 阿坝县| 绥中县| 武鸣县| 社会| 赣州市| 咸阳市| 康平县|