Opencv——findContours函數再探(由輪廓聯想連通域)

目錄

    • 關于調參的一些思考
    • 分析圖像的一些角度
    • 面積、周長、矩形度、圓形度、寬長比
    • 例1:找出汽車輪轂圓孔(從輪廓和連通域兩個角度)
    • 例2:找出芯片中間正方形物體
    • 例3:桌面上橘色物體
    • 總結

關于調參的一些思考

合理的參數設置,應該是基于對需要解決的問題的一些已知條件。如需要提取的線段的長度范圍,需要定位的工件的尺寸、大小(面積)、形狀,周長,矩形度,圓形度等。

分析圖像的一些角度

1.從算法上
圖像降噪,直方圖增強,二值化,頻率分析,圖像形態學,幾何信息 提取,特征提取,等各種數學方法。 盡可能多的輸出結果。
2.從策略上
篩選出實際需要的結果。
把握需要的信息和干擾信息的本質差距。

面積、周長、矩形度、圓形度、寬長比

圓形度
最小外接矩形
寬敞比
這里不做具體分析,以后專門寫一篇筆記。

例1:找出汽車輪轂圓孔(從輪廓和連通域兩個角度)

原圖:
原圖
分析:
1、獲取二值圖像(選用二值化閾值或者canny算子掃描)
2、通過findContours函數尋找連通域,輪廓則是對應連通域的輪廓
3、通過minAreaRect函數獲取輪廓最小矩形框(可旋轉),利改矩形框的特征來鎖定目標(這里我們限制,矩形框的長寬比值在1附近,并且矩形框的寬度大于10)
4、對鎖定的輪廓,通過drawContours函數繪制輪廓(注意參數,倒數第二個填-1則為填該改輪廓,類似漫水填充,不過漫水填充不能獲取輪廓特征)
另一種思路:
1、獲取二值圖像(這里為了使圓圈內部為白,使用反閾值)
2、利用connectedComponentsWithStats函數獲取連通域矩陣
3、通過狀態矩陣statsMat,來獲取連通域最小外接四邊形 (bounding box)的 x, y, width,height和面 積(像素數量)
4、通過四邊形的條件來限制

思路1代碼:

int main()
{cv::Mat srcMat = imread("D:\\opencv_picture_test\\rim.png", 1);Mat dstMat, binMat;cvtColor(srcMat, dstMat, COLOR_BGR2GRAY);threshold(dstMat, binMat, 0, 255, THRESH_OTSU);imshow("bin", binMat);//通過findContours函數尋找連通域vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(binMat, contours, RETR_LIST,CHAIN_APPROX_NONE);//繪制輪廓,內填充for (int i = 0; i < contours.size(); i++) {RotatedRect rbox = minAreaRect(contours[i]);if (fabs(rbox.size.width * 1.0 / rbox.size.height - 1) < 0.1 && rbox.size.width > 10)drawContours(srcMat, contours, i, Scalar(0, 255, 255), -1, 8);}imshow("rim", srcMat);waitKey(0);
}

二值圖:
二值圖
框定圖:
框定圖
思路2代碼:

int main()
{Mat lableMat;Mat statsMat;Mat centerMat;Mat srcMat = imread("D:\\opencv_picture_test\\輪廓\\rim.png", 1);		//讀取灰度Mat dstMat;cvtColor(srcMat, srcMat, COLOR_BGR2GRAY);//調用閾值函數threshold(srcMat, dstMat, 120, 255,THRESH_BINARY_INV);//腐蝕操作//Mat element = getStructuringElement(MORPH_ELLIPSE, Size(9,9));		//morphologyEx(dstMat,dstMat, MORPH_ERODE, element);		int nComp = cv::connectedComponentsWithStats(dstMat,lableMat,statsMat,centerMat,8,CV_32S);for (int i = 1; i < nComp; i++){cout << "pixels = " << statsMat.at<int>(i, 4) << endl;cout << "width = " << statsMat.at<int>(i, 2) << endl;cout << "height = " << statsMat.at<int>(i, 3) << endl;cout << endl;}for (int i = 1; i < nComp; i++){Rect bndbox;bndbox.x = statsMat.at<int>(i, 0);bndbox.y = statsMat.at<int>(i, 1);bndbox.width = statsMat.at<int>(i, 2);bndbox.height = statsMat.at<int>(i, 3);if (fabs(bndbox.width * 1.0 / bndbox.height - 1) < 0.1 && bndbox.width > 30)rectangle(srcMat, bndbox, CV_RGB(255, 255, 255), 1, 8, 0);}imshow("src", srcMat);//imshow("dst", dstMat);waitKey(0);
}

效果圖:
結果

