1. 程式人生 > >opencv--輪廓繪製

opencv--輪廓繪製

在這裡插入圖片描述

輪廓發現

  • 定義
    在這裡插入圖片描述
  • API
CV_EXPORTS_W void findContours( InputOutputArray image,
                                OutputArrayOfArrays contours,
                                OutputArray hierarchy, 
                                int mode,
                                int method, 
                                Point offset =
Point() );
  • 引數說明
    在這裡插入圖片描述
  1. 8位元單通道的源二值影象。非零畫素作為1處理,0畫素儲存不變。從一個灰度影象得到二值影象的函式有:cvThreshold,cvAdaptiveThreshold和cvCanny。

    如果第四個引數為cv::RETR_CCOMP或cv::RETR_FLOODFILL,輸入影象可以是32-bit整型影象(CV_32SC1)

  2. contours:檢測到的輪廓,每個輪廓都是以點向量的形式進行儲存即使用point型別的vector表示

  3. hierarchy:可選的輸出向量(std::vector),包含了影象的拓撲資訊,作為輪廓數量的表示hierarchy包含了很多元素,每個輪廓contours[i]對應hierarchy中hierarchy[i][0]~hierarchy[i][3],分別表示後一個輪廓,前一個輪廓,父輪廓,內嵌輪廓的索引,如果沒有對應項,則相應的hierarchy[i]設定為負數。

  4. mode輪廓檢索模式,可以通過cv::RetrievalModes()檢視詳細資訊

    mode 說明
    RETR_EXTERNAL 表示只檢測最外層輪廓,意思是影象中獨立的個體只檢測最外層輪廓,包含在裡面的輪廓不會提取出來。在這裡插入圖片描述
    RETR_LIST 提取所有輪廓,並放置在list中,不建立等級關係。意思就是提取出來的輪廓之間是沒有聯絡的。在這裡插入圖片描述
    RETR_CCOMP 提取所有輪廓,並且將其組織為雙邊結構。意思就是第一層為它的外圍輪廓,第二層為內圍輪廓,利用這個引數可以篩選出來一個獨立邊緣只對應一個輪廓在這裡插入圖片描述
    RETR_TREE 提取所有輪廓,並且重新建立網狀輪廓結構。它體現出來的輪廓聯絡很緊密,比如說一個輪廓在另外一個輪廓的裡面,輪廓裡面又包含輪廓。
  5. 邊緣近似方法(除了CV_RETR_RUNS使用內建的近似,其他模式均使用此設定的近似演算法)。可以通過cv::ContourApproximationModes()檢視詳細資訊 .

    method 說明
    CV_CHAIN_CODE 以Freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點的序列)
    CV_CHAIN_APPROX_NONE 獲取每個輪廓的每個畫素,相鄰的兩個點的畫素位置差不超過1
    CV_CHAIN_APPROX_SIMPLE 壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點座標,如果一個矩形輪廓只需4個點來儲存輪廓資訊
    CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用the flavors of Teh-Chinchain近似演算法的一種。
    CV_LINK_RUNS 通過連線水平段的1,使用完全不同的邊緣提取演算法。使用 CV_RETR_LIST檢索模式能使用此方法
  6. 偏移量,用於移動所有輪廓點。當輪廓是從影象的ROI提取的,並且需要在整個影象中分析時,這個引數將很有用。


輪廓繪製

  • 定義
CV_EXPORTS_W void drawContours( InputOutputArray image,
                                InputArrayOfArrays contours,
                                int contourIdx, 
                                const Scalar& color,
                                int thickness = 1, 
                                int lineType = LINE_8,
                                InputArray hierarchy = noArray(),
                                int maxLevel = INT_MAX, 
                                Point offset = Point() );
  • 引數
    在這裡插入圖片描述
    1. image:輸入需要最終輸出的影象,Mat型別即可
    2. contours:使用findContours檢測到的輪廓資料,每個輪廓以點向量的形式儲存,point型別的vector
    3. contourIdx:繪製輪廓的只是變數,如果為負值則繪製所有輸入輪廓
    4. color:輪廓顏色
    5. thickness:繪製輪廓所用線條粗細度,如果值為負值,則在輪廓內部繪製
    6. lineTpye:線條型別,有預設值LINE_8。
    7. hierarchy: 關於層級的可選引數,只有繪製部分輪廓時才會用到
    8. maxLevel: 用於繪製輪廓的最大等級 .畫輪廓的最大層數。
      如果是0,只繪製contour;
      如果是1,將繪製contour後和contour同層的所有輪廓;
      如果是2,繪製contour後所有同層和低一層的輪廓,
      以此類推;如果值是負值,則函式並不繪製contour後的輪廓,但是將畫出其子輪廓,一直到abs(max_level) - 1層。
    9. offset: 可選輪廓便宜引數,用制定偏移量offset=(dx, dy)給出繪製輪廓的偏移量

程式碼演示

在這裡插入圖片描述

Mat src, dst1,dst2,dst3;
char winName[] = "contour_dst3";
int track_size = 10;
int max_size = 100;

void onContour(int, void*) {
	Canny(dst1, dst2, track_size, track_size * 2);
	vector<vector<Point>>contours;
	vector<Vec4i>hierachy;
	//尋找輪廓
	findContours(dst2, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
	dst3 = Mat::zeros(src.size(), CV_8UC3);
	RNG rng(12345);
	for (size_t i = 0; i < contours.size(); i++)
	{
		Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
		drawContours(dst3, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
	}
	imshow(winName, dst3);
}
int main() {
	src = imread("D:\\fish.png");
	imshow("src", src);
	cvtColor(src, dst1, CV_BGR2GRAY);
	imshow("dst1",dst1);

	onContour(0, 0);
	createTrackbar("trackbar_step", winName, &track_size, max_size, onContour);
	//onContour(0, 0);

	waitKey(0);
	return 0;

}

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

分享好文章:
【OpenCV3】影象輪廓查詢與繪製——cv::findContours()與cv::drawContours()詳解
https://blog.csdn.net/guduruyu/article/details/69220296