霍夫變換最大的作用是檢測圖像中的直線。其原理是這樣的:假設圖像中有一條直線,其方程爲y=kx+b。直線上有一個點,其座標爲(x1,y1)。顯然,y1=kx1+b。如果我們把x、y看成是已知的,把k、b看成是未知數,有:b=-x1k+y1。我們發現,(x,y)座標系上的一個點,對應了(k,b)座標系上的一條直線。如果有另外一個點(x2,y2),則其必然對應(k,b)座標系上的另一條直線。顯然,(k,b)座標系上的線都會交於一點,而這個點轉到(x,y)座標系就是我們要求的直線。
原理是這樣,但實際了OpenCV裏面並不是用y=kx+b這樣的直線方程,而是轉到極座標。而且,OpenCV裏的霍夫變換還能檢測圓。
一、霍夫線變換
代碼如下:
Mat src = new Mat(img_line, ImreadModes.Grayscale);
Mat result = new Mat(img_line);
LineSegmentPolar[] lines = Cv2.HoughLines(src, 1, Math.PI / 180, 200);
foreach (LineSegmentPolar line in lines)
{
double a = Math.Cos(line.Theta), b = Math.Sin(line.Theta);
double x0 = a * line.Rho, y0 = b * line.Rho;
double x1 = x0 + 1000 * (-b);
double y1 = y0 + 1000 * a;
double x2 = x0 + 1000 * b;
double y2 = y0 - 1000 * a;
Cv2.Line(result, (int)x1, (int)y1, (int)x2, (int)y2, new Scalar(0, 0, 255));
}
result.SaveImage(img_result);
霍夫線變換隻能找到線的斜率及位置,並不能確定線的端點。
其效果如下圖所示:
二、霍夫概率線變換
此變換可以找出線的端點,代碼如下:
Mat src = new Mat(img_line, ImreadModes.Grayscale);
Mat result = new Mat(img_line);
LineSegmentPoint[] ps = Cv2.HoughLinesP(src, 1, Math.PI / 180, 200);
foreach (LineSegmentPoint p in ps)
{
Cv2.Line(result, p.P1, p.P2, new Scalar(0, 0, 255));
}
result.SaveImage(img_result);
效果如下:
三、霍夫圓變換
代碼如下:
Mat src = new Mat(img_line, ImreadModes.Grayscale);
Mat result = new Mat(img_line);
CircleSegment[] circles = Cv2.HoughCircles(src, HoughMethods.Gradient, 1, 100);
foreach (CircleSegment circle in circles)
{
Cv2.Circle(result, (int)circle.Center.X, (int)circle.Center.Y, (int)circle.Radius, new Scalar(0, 0, 255));
}
result.SaveImage(img_result);
其效果如下: