2015年9月26日 星期六

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

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

其實在 OpenCV 2.4 的霍夫直線偵測轉換(Hough Line Transform)是有兩種函數,分別為 HoughLines HoughLinesP 來檢測圖像中的直線,HoughLines 是標準霍夫線變換和 HoughLinesP是統計概率霍夫線變換。函數 HoughLines 只能得到直線的參數 P ,θ 並不知道檢測到的直線的端點,而霍 HoughLinesP 是可以檢測到直線的兩個端點,筆者已經試驗了 HoughLines 來檢測圖像中的直線,接下來便是測試 HoughLinesP 來檢測圖像中的直線了。

OpenCV 2.4 的霍夫直線偵測轉換 – HoughLinesP 函數
兩種霍夫線變換函數: 
1HoughLines 是標準霍夫線變換,原理在上面的部分已經說明了. 它能給我們提供一組參數對 (\theta, r_{\theta}) 的集合來表示檢測到的直線 
2HoughLinesP是統計概率霍夫線變換,這是執行起來效率更高的霍夫線變換. 它輸出檢測到的直線的端點 (x_{0}, y_{0}, x_{1}, y_{1})

霍夫直線偵測轉換(Hough Line Transform) – HoughLinesP 函數:
// HoughLinesP函數

void void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )
image = 輸入圖像(8位單通道或二值化圖像)
lines = 是直線參數輸出,儲存著檢測到的直線的參數對 (x_{start}, y_{start}, x_{end}, y_{end}) 的容器 
rho = 是距離r的精度,即每個圖元對應的距離
theta = 是角度 θ 的解析度,即每個圖元對應的角度,使用 1 ( CV_PI/180)
threshold = 是累計值的閾值,大於這個閾值輸出相應的直線
minLinLength = 能組成一條直線的最少點的數量,點數量不足的直線將被拋棄 
maxLineGap = 能被認為在一條直線上的亮點的最大距離

霍夫 HoughLinesP 函數直線變換方式: 
1先隨機檢測出一部分直線,然後將直線上點的排查掉,再進行其他直線的檢測 
2首先僅統計圖像中非零點的個數,對於已經確認是某條直線上的點就不再變換了 
3對所以有非零點逐個變換到霍夫空間,並累加到霍夫統計表(圖像)中,並統計最大值
4最大值與閾值比較,小於閾值,則繼續下一個點的變換
5若大於閾值,則有一個新的直線段要產生了
6計算直線上線段的端點、長度,如果符合條件,則保存此線段,並 Mark 這個線段上的點不參與其他線段檢測的變換
 
霍夫直線偵測轉換(Hough Line Transform)程式
霍夫直線偵測轉換(Hough Line Transform)程式:
// 霍夫直線偵測轉換(Hough Line Transform)程式
// HoughLinesP函數

                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;

                // 霍夫變換檢測直線
                HoughLinesP(mat_img, lines, 1, CV_PI/180, 80,50,10);

                // 依次在圖中繪製出每條線段
                for (size_t i=0; ilines.size(); i++)    {
                     Vec4i l = lines[i];

line(mat_src, cvPoint(l[0], l[1]), cvPoint(l[2], l[3]), Scalar(255 , 0 , 0),10, CV_AA);
                }

     // 顯示效果圖
     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月 26日 天氣報告
氣溫:28.9@ 20:40
相對濕度:百分之 91%
天氣:微雨

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%
天氣:天色大致良好

2015年9月20日 星期日

OpenCV 2.4 的坎尼圖像邊緣檢測(Canny Edge Detection) – Canny 函數

OpenCV 2.4 的坎尼圖像邊緣檢測(Canny Edge DetectionCanny 函數

筆者將來需要用奧尼(Aoni)百腦通相影 HD720P 高清網絡攝像頭(Webcam)作智能小車或機械人的圖像處理,所以圖像邊緣檢測是必須的,在 OpenCV 內有坎尼邊緣檢測(Canny Edge Detector )函數,坎尼邊緣檢測(Canny Edge Detector )是由 John F. Canny1986年開發的,將來智能小車或機械人行走時便要使用這函數。

OpenCV 2.4 的坎尼圖像邊緣檢測(Canny Edge Detection
坎尼圖像邊緣檢測(Canny Edge Detection)的主要算法(Algorithm):
1Low error rateMeaning a good detection of only existent edges 
2Good localizationThe distance between edge pixels detected and real edge pixels have to be minimized 
3Minimal responseOnly one detector response per edge 

Canny 邊緣檢測演算法可以分為以下 5 個步驟: 
1應用高斯濾波來平滑圖像,目的是去除雜訊。 
2找尋圖像的強度梯度(intensity gradients)。
3應用非最大抑制(non-maximum suppression)技術來消除邊誤檢(本來不是但檢測出來是)。
4應用雙閾值的方法來決定可能的(潛在的)邊界。
5利用滯後技術來跟蹤邊界。
 
操作系統:Windows XP 32-bit 
操作環境:Windows Visual Studio 2010 C++/CLI + OpenCV 2.4.8

坎尼圖像邊緣檢測(Canny Edge Detection)程式:
// 圖像邊緣檢測
// Canny Edge Detection - Canny 函數

int edgeThresh     = 50;
IplImage *pImgGray = cvCreateImage(cvGetSize(pImg),IPL_DEPTH_8U, 1);
IplImage *pImgEdge = cvCreateImage(cvGetSize(pImg),IPL_DEPTH_8U, 1);

cvCvtColor(pImg, pImgGray, CV_BGR2GRAY);
cvCanny(pImgGray, pImgEdge, edgeThresh, edgeThresh*3, 3);
                    
int step       = pImgEdge->widthStep;
uchar* oData   = (uchar*)pImgEdge->imageData;
IplImage* nImg = cvCreateImage(cvSize(pImgEdge->width,pImgEdge->height),IPL_DEPTH_8U,3);

int nStep      = nImg->widthStep;
int nChannels  = nImg->nChannels;
uchar* nData   = (uchar *)nImg->imageData;

     for (int j = 0; jheight; j++){
            for (int i = 0; iwidth; i++){
                 int counter = j*nStep + i*nChannels;
                 nData[counter+ 0] = oData[j*step + i];  // Blue
                 nData[counter+ 1] = oData[j*step + i];  // Green
                 nData[counter+ 2] = oData[j*step + i];  // Red
                 }                  
            }                  

    pictureBox2->Image  = gcnew System::Drawing::Bitmap(frame->width,frame->height,
    frame->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb,
    (System::IntPtr) nImg->imageData);
    pictureBox2->Refresh();
} // End If Canny Edge Detection

OpenCV 中的 Canny 函數:
採用 Canny 演算法做邊緣檢測
void cvCanny( const CvArr* image, CvArr* edges, double threshold1,double threshold2, int aperture_size=3 );
image = 輸入圖像 
edges = 的邊緣圖像
threshold1 = 一個閾值
threshold2 = 第二個閾值
aperture_size = Sobel 運算元內核大小 ( cvSobel)
 函數 cvCanny 採用 CANNY 演算法發現輸入圖像的邊緣而且在輸出圖像中標識這些邊緣。threshold1 threshold2 當中的小閾值用來控制邊緣連接,大的閾值用來控制強邊緣的初始分割。

相關網址:
※ 在 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月 20日 天氣報告
氣溫:28.0@ 20:10
相對濕度:百分之 77%
天氣:大致多雲