2015年9月25日 星期五

OpenCV 2.4 的霍夫直線偵測轉換 – HoughLines 函數

OpenCV 2.4 的霍夫直線偵測轉換 – HoughLines 函數: 

完成了 OpenCV 2.4 的坎尼圖像邊緣檢測(Canny Edge Detection)後,進一步便是找出圖像內的直線,目的是找出道路上的行車線,讓智能小車或機械人可以跟隨行車線向前走。在 OpenCV 2.4 可使用標準霍夫線變換(Hough Line TransformHoughLines 函數來檢測圖像中的直線,霍夫變換是於1962年保羅‧霍夫(Paul Hough)提出 Method and Means for Recognizing Complex Patterns

OpenCV 2.4 的霍夫直線偵測(Hough Line Transform
霍夫直線偵測轉換(Hough Line Transform)– HoughLines 函數:
// HoughLines函數
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )
image = 輸入圖像(8位單通道或二值化圖像)
lines = 是直線參數輸出,儲存偵測結果(r,θ)
rho = 是距離 r 的精度,即每個圖元對應的距離 
theta = 是角度 θ 的解析度,即每個圖元對應的角度,使用1 (CV_PI/180)
threshold = 是累計值的閾值,大於這個閾值輸出相應的直線
srn = 是多尺度霍夫變換中 rho 的分母 
stn = 是多尺度霍夫變換中的 theta 的分母,對於標準霍夫變換,srn stn 都設置為 0 



HoughLines 函數的輸入為一幅包含一組點的二值化圖像,其中一些排列後形成直線,通常這是一幅邊緣圖像,比如來自 Sobel 運算元或 Canny 運算元。HoughLines 函數的輸出是 Vec2f 向量,每個元素都是一對代表檢測到的直線的浮點數 (r,θ)。在設計程式時,先求出圖像中每點的極座標方程,若相交於一點的極座標曲線的個數大於最小投票數,則將該點所對應的 (r,θ) 放入 vector 中,即得到一條直線。在做 Hough 變換之前,一般都要先使用坎尼圖像邊緣檢測(Canny Edge Detection)做邊緣檢測,再對邊緣圖像進行 Hough 變換操作,要注意運算元的數值。 
1Canny 的兩個閾值 
2HoughLines 的閾值參數

霍夫線變換方式: 
1‧將所有非零圖元點逐個變換到霍夫空間,並累加到霍夫表中,統計累加值
2‧找出累加值中大於閾值並且為鄰域內的最大值的點,存入緩存中
3‧排序通過霍夫變換檢測到的直線段4‧將排序好的直線段從小到大存入輸出緩存

霍夫直線偵測轉換(Hough Line Transform)程式:
// 霍夫直線偵測轉換(Hough Line Transform)程式
// HoughLines 函數

Mat mat_img;
IplImage* img_hough;

// 載入原圖和Mat變數定義
Mat mat_src = imread(fileName, CV_LOAD_IMAGE_COLOR);
img_hough = &IplImage(mat_src);

// 轉化為灰度圖
cvtColor(mat_src, mat_img, CV_BGR2GRAY);

// GaussianBlur 消除雜訊
GaussianBlur(mat_img, mat_img, cv::Size (5, 5), 1.5, 1.5); // GaussianBlur OK

// Canny 對圖像進行邊緣檢測
Canny(mat_img, mat_img, 100, 200,3);

// 存儲直線參數對的容器   
std::vector lines;

// 霍夫變換檢測直線
HoughLines(mat_img, lines, 1, CV_PI/180, 170); // mat_imgFormat8bppIndexed

std::vector::iterator i= lines.begin();
// 依次在圖中繪製出每條線段
    for (; i!=lines.end(); ++i)    {
             float rho = (*i)[0];
             float theta = (*i)[1];

             cv::Point pt1,pt2;
             double a=cos(theta);
             double b=sin(theta);
             double x0= rho*a;
             double y0= rho*b;
             pt1.x = cvRound(x0+1000*(-b));
             pt1.y = cvRound(y0+1000*a);
             pt2.x = cvRound(x0-1000*(-b));
             pt2.y = cvRound(y0-1000*a);
             cvLine(img_hough, pt1, pt2, CV_RGB(255 , 0 , 0 ), 10 , CV_AA , 0);
    }
     // 顯示效果圖
     pictureBox2->Image  = gcnew       System::Drawing::Bitmap(img_hough->width,img_hough->height,     img_hough->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb,
     (System::IntPtr) img_hough->imageData);
     pictureBox2->Refresh();

操作系統:Windows XP 32-bit 
操作環境:Windows Visual Studio 2010 C++/CLI + OpenCV 2.4.8

相關網址:
※ 在 Windows XP Visual Studio 2010 安裝 OpenCV 2.4
※ 在 Windows XP Visual Studio 2010 使用 OpenCV 2.4 第一個程式
※ 在 Windows XP Visual Studio 2010 使用 OpenCV 2.4 使用 WebCam
※ 在 Windows XP Visual Studio 2010 安裝使用 FFmpeg 函數庫
※ 在 Windows XP Visual Studio 2010 使用 OpenCV 2.4 使用 WebCam
※ 在 Windows XP Visual Studio 2010 使用 OpenCV 2.4 顯示 IPCam 串流視頻
※ 在 Windows XP Visual Studio 2010 使用 OpenCV 2.4 導入屬性工作表文件檔
※ 在 Windows XP Visual Studio 2010 使用 Windows From OpenCV 2.4 配置
※ 在 OpenCV 2.4 的 IplImage 資料結構
※ OpenCV 2.4 的坎尼圖像邊緣檢測(Canny Edge Detection) – Canny 函數
※ OpenCV 2.4 的霍夫直線偵測轉換 – HoughLines 函數
※ OpenCV 2.4 的霍夫直線偵測轉換 – HoughLinesP 函數
※ OpenCV 2.4 的人臉偵測(Face Detection)– cvHaarDetectObjects 函數
※ OpenCV 2.4 的物件偵測(Object Detection)– cvHoughCircles 函數
※ OpenCV 2.4 的物件追蹤(Object Tracking)– cvMoments 函數

2015 年 9月 25日 天氣報告
氣溫:28.4@ 23:00
相對濕度:百分之 77%
天氣:天色大致良好

沒有留言:

張貼留言