OpenCV中提供了很多關(guān)于圖像輪廓處理的函數(shù),這里我用FindContours函數(shù)來提取輪廓清酥,并用DrawContours函數(shù)將提取的輪廓畫出來。函數(shù)FindContours的第一個參數(shù)就是我們要進行提取輪廓的目標(biāo)圖像蕴侣,這里要注意,這個圖像必須是一個二值圖臭觉。
代碼:
//find
Mat middle = cvarrToMat(SrcImage);
Mat resultImage;
Mat CannyImg;Canny(DstImg, CannyImg, 50, 200, 3);
findContours(DstImg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);vector>::iterator itc = contours.begin();
while (itc != contours.end())
{
if (itc->size()<500)? ? ? ? ? ? ? ? ? ? ? //刪除連通域面積小于500的輪廓連通域
{
itc = contours.erase(itc);
}
else
{
++itc;
}
}
//draw
Mat result(middle.size(), CV_8U, Scalar(255,255,255));
drawContours(result, contours, -1, Scalar(0,0,0), 2);
效果圖
直線檢測
霍夫變換(Hough Transform)是圖像處理中的一種特征提取技術(shù)昆雀,它通過一種投票算法檢測具有特定形狀的物體。該過程在一個參數(shù)空間中通過計算累計結(jié)果的局部最大值得到一個符合該特定形狀的集合作為霍夫變換結(jié)果蝠筑∧欤霍夫變換于1962年由Paul Hough 首次提出[53],后于1972年由Richard Duda和Peter Hart推廣使用[54]什乙,經(jīng)典霍夫變換用來檢測圖像中的直線挽封,后來霍夫變換擴展到任意形狀物體的識別,多為圓和橢圓.
經(jīng)過幾天的學(xué)習(xí)臣镣,發(fā)現(xiàn)各位大牛的理解方式之前都是有一些區(qū)別的辅愿,但是核心的思想沒有變化,因此記錄一下自己對霍夫變換直線檢測的認(rèn)識忆某。
一点待、原理介紹:
1、對于直角坐標(biāo)系中的任意一點A(x0,y0)弃舒,經(jīng)過點A的直線滿足Y0=k*X0+b.(k是斜率癞埠,b是截距)
2状原、那么在X-Y平面過點A(x0,y0)的直線簇可以用Y0=k*X0+b表示,但對于垂直于X軸的直線斜率是無窮大的則無法表示苗踪。因此將直角坐標(biāo)系轉(zhuǎn)換到極坐標(biāo)系就能解決該特殊情況颠区。
3、在極坐標(biāo)系中表示直線的方程為ρ=xCosθ+ySinθ(ρ為原點到直線的距離),如圖所示:
4通铲、如上圖毕莱,假定在一個8*8的平面像素中有一條直線,并且從左上角(1,8)像素點開始分別計算θ為0°测暗、45°央串、90°、135°碗啄、180°時的ρ质和,圖中可以看出ρ分別為1、(9√2)/2稚字、8饲宿、(7√2)/2、-1胆描,并給這5個值分別記一票瘫想,同理計算像素點(3,6)點θ為0°、45°昌讲、90°国夜、135°、180°時的ρ短绸,再給計算出來的5個ρ值分別記一票车吹,此時就會發(fā)現(xiàn)ρ =(9√2)/2的這個值已經(jīng)記了兩票了,以此類推醋闭,遍歷完整個8*8的像素空間的時候ρ =(9√2)/2就記了5票窄驹, 別的ρ值的票數(shù)均小于5票,所以得到該直線在這個8*8的像素坐標(biāo)中的極坐標(biāo)方程為(9√2)/2=x*Cos45°+y*Sin45°证逻,到此該直線方程就求出來了乐埠。(PS:但實際中θ的取值不會跨度這么大,一般是PI/180)囚企。
代碼
Mat image;
cvtColor(result,image, CV_GRAY2BGR);
Mat I;
cvtColor(image,I, CV_BGR2GRAY);
Mat contours1;
Canny(I, contours1, 125, 350);
threshold(contours1, contours1, 128, 255, THRESH_BINARY);
vector<lines;
// 檢測直線
HoughLinesP(contours1, lines, 1, CV_PI / 180, 145, 300, 2000);
printf("%d\n", lines.size());
drawDetectLines(image,lines, Scalar(0, 255, 0));
namedWindow("result", 2);
imshow("result", image);
sprintf(image_name, "%d HoughLinesP %s", n, ".jpg");//保存的圖片名
imageAddress = path + image_name;
imwrite(imageAddress.c_str(),image);? //保存一幀圖片
效果圖