最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ OpenCV實(shí)戰(zhàn)之網(wǎng)孔檢測(cè)的實(shí)現(xiàn)

 更新時(shí)間:2022年05月05日 15:46:47   作者:Zero___Chen  
這篇文章主要介紹了如何利用C++和OpenCV實(shí)現(xiàn)網(wǎng)孔檢測(cè),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,感興趣的小伙伴可以了解一下

前言

前段時(shí)間,有位粉絲私信我,給我發(fā)了一張圖片,如下圖所示:

在這里貼出他的原話。

從他給的圖片分析,該圖存在遮擋,所以不能簡(jiǎn)單的二值化,然后提取圖像輪廓去尋找結(jié)果。所以,我就想如何去掉這些遮擋物(即圖像修復(fù))。從圖像可知,該遮擋物是黃色的線,所以,我就想可否使用hsv色彩空間提取出黃色,然后得到二值掩模圖像,最后對(duì)原圖進(jìn)行修復(fù)。接下來(lái),就一起看看是如何一步步實(shí)現(xiàn)的吧。

一、HSV通道轉(zhuǎn)換

通過(guò)hsv通道轉(zhuǎn)換,可以提取出圖像中的黃色分量。

    //hsv顏色通道轉(zhuǎn)換,提取圖像中黃色線部分,生成掩膜圖像
    Mat hsv;
    cvtColor(src, hsv, COLOR_BGR2HSV);

    Mat mask;
    inRange(hsv, Scalar(10, 50, 255), Scalar(40, 255, 255), mask);

結(jié)果如圖所示:

二、圖像修復(fù)

關(guān)于圖像修復(fù)的相關(guān)知識(shí)可以參考我之前的博文。這里就不細(xì)說(shuō)了。

OpenCV C++案例實(shí)戰(zhàn)十四《圖像修復(fù)》

OpenCV C++案例實(shí)戰(zhàn)十七《圖像去水印》

我們拿到上面的mask掩模圖像,需要對(duì)其進(jìn)行膨脹處理,使修復(fù)區(qū)域范圍擴(kuò)大。

    //將生成的掩膜mask膨脹一下,使掩膜區(qū)域放大
    Mat kernel = getStructuringElement(MORPH_RECT, Size(9, 9));
    dilate(mask, mask, kernel);

接下來(lái),需要對(duì)圖像進(jìn)行修復(fù)。這里我提供兩種修復(fù)方法,一種是OpenCV提供的inpaint函數(shù),一種是我自己寫的。

2.1 OpenCV函數(shù)實(shí)現(xiàn)

    //使用OpenCV自帶的inpaint函數(shù)進(jìn)行圖像修復(fù),得到目標(biāo)圖像
    Mat inpaintImg;
    inpaint(src, mask, inpaintImg, 1, INPAINT_NS);

效果如圖所示。

2.2 MyFunction

通過(guò)修改圖像像素達(dá)到圖像修復(fù)的效果。具體請(qǐng)看源碼注釋。

    //自己寫的算法,修改圖像像素,完成圖像修復(fù)
    Mat canvas = Mat::zeros(src.size(), src.type());
    int r = 1;//像素查找范圍--表示在該像素點(diǎn)上下幾行像素進(jìn)行查找
    for (int i = r; i < src.rows- r; i++)
    {
        for (int j = 0; j < src.cols; j++)
        {        
            if (mask.at<uchar>(i, j) != 255)
            {   
                //對(duì)于非掩膜區(qū)域,直接將原像素進(jìn)行像素賦值
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(i, j)[c];
                }          
            }
            else
            {
                //找到距離該掩膜像素點(diǎn)最近的非掩膜區(qū)域像素進(jìn)行賦值
                Point res = find_Nearest_Point(mask, i, j, r);
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(res.x, res.y)[c];
                }
            }
        }
    }

效果如何所示

三、輪廓提取

接下來(lái)我們只需要對(duì)修復(fù)之后的圖像進(jìn)行輪廓提取就可以了。

    //將修復(fù)之后的目標(biāo)圖像進(jìn)行圖像預(yù)處理,提取輪廓
    Mat gray;
    cvtColor(canvas, gray, COLOR_BGR2GRAY);

    Mat gaussian;
    GaussianBlur(gray, gaussian, Size(3, 3), 0);

    Mat thresh;
    threshold(gaussian, thresh, 30, 255, THRESH_BINARY_INV);

    Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(thresh, thresh, MORPH_OPEN, kernel);

    //namedWindow("thresh", WINDOW_NORMAL);
    //imshow("thresh", thresh);

    //輪廓提取
    vector<vector<Point>>contours;
    findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    //經(jīng)過(guò)面積,外接矩形特征篩選出目標(biāo)區(qū)域
    vector<vector<Point>>EffectiveConts;
    for (int i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);

        if (area>100)
        {
            Rect rect = boundingRect(contours[i]);

            if (double(rect.height) > 30 && double(rect.width) > 30)
            {
                EffectiveConts.push_back(contours[i]);
            }
        }
    }

四、效果顯示

    for (int i = 0; i < EffectiveConts.size(); i++)
    {
        //計(jì)算輪廓矩
        Moments Mo = moments(EffectiveConts[i]);
        //計(jì)算質(zhì)心--即插孔坐標(biāo)
        Point center = Point(Mo.m10 / Mo.m00, Mo.m01 / Mo.m00);
        //效果繪制
        Rect rect = boundingRect(EffectiveConts[i]);
        rectangle(src, rect, Scalar(0, 255, 0), 5);
        circle(src, center, 3, Scalar(0, 0, 255), -1);
    }

如圖為該案例最終效果。

五、源碼

#include<opencv2/opencv.hpp>
#include <iostream>
#include<opencv2/photo.hpp>
using namespace std;
using namespace cv;

double EuDis(Point pt1, Point pt2)
{
    return sqrt(pow(pt1.x - pt2.x, 2) + pow(pt1.y - pt2.y, 2));
}

Point find_Nearest_Point(Mat mask , int currentrow, int currentcol, int r)
{  
    double mindis = 100000.0;
    Point res(0,0);

    //查找該像素點(diǎn)上下r行像素,找到最接近該像素的非掩膜區(qū)域像素
    for (int i = currentrow - r; i < currentrow + r; i++)
    {
        for (int j = 0; j < mask.cols; j++)
        {
            if (mask.at<uchar>(i, j) != 255)
            {
                //Point(currentrow, currentcol) 表示當(dāng)前需要賦值的掩膜像素點(diǎn)
                double dis = EuDis(Point(currentrow, currentcol), Point(i, j));
                if (dis < mindis)
                {
                    mindis = dis;
                    res = Point(i, j); //目標(biāo)像素點(diǎn)
                }
            }
        }
    }

    return res;
}

