有時候我們想找影像中某個物體,找到後要把它給標記出來,然後做後續處理,可以怎麼做呢?

我特地加入非純色的愛心
多虧OpenCV有提供現成的函式,就能輕易地找出物體的輪廓。
接下來會使用到幾個內建函式:
- findContours :- Find contours in the binary image.
- drawContours :- Draw filled contour or outline of contour.
- boundingRect :- Calculate a bounding rectangle for a contour.
- contourArea :- Calculate area for a specific contour.
/** Theme: Find Contours IDE: Xcode 7 Language: C++ Date: 105/03/28 Author: HappyMan Blog: https://cg2010studio.wordpress.com/ */ #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { int largest_area = 0; int largest_contour_index = 0; Rect bounding_rect; Mat src = imread("shape.jpg"); // Load source image Mat thr(src.rows, src.cols, CV_8UC1); Mat dst(src.rows, src.cols, CV_8UC3, Scalar::all(0)); cvtColor(src, thr, CV_BGR2GRAY); // Convert to gray threshold(thr, thr, 25, 255, THRESH_BINARY); // Threshold the gray vector<vector<Point>> contours; // Vector for storing contour vector<Vec4i> hierarchy; findContours(thr, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image Scalar color(0,0,255); for(int i = 0; i < contours.size(); i++) // Iterate through each contour { double a = contourArea(contours[i], false); // Find the area of contour if(a > largest_area){ largest_area = a; largest_contour_index = i; // Store the index of largest contour bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour } } for(int i = 0; i < contours.size(); i++) // Iterate through each contour { if (i != largest_contour_index) { drawContours(dst, contours, i, color, CV_FILLED, 8, hierarchy); } } Scalar color2(255,0,0); drawContours(dst, contours,largest_contour_index, color2, 5, 8, hierarchy); // Draw the largest contour using previously stored index. rectangle(src, bounding_rect, Scalar(0,255,0), 1, 8, 0); imshow("Happy Thread", thr); imshow("Happy Source", src); imshow("Happy Largest Contour", dst); // Wait for a keystroke in the window waitKey(0); return 0; }
執行後跳出三個影像:

灰階化後設閾值找到的輪廓

將最大輪廓給框住

