霍夫變換是圖像處理中檢測直線、圓等幾何形狀的經典算法。OpenCV 提供 `cvHoughLines2` (C 接口) 和 `HoughLines`/`HoughLinesP` (C++ 接口)。本文給出基於 OpenCV 1.x/2.x C 接口的完整示例,包含灰度轉換、Canny 邊緣檢測、概率霍夫變換、結果繪制與顯示。
void CCVMFCView::OnHoughLines() {
IplImage* src = 0;
IplImage* color_dst = 0;
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
int i;
// 1. 獲取工作圖像 workImg (假設為成員變量 IplImage*)
if (workImg->nChannels == 3) {
src = cvCreateImage(cvGetSize(workImg), IPL_DEPTH_8U, 1);
cvCvtColor(workImg, src, CV_BGR2GRAY); // 彩色轉灰度
} else {
src = cvCloneImage(workImg); // 已是灰度
}
// 2. Canny 邊緣檢測
IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
color_dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
cvFlip(src); // 翻轉 (視座標系需要)
cvCanny(src, dst, 50, 120, 3); // 閾值 50/120, aperture 3
cvCvtColor(dst, color_dst, CV_GRAY2BGR); // 灰度轉 BGR 以便畫彩色線
// 3. 概率霍夫變換 (CV_HOUGH_PROBABILISTIC)
// rho=1, theta=PI/180, threshold=20, minLineLength=20, maxLineGap=30
lines = cvHoughLines2(dst, storage, CV_HOUGH_PROBABILISTIC,
1, CV_PI/180, 20, 20, 30);
// 4. 繪制檢測到的線段
for (i = 0; i < lines->total; i++) {
CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i);
// line[0] 起點, line[1] 終點
cvLine(color_dst, line[0], line[1], CV_RGB(255,0,0), 3, CV_AA, 0);
}
// 5. 顯示結果
cvNamedWindow("Hough", 1);
cvShowImage("Hough", color_dst);
cvWaitKey(0);
// 6. 釋放資源
cvReleaseMemStorage(&storage);
cvReleaseImage(&src);
cvReleaseImage(&dst);
cvDestroyWindow("Hough");
}
| 參數 | 含義 | 建議範圍 |
|---|---|---|
rho | 極坐標徑向分辨率(像素) | 1 |
theta | 極坐標角度分辨率(弧度) | CV_PI/180 (1度) |
threshold | 累加器閾值,只有獲得足夠投票的線才被輸出 | 視圖像大小/邊緣密度調整,如 50-200 |
minLineLength | 最小線段長度(像素),短於此被過濾 | 20-100 |
maxLineGap | 同一直線上兩線段最大允許間隙(像素),小於此合併 | 10-50 |
// C++ 接口更簡潔,自動內存管理
#include
using namespace cv;
void HoughLinesDemo(const Mat& src) {
Mat gray, edges, color_dst;
if (src.channels() == 3) cvtColor(src, gray, COLOR_BGR2GRAY);
else gray = src.clone();
Canny(gray, edges, 50, 120, 3);
cvtColor(edges, color_dst, COLOR_GRAY2BGR);
vector lines; // 每行: x1,y1,x2,y2
HoughLinesP(edges, lines, 1, CV_PI/180, 20, 20, 30);
for (auto& l : lines)
line(color_dst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
imshow("Hough Lines", color_dst);
waitKey(0);
}