int main()
{
    Mat src = imread("test.jpg");
    if (src.empty())
    {
        cout << "No Image!" << endl;
        system("pause");
        return -1;
    }
  
    //hsv顏色通道轉(zhuǎn)換,提取圖像中黃色線部分,生成掩膜圖像
    Mat hsv;
    cvtColor(src, hsv, COLOR_BGR2HSV);

    Mat mask;
    inRange(hsv, Scalar(10, 50, 255), Scalar(40, 255, 255), mask);
	
    //將生成的掩膜mask膨脹一下,使掩膜區(qū)域放大
    Mat kernel = getStructuringElement(MORPH_RECT, Size(9, 9));
    dilate(mask, mask, kernel);

    //使用OpenCV自帶的inpaint函數(shù)進(jìn)行圖像修復(fù),得到目標(biāo)圖像
    //Mat inpaintImg;
    //inpaint(src, mask, inpaintImg, 1, INPAINT_NS);
    //namedWindow("inpaintImg", WINDOW_NORMAL);
    //imshow("inpaintImg", inpaintImg);

    //自己寫的算法,修改圖像像素,完成圖像修復(fù)
    Mat canvas = Mat::zeros(src.size(), src.type());
    int r = 1;//像素查找范圍--表示在該像素點(diǎn)上下幾行像素進(jìn)行查找
    for (int i = r; i < src.rows- r; i++)
    {
        for (int j = 0; j < src.cols; j++)
        {        
            if (mask.at<uchar>(i, j) != 255)
            {   
                //對(duì)于非掩膜區(qū)域,直接將原像素進(jìn)行像素賦值
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(i, j)[c];
                }          
            }
            else
            {
                //找到距離該掩膜像素點(diǎn)最近的非掩膜區(qū)域像素進(jìn)行賦值
                Point res = find_Nearest_Point(mask, i, j, r);
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(res.x, res.y)[c];
                }
            }
        }
    }
    //namedWindow("canvas", WINDOW_NORMAL);
    //imshow("canvas", canvas);

    //將修復(fù)之后的目標(biāo)圖像進(jìn)行圖像預(yù)處理,提取輪廓
    Mat gray;
    cvtColor(canvas, gray, COLOR_BGR2GRAY);

    Mat gaussian;
    GaussianBlur(gray, gaussian, Size(3, 3), 0);

    Mat thresh;
    threshold(gaussian, thresh, 30, 255, THRESH_BINARY_INV);

    Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(thresh, thresh, MORPH_OPEN, kernel);

    //namedWindow("thresh", WINDOW_NORMAL);
    //imshow("thresh", thresh);

    //輪廓提取
    vector<vector<Point>>contours;
    findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    //經(jīng)過(guò)面積,外接矩形特征篩選出目標(biāo)區(qū)域
    vector<vector<Point>>EffectiveConts;
    for (int i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);

        if (area>100)
        {
            Rect rect = boundingRect(contours[i]);

            if (double(rect.height) > 30 && double(rect.width) > 30)
            {
                EffectiveConts.push_back(contours[i]);
            }
        }
    }

    for (int i = 0; i < EffectiveConts.size(); i++)
    {
        //計(jì)算輪廓矩
        Moments Mo = moments(EffectiveConts[i]);
        //計(jì)算質(zhì)心--即插孔坐標(biāo)
        Point center = Point(Mo.m10 / Mo.m00, Mo.m01 / Mo.m00);
        //效果繪制
        Rect rect = boundingRect(EffectiveConts[i]);
        rectangle(src, rect, Scalar(0, 255, 0), 5);
        circle(src, center, 3, Scalar(0, 0, 255), -1);
    }

    namedWindow("src", WINDOW_NORMAL);
    imshow("src", src);
    waitKey(0);
	system("pause");
    return 0;
}

總結(jié)

本文使用OpenCV C++實(shí)現(xiàn)網(wǎng)孔檢測(cè),主要操作有以下幾點(diǎn)。

1、hsv通道轉(zhuǎn)換,提取出黃色分量,得到掩模圖像。

2、利用掩模圖像對(duì)原圖進(jìn)行圖像修復(fù)。

3、通過(guò)輪廓提取定位網(wǎng)孔位置。