例2:找出芯片中間正方形物體

原圖:
原圖
分析:
1、獲取二值圖像(選用二值化閾值或者canny算子掃描)
2、通過findContours函數尋找連通域,輪廓則是對應連通域的輪廓
3、通過minAreaRect函數獲取輪廓最小矩形框(可旋轉),利改矩形框的特征來鎖定目標(這里我們限制,矩形框的長寬比值在1附近,并且矩形框的寬度大于10)
4、對鎖定的輪廓,通過drawContours函數繪制輪廓
5、通過輪廓外最小矩形的四個頂點坐標,來繪制邊框
另一種思路:
1、獲取二值圖像(這里為了使圓圈內部為白,使用反閾值)
2、利用connectedComponentsWithStats函數獲取連通域矩陣
3、通過狀態矩陣statsMat,來獲取連通域最小外接四邊形 (bounding box)的 x, y, width,height和面 積(像素數量)
4、通過四邊形的條件來限制
最小矩形
思路1代碼:

*--------------------------【練習2】矩形框-------------------------------------*/
int main()
{cv::Mat srcMat = imread("D:\\opencv_picture_test\\輪廓\\die_on_chip.png", 1);Mat dstMat, binMat;cvtColor(srcMat, dstMat, COLOR_BGR2GRAY);threshold(dstMat, binMat, 0, 255, THRESH_OTSU);imshow("bin", binMat);//通過findContours函數尋找連通域vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(binMat, contours, RETR_LIST, CHAIN_APPROX_NONE);//繪制輪廓for (int i = 0; i < contours.size(); i++) {RotatedRect rbox = minAreaRect(contours[i]);if (fabs(rbox.size.width * 1.0 / rbox.size.height - 1) < 0.1 && rbox.size.width > 10){drawContours(srcMat, contours, i, Scalar(0, 255, 255), 1, 8);Point2f vtx[4];rbox.points(vtx);for (int j = 0; j < 4; ++j) {cv::line(srcMat, vtx[j], vtx[j < 3 ? j + 1 : 0], Scalar(0, 0, 255), 3, LINE_AA);}}}imshow("die_on_chip", srcMat);waitKey(0);
}

結果
思路2代碼:

*--------------------------【練習1連通域解法】-------------------------------------*/int main()
{Mat lableMat;Mat statsMat;Mat centerMat;Mat srcMat = imread("D:\\opencv_picture_test\\輪廓\\die_on_chip.png", 1);		//讀取灰度Mat dstMat;cvtColor(srcMat, srcMat, COLOR_BGR2GRAY);//調用閾值函數threshold(srcMat, dstMat, 120, 255,THRESH_BINARY);//腐蝕操作//Mat element = getStructuringElement(MORPH_ELLIPSE, Size(9,9));		//morphologyEx(dstMat,dstMat, MORPH_ERODE, element);		int nComp = cv::connectedComponentsWithStats(dstMat,lableMat,statsMat,centerMat,8,CV_32S);for (int i = 1; i < nComp; i++){cout << "pixels = " << statsMat.at<int>(i, 4) << endl;cout << "width = " << statsMat.at<int>(i, 2) << endl;cout << "height = " << statsMat.at<int>(i, 3) << endl;cout << endl;}for (int i = 1; i < nComp; i++){Rect bndbox;bndbox.x = statsMat.at<int>(i, 0);bndbox.y = statsMat.at<int>(i, 1);bndbox.width = statsMat.at<int>(i, 2);bndbox.height = statsMat.at<int>(i, 3);if (fabs(bndbox.width * 1.0 / bndbox.height - 1) < 0.2 && statsMat.at<int>(i, 4)>=1200)rectangle(srcMat, bndbox, CV_RGB(0, 255, 255), 1, 8, 0);}imshow("src", srcMat);//imshow("dst", dstMat);waitKey(0);
}

效果圖:
思路2

例3:桌面上橘色物體

分析:
1、RGB轉HSV圖
2、將HSV通道分離,獲取三個通道值
3、對S通道進行二值化處理
4、接下來按照上面兩題的思路,找輪廓,框定。、
代碼:

