原理先留着,日後補上。
針對線檢測,一般使用累計概率霍夫變換:HoughLineP()函數 檢測速度更快。
CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double minLineLength = 0, double maxLineGap = 0 );
輸入圖像必須是八位單通道二進制圖像!
第二個參數:輸出的lines,存儲了檢測到的線條的矢量,每條線具有4個元素的矢量(x_1,x_2,y_1,y_2)
真實存儲時 [0] [1]表示第一個點 [2][3]表示第二個點
第三個參數:以像素爲單位的距離精度,生成極座標的時候的像素掃描步長
第四個參數:以弧度爲單位的角度精度,生成極座標的時候的角度步長 ,一般取值 CV_PI/180
第五個參數:即識別某部分爲圖中的一條直線時它在累加平面中必須達到的值,只有獲得足夠交點的極座標點才被看作是直線,
大於閾值threshold的線段纔可以被檢測並返回到結果中
第六個參數: 最小直線長度,默認值0 ,比這個長度短的直線就不能被顯現出來
第七個參數:允許將同一行點與點之間連接起來的最大的距離
Img1 = imread("demo.jpg");
if (!Img1.data)
{
cout << "未找到圖片" << endl;
return -1;
}
Canny(Img1, GrayImg, 100, 200); //輸出即爲邊緣二值化圖像
cvtColor(GrayImg, Img1, COLOR_GRAY2BGR);
imshow("Input Img", GrayImg); //邊緣二值化圖像
vector<Vec4f> lines;//定義一個矢量結構lines用來存放得到的線段矢量集合
HoughLinesP(GrayImg, lines, 1, CV_PI / 180, 100, 20, 10);
for (size_t i = 0;i < lines.size();i++)
{
Vec4i l = lines[i];
line(Img1, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 1, LINE_AA);
//不能在GrayImg中畫線 因爲GrayImg爲單通道八位圖像,不能顯示彩色,
//前面的GRAY2BGR是爲了能在IMG1中用別的顏色顯示出檢測的線
}
imshow("Output Img", Img1);
霍夫圓變換 HoughCircle()函數
與線變換相比, 圓變換最大的優勢就是不需要原圖是二值的, HoughLinesP需要原圖爲二值圖像;
CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
輸入圖像爲 八位單通道灰度圖像即可
輸出 circles 爲存儲了檢測到的圓的矢量, 每個矢量包含了三個元素的浮點矢量(x,y,radius)
第三個參數爲使用的檢測方法,目前只有一種辦法可以使用 即霍夫梯度法 HOUGH_GRADIENT
第四個參數dp 通常設置1 使得檢測圓心的累加器圖像與源圖像分辨率相同。
設置爲2的話,累加器只有源圖像一般大小的高度和寬度
第五個參數 minDist 圓心之間的最小距離,這個參數如果太小,多個相鄰的圓可能就被檢測成同一個圓
設置太大,某些圓就不能被檢測出來
第六個參數 有默認值100,他表示傳遞給canny邊緣檢測算子的高閾值,而低閾值爲高閾值的一半
第七個參數 有默認值爲100, 他表示在檢測圓心階段的累加器的閾值。
它越小,則可以檢測更多不存在的圓;越大的話,能通過檢測的圓就更加接近完美的圓形
最後倆參數 一個表示圓半徑的最小值,一個表示圓半徑的最大值,可以直接使用默認,也可以自己規定來輔助檢測圓。
cvtColor(Img1,GrayImg,COLOR_BGR2GRAY);
medianBlur(GrayImg, GrayImg, 3);
//因爲霍夫圓檢測對噪聲比較敏感,首先要對圖像做中值濾波
//GaussianBlur(GrayImg, GrayImg, Size(7, 7), 1.5, 1.5);
//此濾波方式爲釋義中推薦 7*7 sigma1.5 1.5
vector<Vec3f> circle1;
HoughCircles(GrayImg, circle1, HOUGH_GRADIENT, 1, 50, 100, 50, 0, 0);
cvtColor(GrayImg, GrayImg, COLOR_GRAY2BGR);
for (size_t i = 0; i < circle1.size(); i++)
{
Vec3f c=circle1[i];
Point center = Point((int)c[0], (int)c[1]);
circle(GrayImg, center, (int)c[2], Scalar(255, 0, 90), 2, LINE_AA);
//畫出圓
circle(GrayImg, center, 2, Scalar(255, 90, 90), 2, LINE_AA);
//畫出圓心
}
imshow("Output Img", GrayImg);