最大輪廓以藍色畫非填滿,其它輪廓以紅色畫填滿
我特地設中斷點檢視最大輪廓(愛心)的座標點,index = 4總共有214個座標點:
[4] = size=214 {
[0] = (x = 687, y = 113)
[1] = (x = 686, y = 114)
[2] = (x = 680, y = 114)
[3] = (x = 679, y = 115)
[4] = (x = 677, y = 115)
[5] = (x = 676, y = 116)
[6] = (x = 674, y = 116)
[7] = (x = 673, y = 117)
[8] = (x = 671, y = 117)
[9] = (x = 670, y = 118)
[10] = (x = 669, y = 118)
[11] = (x = 667, y = 120)
[12] = (x = 666, y = 120)
[13] = (x = 664, y = 122)
[14] = (x = 663, y = 122)
[15] = (x = 655, y = 130)
[16] = (x = 655, y = 131)
[17] = (x = 653, y = 133)
[18] = (x = 653, y = 134)
[19] = (x = 651, y = 136)
[20] = (x = 651, y = 137)
[21] = (x = 650, y = 138)
[22] = (x = 650, y = 139)
[23] = (x = 649, y = 140)
[24] = (x = 649, y = 141)
[25] = (x = 648, y = 142)
[26] = (x = 648, y = 143)
[27] = (x = 647, y = 144)
[28] = (x = 647, y = 146)
[29] = (x = 646, y = 147)
[30] = (x = 646, y = 150)
[31] = (x = 645, y = 151)
[32] = (x = 645, y = 153)
[33] = (x = 644, y = 154)
[34] = (x = 644, y = 171)
[35] = (x = 645, y = 172)
[36] = (x = 645, y = 175)
[37] = (x = 646, y = 176)
[38] = (x = 646, y = 179)
[39] = (x = 647, y = 180)
[40] = (x = 647, y = 182)
[41] = (x = 648, y = 183)
[42] = (x = 648, y = 184)
[43] = (x = 649, y = 185)
[44] = (x = 649, y = 187)
[45] = (x = 650, y = 188)
[46] = (x = 650, y = 189)
[47] = (x = 651, y = 190)
[48] = (x = 651, y = 191)
[49] = (x = 652, y = 192)
[50] = (x = 652, y = 193)
[51] = (x = 654, y = 195)
[52] = (x = 654, y = 196)
[53] = (x = 655, y = 197)
[54] = (x = 655, y = 198)
[55] = (x = 657, y = 200)
[56] = (x = 657, y = 201)
[57] = (x = 660, y = 204)
[58] = (x = 660, y = 205)
[59] = (x = 664, y = 209)
[60] = (x = 664, y = 210)
[61] = (x = 684, y = 230)
[62] = (x = 685, y = 230)
[63] = (x = 690, y = 235)
[64] = (x = 691, y = 235)
[65] = (x = 694, y = 238)
[66] = (x = 695, y = 238)
[67] = (x = 698, y = 241)
[68] = (x = 699, y = 241)
[69] = (x = 701, y = 243)
[70] = (x = 702, y = 243)
[71] = (x = 705, y = 246)
[72] = (x = 706, y = 246)
[73] = (x = 708, y = 248)
[74] = (x = 709, y = 248)
[75] = (x = 711, y = 250)
[76] = (x = 712, y = 250)
[77] = (x = 714, y = 252)
[78] = (x = 715, y = 252)
[79] = (x = 717, y = 254)
[80] = (x = 718, y = 254)
[81] = (x = 719, y = 255)
[82] = (x = 720, y = 255)
[83] = (x = 722, y = 257)
[84] = (x = 723, y = 257)
[85] = (x = 725, y = 259)
[86] = (x = 727, y = 259)
[87] = (x = 728, y = 258)
[88] = (x = 729, y = 258)
[89] = (x = 730, y = 257)
[90] = (x = 731, y = 257)
[91] = (x = 732, y = 256)
[92] = (x = 733, y = 256)
[93] = (x = 735, y = 254)
[94] = (x = 736, y = 254)
[95] = (x = 738, y = 252)
[96] = (x = 739, y = 252)
[97] = (x = 741, y = 250)
[98] = (x = 742, y = 250)
[99] = (x = 744, y = 248)
[100] = (x = 745, y = 248)
[101] = (x = 747, y = 246)
[102] = (x = 748, y = 246)
[103] = (x = 750, y = 244)
[104] = (x = 751, y = 244)
[105] = (x = 754, y = 241)
[106] = (x = 755, y = 241)
[107] = (x = 757, y = 239)
[108] = (x = 758, y = 239)
[109] = (x = 763, y = 234)
[110] = (x = 764, y = 234)
[111] = (x = 769, y = 229)
[112] = (x = 770, y = 229)
[113] = (x = 790, y = 209)
[114] = (x = 790, y = 208)
[115] = (x = 794, y = 204)
[116] = (x = 794, y = 203)
[117] = (x = 795, y = 202)
[118] = (x = 795, y = 201)
[119] = (x = 798, y = 198)
[120] = (x = 798, y = 197)
[121] = (x = 799, y = 196)
[122] = (x = 799, y = 195)
[123] = (x = 801, y = 193)
[124] = (x = 801, y = 192)
[125] = (x = 802, y = 191)
[126] = (x = 802, y = 190)
[127] = (x = 803, y = 189)
[128] = (x = 803, y = 188)
[129] = (x = 804, y = 187)
[130] = (x = 804, y = 185)
[131] = (x = 805, y = 184)
[132] = (x = 805, y = 183)
[133] = (x = 806, y = 182)
[134] = (x = 806, y = 180)
[135] = (x = 807, y = 179)
[136] = (x = 807, y = 176)
[137] = (x = 808, y = 175)
[138] = (x = 808, y = 172)
[139] = (x = 809, y = 171)
[140] = (x = 809, y = 154)
[141] = (x = 808, y = 153)
[142] = (x = 808, y = 150)
[143] = (x = 807, y = 149)
[144] = (x = 807, y = 147)
[145] = (x = 806, y = 146)
[146] = (x = 806, y = 144)
[147] = (x = 805, y = 143)
[148] = (x = 805, y = 142)
[149] = (x = 804, y = 141)
[150] = (x = 804, y = 140)
[151] = (x = 803, y = 139)
[152] = (x = 803, y = 138)
[153] = (x = 802, y = 137)
[154] = (x = 802, y = 136)
[155] = (x = 801, y = 135)
[156] = (x = 801, y = 134)
[157] = (x = 798, y = 131)
[158] = (x = 798, y = 130)
[159] = (x = 789, y = 121)
[160] = (x = 788, y = 121)
[161] = (x = 786, y = 119)
[162] = (x = 785, y = 119)
[163] = (x = 784, y = 118)
[164] = (x = 783, y = 118)
[165] = (x = 782, y = 117)
[166] = (x = 780, y = 117)
[167] = (x = 779, y = 116)
[168] = (x = 778, y = 116)
[169] = (x = 777, y = 115)
[170] = (x = 774, y = 115)
[171] = (x = 773, y = 114)
[172] = (x = 766, y = 114)
[173] = (x = 765, y = 113)
[174] = (x = 759, y = 113)
[175] = (x = 758, y = 114)
[176] = (x = 752, y = 114)
[177] = (x = 751, y = 115)
[178] = (x = 748, y = 115)
[179] = (x = 747, y = 116)
[180] = (x = 745, y = 116)
[181] = (x = 744, y = 117)
[182] = (x = 743, y = 117)
[183] = (x = 742, y = 118)
[184] = (x = 740, y = 118)
[185] = (x = 739, y = 119)
[186] = (x = 738, y = 119)
[187] = (x = 737, y = 120)
[188] = (x = 736, y = 120)
[189] = (x = 734, y = 122)
[190] = (x = 733, y = 122)
[191] = (x = 732, y = 123)
[192] = (x = 731, y = 123)
[193] = (x = 727, y = 127)
[194] = (x = 726, y = 127)
[195] = (x = 722, y = 123)
[196] = (x = 721, y = 123)
[197] = (x = 719, y = 121)
[198] = (x = 718, y = 121)
[199] = (x = 717, y = 120)
[200] = (x = 716, y = 120)
[201] = (x = 715, y = 119)
[202] = (x = 714, y = 119)
[203] = (x = 713, y = 118)
[204] = (x = 712, y = 118)
[205] = (x = 711, y = 117)
[206] = (x = 709, y = 117)
[207] = (x = 708, y = 116)
[208] = (x = 706, y = 116)
[209] = (x = 705, y = 115)
[210] = (x = 702, y = 115)
[211] = (x = 701, y = 114)
[212] = (x = 696, y = 114)
[213] = (x = 695, y = 113)
}
找到之後就可以好好處理它囉~
Comments on: "[OpenCV] 尋找輪廓 (Find Contours)" (8)
有沒有辦法只提取特定輪廓的座標阿?
讚讚
有,須自行定義想取的參數來篩選提取哦~
讚讚
請問我想分析目標輪廓內的顏色的分布,我有辦法找到那些點的位置嗎?
讚讚
有,寫演算法來處理。
讚讚
你真的很利害 我在找什麼資料 都常找到您。 加油
讚Liked by 1 person
謝謝你的讚賞,其實就是感興趣而把複雜的事情簡單化囉o(^▽^)o
讚讚
請問你怎麼印出輪廓座標點 和總點數的
讚讚
很簡單喔~設中斷點來列印出來。😉
讚讚