//*--------------------------【練習3】矩形框-------------------------------------*/
int main()
{cv::Mat srcMat = imread("D:\\opencv_picture_test\\輪廓\\topic1.jpg", 1);Mat dstMat, binMat;cvtColor(srcMat, dstMat, COLOR_BGR2HSV);vector<Mat> channels;split(dstMat, channels);//namedWindow("H", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口//imshow("H", channels.at(0));namedWindow("S", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口imshow("S", channels.at(1));//namedWindow("V", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口//imshow("V", channels.at(2));//將S通道的圖像復制,然后處理Mat S_Mat;channels.at(1).copyTo(S_Mat);//namedWindow("S", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口//imshow("S", S_Mat);threshold(S_Mat, binMat, 120, 255, THRESH_BINARY);namedWindow("bin", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口imshow("bin", binMat);//通過findContours函數尋找連通域vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(binMat, contours, RETR_LIST, CHAIN_APPROX_NONE);//繪制輪廓for (int i = 0; i < contours.size(); i++) {RotatedRect rbox = minAreaRect(contours[i]);if (fabs(rbox.size.width * 1.0 / rbox.size.height - 1) < 0.3 && rbox.size.width > 10){drawContours(srcMat, contours, i, Scalar(0, 255, 255), 1, 8);Point2f vtx[4];rbox.points(vtx);for (int j = 0; j < 4; ++j) {cv::line(srcMat, vtx[j], vtx[j < 3 ? j + 1 : 0], Scalar(255, 255, 255), 2, LINE_AA);}}}namedWindow("topic1", WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口imshow("topic1", srcMat);waitKey(0);return 0;}

S通道圖:
S
用S通道進行二值化:
二值圖
框定圖:
框定圖

總結

從目前來看,框定目標物體我們從輪廓和連通域都可以。
其中,利用minAreaRect函數可以獲取輪廓最小矩形框的參數值,也包括了輪廓的部分信息。
利用connectedComponentsWithStats獲取連通域,可從中獲取的連通域信息。
利用這些信息,結合矩形度、圓形度、寬長比等數學特征則可以剔除一些不符合特征的備選項。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378605.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378605.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378605.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

stl vector 函數_vector :: crend()函數以及C ++ STL中的示例

stl vector 函數C vector :: crend()函數 (C vector::crend() function) vector::crend() is a library function of "vector" header, it is used to get the first element of a vector from reverse ending, it returns a const reverse iterator pointing to th…

.Net DateTime.ToString 格式化輸出 (轉載)

原文 雖然 System.DateTime 本身已經具有了不少現成的格式化輸出&#xff0c;例如&#xff1a; ToLongDateString, ToShortTimeString, ToUniversalTime 等&#xff0c;但是卻遠遠不能滿足我們實際的需要&#xff0c;這就要用到了 DateTime.ToString&#xff0c;就要提到 DateT…

modelsim 編譯 xilinx庫

1.為單個工程加入庫 在某一個目錄建立工程 然后 vlib unisim vcom -work unsim *.vhd 然后就加入了unisim庫 如果是windows的話&#xff0c;工程文件mpf應該是記錄了這個庫的信息&#xff0c;所以重新打開這個工程時&#xff0c;依然有這個庫 linux&#xff0c;不用gui界面…

php 字符串匹配 like,ThinkPHP like模糊查詢,like多匹配查詢,between查詢,in查詢,一般查詢書寫方法...

搜索熱詞ThinkPHP的數據庫條件查詢語句有字符串式&#xff0c;數組式書寫方法字符串式即是原生式&#xff0c;數組式查詢語句因書寫方式與特定字符的原因比較復雜&#xff0c;下面為大家例出了常用的ThinkPHP數組式查詢語句的使用方法ThinkPHP一般查詢$data_gt[id]array(gt,8);…

C++---漢明距離

兩個整數之間的漢明距離指的是這兩個數對應二進制位不同的位置的數目。 【輸入形式】 給出兩個整數x和y(0<x,y<2^31)&#xff0c;用空格分隔 【輸出形式】 輸出他們之間的漢明距離 【樣例輸出】 1 4 【樣例說明】 00000000 00000000 00000000 00000001 00000000 00000000…

Opencv基礎畫圖函數——line、circle、rectangle、Rect、ellipse、polylines、putText函數的用法

目錄1、line函數2、circle函數3、rectangle、Rect函數4、ellipse函數5、polylines函數6、隨機初始化顏色7、putText函數總結1、line函數 line(img,(0,0),(511,511),(255,0,0),5)這個函數有5個參數&#xff0c;img是圖像名稱&#xff0c;起點坐標&#xff0c;終點坐標&#xff…

GCC 里面的一些命令

記錄一下常用GCC 相關的命令和參數 ldd ---> print share library dependenciy LD_LIBRARY_PATH---> environment variable, it will search the path accord to this variable. Also check the ldd to verify this environmental variable ldconfig-----> configure…

理解關聯容器“map”的關鍵點

map有一個構造函數: map<k, v> m(b, e); 《C Primer》解釋為&#xff1a;“創建 map 類型的對象 m&#xff0c; 存儲迭代器 b 和 e 標記的范圍內所有元素的副本&#xff0c;元素的類型必須能轉換為 pair<const k, v>”&#xff0c;這個構造函數理解起來沒有另外兩個…

c語言中圖形驅動程序功能_C / C ++中的圖形:一些更有趣的功能

c語言中圖形驅動程序功能In this Advance Learning Tutorial of C / C today, we are going to tell you about some of the functions that can be used to make the program more attractive. This works on both text and graphics modes. That is why knowing these funct…

php 載入css就可以顯示,如何在進度條加載后顯示頁面

1.思路&#xff1a;加入很多圖片&#xff0c;以延遲加載時間&#xff0c;實現加載完后顯示圖片。定義一個外層p&#xff0c;覆蓋住圖片&#xff0c;在內層p中引入加載時顯示的圖片&#xff0c;讓內層p居中在頁面上&#xff0c;利用setInterval定時器設置3秒后將外層p隱藏&#…

如何獲取輪廓(連通域)的面積、周長、矩形度、圓形度、寬長比、周徑比等形狀描述符?

博主聯系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里會有往屆的smarters和電賽選手&#xff0c;群里也會不時分享一些有用的資料&#xff0c;有問題可以在群里多問問。 目錄前言1、輪廓面積獲取函數2、輪廓周長獲取函數3、輪廓圓形度計算4、矩形度計算…

01-基礎部分

一、tensorflow和opencv測試 import tensorflow as tf import cv2hello tf.constant(hello tensorflow) session tf.Session() print(session.run(hello))print(hello opencv)運行效果如下&#xff1a; 二、基礎部分 1、opencv基礎 代碼三部曲&#xff1a; 1、引入Open…

網絡和通信 - Silverlight 中的 HTTP 通信和安全

Silverlight 支持幾種使用 HTTP/HTTPS 的方案。雖然可以使用多種方式和技術執行 HTTP 調用&#xff0c;但是下表描述的是針對這些 HTTP 通信方案的建議方法 執行 HTTP 調用的選項 確定應由瀏覽器還是客戶端來執行應用程序的 HTTP 處理后&#xff0c;應在創建任何 Web 請求之前指…

linux下g++和gcc_Linux中gcc和g ++有什么區別?

linux下g和gccgcc和g 之間的區別 (Difference between gcc and g) Both are the compilers in Linux to compile and run C and C programs. Initially gcc was the GNU C Compiler but now a days GCC (GNU Compiler Collections) provides many compilers, two are: gcc and …

WT2605C高品質音頻藍牙語音芯片:外接功放實現雙聲道DAC輸出的優勢

在音頻處理領域&#xff0c;雙聲道DAC輸出能夠提供更為清晰、逼真的音效&#xff0c;增強用戶的聽覺體驗。針對這一需求&#xff0c;唯創知音的WT2605C高品質音頻藍牙語音芯片&#xff0c;通過外接功放實現雙聲道DAC輸出&#xff0c;展現出獨特的應用優勢。 一、高品質音頻處理…

對c++primer 16.6.1的第4小節的代碼說明

這段代碼是這樣的: template<typename T>int compare(const T& t1,const T& t2){ cout<<"范型"<<endl; return 1;} int main(){   cout<<compare("hello","world")<<endl;} template<> int compa…

php curl form-data,在php curl multipart / form-data請求中發送一個文件和json數據

我正在嘗試在PHP的curl請求中上傳文件和json數據 . 請求在命令行中使用curl正常工作 . 這是命令行中的curl請求&#xff1a;curl -v --basic -uusername -F file"documentTest.pdf;typeapplication/octet-stream" -F data{"nomDocument":"test.pdf&qu…

角點檢測(Harris角點檢測法)

博主聯系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里會有往屆的smarters和電賽選手&#xff0c;群里也會不時分享一些有用的資料&#xff0c;有問題可以在群里多問問。 目錄原理講解【1】為何選取角點作為特征&#xff1f;【2】角點的定義&#xff1a;…

02-圖像的幾何變換

一、圖片縮放 imageInfo&#xff1a;圖片寬、高、通道個數等 縮放&#xff1a; 等比例縮放&#xff1a;寬高比不變 任意比例縮放&#xff1a;圖片拉伸、非拉伸 窗體大小 實現步驟&#xff1a; 1&#xff0c;完成圖像的加載&#xff0c;拿到圖像的數據信息 2&#xff0c;圖片的寬…

c ++查找字符串_C ++數組| 查找輸出程序| 套裝5

c 查找字符串Program 1: 程序1&#xff1a; #include <iostream>using namespace std;int main(){char* STR[] { "HELLO", "HIII", "RAM", "SHYAM", "MOHAN" };cout << (*STR 2)[2];return 0;}Output: 輸出&…