以上就是C++ OpenCV實(shí)戰(zhàn)之網(wǎng)孔檢測(cè)的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于C++ OpenCV網(wǎng)孔檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言簡(jiǎn)明清晰講解枚舉

    C語(yǔ)言簡(jiǎn)明清晰講解枚舉

    枚舉法的本質(zhì)就是從所有候選答案中去搜索正確的解,枚舉算法簡(jiǎn)單粗暴,他暴力的枚舉所有可能,盡可能地嘗試所有的方法,感興趣的朋友來(lái)看看吧
    2022-05-05
  • Embarcadero?Dev-C++輸出中文亂碼問(wèn)題圖文詳解

    Embarcadero?Dev-C++輸出中文亂碼問(wèn)題圖文詳解

    Dev-C++(或者叫做 Dev-Cpp)是Windows環(huán)境下的一個(gè)輕量級(jí)C/C++ 集成開發(fā)環(huán)境(IDE),下面這篇文章主要給大家介紹了關(guān)于Embarcadero?Dev-C++輸出中文亂碼問(wèn)題的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • C++ 中私有繼承的作用

    C++ 中私有繼承的作用

    這篇文章主要介紹了C++ 中私有繼承的作用的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • C++ I/O文件讀寫操作的示例代碼

    C++ I/O文件讀寫操作的示例代碼

    這篇文章主要介紹了C++ I/O文件讀寫操作的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • C語(yǔ)言五子棋小游戲?qū)崿F(xiàn)代碼

    C語(yǔ)言五子棋小游戲?qū)崿F(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言五子棋小游戲?qū)崿F(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 獲取C語(yǔ)言中int類型的最大值的方法小結(jié)

    獲取C語(yǔ)言中int類型的最大值的方法小結(jié)

    在C語(yǔ)言中,int?類型的大小通常是根據(jù)系統(tǒng)架構(gòu)來(lái)決定的,在大多數(shù)現(xiàn)代系統(tǒng)上,int?通常是32位的,在C語(yǔ)言中,獲取int類型的最大值有幾種不同的方法,下面,我們將討論兩種方法:使用標(biāo)準(zhǔn)庫(kù)函數(shù)和使用算法,需要的朋友可以參考下
    2024-06-06
  • C++全面細(xì)致講解復(fù)數(shù)類

    C++全面細(xì)致講解復(fù)數(shù)類

    本文章向大家介紹C++ 標(biāo)準(zhǔn)庫(kù)中的復(fù)數(shù)類,主要包括C++ 標(biāo)準(zhǔn)庫(kù)中的復(fù)數(shù)類使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-06-06
  • C++編寫簡(jiǎn)單的打靶游戲

    C++編寫簡(jiǎn)單的打靶游戲

    這篇文章主要介紹了使用C++編寫簡(jiǎn)單的打靶游戲,本人也是個(gè)菜鳥,水平有限,有錯(cuò)誤遺漏的地方在所難免,大家看看就好。
    2015-03-03
  • 詳解VisualS tudio Code開發(fā)Arm嵌入式Linux應(yīng)用

    詳解VisualS tudio Code開發(fā)Arm嵌入式Linux應(yīng)用

    本文介紹如何在 Visual Studio Code 中使用 Yocto Project 生成的 Linux SDK,并針對(duì) Arm 處理器進(jìn)行 C/C++ 應(yīng)用交叉編譯和調(diào)試,感興趣的朋友跟隨小編一起看看吧
    2021-04-04
  • c++ 盡量不要使用#define 而是用const、enum、inline替換。

    c++ 盡量不要使用#define 而是用const、enum、inline替換。

    為什么這么說(shuō)呢?或許很多程序員已經(jīng)習(xí)慣在文件開始使用大量的#define語(yǔ)句
    2013-01-01

最新評(píng)論

张北县| 壤塘县| 南漳县| 沾化县| 屯留县| 昭苏县| 云阳县| 清徐县| 开阳县| 新巴尔虎左旗| 江口县| 新巴尔虎左旗| 博乐市| 昂仁县| 土默特右旗| 贺兰县| 布尔津县| 利川市| 蓝田县| 诸城市| 新化县| 德安县| 汕头市| 蒙阴县| 阿拉善盟| 高尔夫| 宜城市| 嘉荫县| 温泉县| 沾化县| 德惠市| 象州县| 谷城县| 岐山县| 宁安市| 张掖市| 庄河市| 台前县| 黎平县| 汝州市| 金川县|