1. 程式人生 > >霍夫線變換,霍夫圓變化

霍夫線變換,霍夫圓變化

向淺墨學習,南航小碩很慚愧。

本系列文章由出品,轉載請註明出處。 

寫作當前博文時配套使用的OpenCV版本:2.4.9

 本篇文章中,我們一起探討了OpenCV中霍夫變換相關的知識點,以及瞭解了OpenCV中實現霍夫線變換的HoughLines、HoughLinesP函式的使用方法,實現霍夫圓變換的HoughCircles函式的使用方法。此博文一共有四個配套的簡短的示例程式,其詳細註釋過的程式碼都在文中貼出,且文章最後提供了綜合示例程式的下載。

先嚐鮮一下其中一個示例程式的執行截圖:


一、引言

在影象處理和計算機視覺領域中,如何從當前的影象中提取所需要的特徵資訊是影象識別的關鍵所在。在許多應用場合中需要快速準確地檢測出直線或者圓。其中一種非常有效的解決問題的方法是霍夫(Hough)變換,其為影象處理中從影象中識別幾何形狀的基本方法之一,應用很廣泛,也有很多改進演算法。最基本的霍夫變換是從黑白影象中檢測直線(線段)。這篇文章就將介紹OpenCV中霍夫變換的使用方法和相關知識。

二、霍夫變換概述

霍夫變換(Hough Transform)是影象處理中的一種特徵提取技術,該過程在一個引數空間中通過計算累計結果的區域性最大值得到一個符合該特定形狀的集合作為霍夫變換結果。

霍夫變換於1962年由PaulHough首次提出,最初的Hough變換是設計用來檢測直線和曲線,起初的方法要求知道物體邊界線的解析方程,但不需要有關區域位置的先驗知識。這種方法的一個突出優點是分割結果的Robustness,即對資料的不完全或噪聲不是非常敏感。然而,要獲得描述邊界的解析表達常常是不可能的。 後於1972年由Richard Duda & Peter Hart推廣使用,經典霍夫變換用來檢測影象中的直線,後來霍夫變換擴充套件到任意形狀物體的識別,多為圓和橢圓。霍夫變換運用兩個座標空間之間的變換將在一個空間中具有相同形狀的曲線或直線對映到另一個座標空間的一個點上形成峰值,從而把檢測任意形狀的問題轉化為統計峰值問題。

霍夫變換在OpenCV中分為霍夫線變換和霍夫圓變換兩種,我們下面將分別進行介紹。

三、霍夫線變換

3.1  OpenCV中的霍夫線變換

我們知道,霍夫線變換是一種用來尋找直線的方法. 在使用霍夫線變換之前, 首先要對影象進行邊緣檢測的處理,也即霍夫線變換的直接輸入只能是邊緣二值影象.

OpenCV支援三種不同的霍夫線變換,它們分別是:標準霍夫變換(Standard Hough Transform,SHT)和多尺度霍夫變換(Multi-Scale Hough Transform,MSHT)累計概率霍夫變換(Progressive Probabilistic Hough Transform ,PPHT)。

其中,多尺度霍夫變換(MSHT)為經典霍夫變換(SHT)在多尺度下的一個變種。累計概率霍夫變換(PPHT)演算法是標準霍夫變換(SHT)演算法的一個改進,它在一定的範圍內進行霍夫變換,計算單獨線段的方向以及範圍,從而減少計算量,縮短計算時間。之所以稱PPHT為“概率”的,是因為並不將累加器平面內的所有可能的點累加,而只是累加其中的一部分,該想法是如果峰值如果足夠高,只用一小部分時間去尋找它就夠了。這樣猜想的話,可以實質性地減少計算時間。

在OpenCV中,我們可以用HoughLines函式來呼叫標準霍夫變換SHT和多尺度霍夫變換MSHT。

而HoughLinesP函式用於呼叫累計概率霍夫變換PPHT。累計概率霍夫變換執行效率很高,所有相比於HoughLines函式,我們更傾向於使用HoughLinesP函式。

總結一下,OpenCV中的霍夫線變換有如下三種:

<1>標準霍夫變換(StandardHough Transform,SHT),由HoughLines函式呼叫。

<2>多尺度霍夫變換(Multi-ScaleHough Transform,MSHT),由HoughLines函式呼叫。

<3>累計概率霍夫變換(ProgressiveProbabilistic Hough Transform,PPHT),由HoughLinesP函式呼叫。

3.2 霍夫線變換的原理

【1】眾所周知, 一條直線在影象二維空間可由兩個變量表示. 如:

<1>在笛卡爾座標系: 可由引數: 斜率和截距(m,b) 表示。

<2>在極座標系: 可由引數: 極徑和極角表示。


對於霍夫變換, 我們將採用第二種方式極座標系來表示直線. 因此, 直線的表示式可為:

化簡便可得到:


【2】一般來說對於點, 我們可以將通過這個點的一族直線統一定義為:

 

這就意味著每一對代表一條通過點的直線。

【3】如果對於一個給定點我們在極座標對極徑極角平面繪出所有通過它的直線, 將得到一條正弦曲線. 例如, 對於給定點X_0= 8 和Y_0= 6 我們可以繪出下圖 (在平面):

 

只繪出滿足下列條件的點  和   .

【4】我們可以對影象中所有的點進行上述操作. 如果兩個不同點進行上述操作後得到的曲線在平面相交, 這就意味著它

們通過同一條直線. 例如,接上面的例子我們繼續對點  和點  繪圖, 得到下圖:

 

這三條曲線在平面相交於點 (0.925, 9.6), 座標表示的是引數對  或者是說點, 點和點組成的平面內的的直線。

【5】以上的說明表明,一般來說, 一條直線能夠通過在平面  尋找交於一點的曲線數量來檢測。而越多曲線交於一點也就意味著這個交點表示的直線由更多的點組成. 一般來說我們可以通過設定直線上點的閾值來定義多少條曲線交於一點我們才認為檢測到了一條直線。

【6】這就是霍夫線變換要做的. 它追蹤影象中每個點對應曲線間的交點. 如果交於一點的曲線的數量超過了閾值, 那麼可以認為這個交點所代表的引數對在原影象中為一條直線。

3.3 HoughLines( )函式詳解

此函式可以找出採用標準霍夫變換的二值影象線條。在OpenCV中,我們可以用其來呼叫標準霍夫變換SHT和多尺度霍夫變換MSHT的OpenCV內建演算法。

[cpp] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. C++: void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )  

  • 第一個引數,InputArray型別的image,輸入影象,即源影象,需為8位的單通道二進位制影象,可以將任意的源圖載入進來後由函式修改成此格式後,再填在這裡。
  • 第二個引數,InputArray型別的lines,經過呼叫HoughLines函式後儲存了霍夫線變換檢測到線條的輸出向量。每一條線由具有兩個元素的向量表示,其中,是離座標原點((0,0)(也就是影象的左上角)的距離。 是弧度線條旋轉角度(0~垂直線,π/2~水平線)。
  • 第三個引數,double型別的rho,以畫素為單位的距離精度。另一種形容方式是直線搜尋時的進步尺寸的單位半徑。PS:Latex中/rho就表示 
  • 第四個引數,double型別的theta,以弧度為單位的角度精度。另一種形容方式是直線搜尋時的進步尺寸的單位角度。
  • 第五個引數,int型別的threshold,累加平面的閾值引數,即識別某部分為圖中的一條直線時它在累加平面中必須達到的值。大於閾值threshold的線段才可以被檢測通過並返回到結果中。
  • 第六個引數,double型別的srn,有預設值0。對於多尺度的霍夫變換,這是第三個引數進步尺寸rho的除數距離。粗略的累加器進步尺寸直接是第三個引數rho,而精確的累加器進步尺寸為rho/srn。
  • 第七個引數,double型別的stn,有預設值0,對於多尺度霍夫變換,srn表示第四個引數進步尺寸的單位角度theta的除數距離。且如果srn和stn同時為0,就表示使用經典的霍夫變換。否則,這兩個引數應該都為正數。

另外,關於霍夫變換的詳細解釋,可以看此英文頁面:

在學完函式解析,看看淺墨為大家準備的以HoughLines為核心的示例程式,就可以全方位瞭解HoughLines函式的使用方法了:

[cpp] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. //-----------------------------------【標頭檔案包含部分】---------------------------------------
  2. //      描述:包含程式所依賴的標頭檔案
  3. //---------------------------------------------------------------------------------------------- 
  4. #include <opencv2/opencv.hpp>
  5. #include <opencv2/imgproc/imgproc.hpp>
  6. //-----------------------------------【名稱空間宣告部分】---------------------------------------
  7. //      描述:包含程式所使用的名稱空間
  8. //----------------------------------------------------------------------------------------------- 
  9. usingnamespace cv;  
  10. //-----------------------------------【main( )函式】--------------------------------------------
  11. //      描述:控制檯應用程式的入口函式,我們的程式從這裡開始
  12. //-----------------------------------------------------------------------------------------------
  13. int main( )  
  14. {  
  15.     //【1】載入原始圖和Mat變數定義   
  16.     Mat srcImage = imread("1.jpg");  //工程目錄下應該有一張名為1.jpg的素材圖
  17.     Mat midImage,dstImage;//臨時變數和目標圖的定義
  18.     //【2】進行邊緣檢測和轉化為灰度圖
  19.     Canny(srcImage, midImage, 50, 200, 3);//進行一此canny邊緣檢測
  20.     cvtColor(midImage,dstImage, CV_GRAY2BGR);//轉化邊緣檢測後的圖為灰度圖
  21.     //【3】進行霍夫線變換
  22.     vector<Vec2f> lines;//定義一個向量結構lines用於存放得到的線段向量集合
  23.     HoughLines(midImage, lines, 1, CV_PI/180, 150, 0, 0 );  
  24.     //【4】依次在圖中繪製出每條線段
  25.     forsize_t i = 0; i < lines.size(); i++ )  
  26.     {  
  27.         float rho = lines[i][0], theta = lines[i][1];  
  28.         Point pt1, pt2;  
  29.         double a = cos(theta), b = sin(theta);  
  30.         double x0 = a*rho, y0 = b*rho;  
  31.         pt1.x = cvRound(x0 + 1000*(-b));  
  32.         pt1.y = cvRound(y0 + 1000*(a));  
  33.         pt2.x = cvRound(x0 - 1000*(-b));  
  34.         pt2.y = cvRound(y0 - 1000*(a));  
  35.         line( dstImage, pt1, pt2, Scalar(55,100,195), 1, CV_AA);  
  36.     }  
  37.     //【5】顯示原始圖  
  38.     imshow("【原始圖】", srcImage);    
  39.     //【6】邊緣檢測後的圖 
  40.     imshow("【邊緣檢測後的圖】", midImage);    
  41.     //【7】顯示效果圖  
  42.     imshow("【效果圖】", dstImage);    
  43.     waitKey(0);    
  44.     return 0;    
  45. }  


執行截圖:

 

來一張大圖:


PS:可以通過調節line(dstImage, pt1, pt2, Scalar(55,100,195), 1, CV_AA);一句Scalar(55,100,195)引數中G、B、R顏色值的數值,得到圖中想要的線條顏色。

3.4 HoughLinesP( )函式詳解

此函式在HoughLines的基礎上末尾加了一個代表Probabilistic(概率)的P,表明它可以採用累計概率霍夫變換(PPHT)來找出二值影象中的直線。

[cpp] view plaincopyprint?在CODE上檢視程式碼片派生到我的程式碼片
  1. C++: void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, 

    相關推薦

    20、【opencv入門】變換變換變換合輯

    接收 最大 sta point hci 都在 imread 創建 滾動 一、引言   在圖像處理和計算機視覺領域中,如何從當前的圖像中提取所需要的特征信息是圖像識別的關鍵所在。在許多應用場合中需要快速準確地檢測出直線或者圓。其中一種非常有效的解決問題的方法是霍夫(Hough

    OpenCV3檢測直線或變換變換合輯

    霍夫變換(Hough Transform)是影象處理中的一種特徵提取技術,該過程在一個引數空間中通過計算累計結果的區域性最大值得到一個符合該特定形狀的集合作為霍夫變換結果。 霍夫變換於1962年由PaulHough首次提出,最初的Hough變換是設計用來檢測直線和曲線,起初的方法要求知道

    變換變化

    向淺墨學習,南航小碩很慚愧。 本系列文章由出品,轉載請註明出處。  寫作當前博文時配套使用的OpenCV版本:2.4.9  本篇文章中,我們一起探討了OpenCV中霍夫變換相關的知識點,以及瞭解

    OpenCV中的變換變換

    word 得到 統計 不同 效率 兩種 做的 ndis pan 一、霍夫線變換 霍夫線變換是OpenCv中一種尋找直線的方法,輸入圖像為邊緣二值圖。 原理: 一條直線在圖像二維空間可由兩個變量表示, 例如: 1、在 笛卡爾坐標系: 可由參數: (m,b) 斜率和截距表示。

    直線變換變換的原理和實現

    一、霍夫直線的原理 (1)本部分大部分學習來自《OpenCV3程式設計入門》,另外有一些自己的理解 如上圖所以,將一條直線由截距是表示為在極座標系下 化簡為 (2)對於一個點(x0,y0)來說,可以通過這個點的一族直線統一定義為 每一對  代表一條通

    變換的原理與實現

    第一個引數,InputArray型別的image,輸入影象,即源影象,需為8位的單通道二進位制影象,可以將任意的源圖載入進來後由函式修改成此格式後,再填在這裡。第二個引數,InputArray型別的lines,經過呼叫HoughLines函式後儲存了霍夫線變換檢測到線條的輸出向量。每一條線由具有兩個元素的向量

    OpenCV變換系列(前篇)-經典變換

    前言:最近新來的的我的大學室友(現在也是我的學弟)在研究霍夫線變換,我之前只是知道這玩意可以拿來做直線檢測,並沒有深入研究,那既然提到了,還是按照我們的老規矩,原理,示例以及OpenCV這一套流程走下來。 菜鳥一枚,好多寫的不好,有點囉嗦,見諒 主要參考部落格:

    python數字影象處理(15):變換

    在圖片處理中,霍夫變換主要是用來檢測圖片中的幾何形狀,包括直線、圓、橢圓等。 在skimage中,霍夫變換是放在tranform模組內,本篇主要講解霍夫線變換。 對於平面中的一條直線,在笛卡爾座標系中,可用y=mx+b來表示,其中m為斜率,b為截距。但是如果直線是一條垂直線,則m為無窮大,所有通常我們

    opencv中的標準變換(HoughLines)和統計變換(HoughLinesP)

    一、下面首先對HoughLines函式進行講解:  void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0,

    LSD直線檢測和變換的學習建議

        最近筆者學習霍夫線變換和LSD直線檢測演算法,有一些學習建議,希望可以給予大家一些幫助。    學習霍夫變換的感想    每個人理解的霍夫變換或許略有差異,但是最主要的是笛卡爾座標系跟極座標系的相互轉換。    霍夫變換分為標準霍夫變換(SHT),多尺度霍夫變換(MS

    opencv-直線變換變換

    計算機視覺 讓我 ali nsf ofo 統一 range 即使 round 轉自:https://blog.csdn.net/poem_qianmo/article/details/26977557 一、引言 在圖像處理和計算機視覺領域中,如何從當前的圖像中提取所

    Opencv2.4學習::變換(1)變換

    霍夫變換 特點: 用於識別幾何形狀 不受旋轉角度影響  線變換基本原理 對於上述不理解的,可以看下面: 對於某直線,可以過原點作其法向量,假設在 ρ為原點到直線距離 和 θ已知的情況下 因此,該直線的   截距=ρ/sin θ   ,     斜率=  -1

    Opencv2.4學習::變換(2)變換

    霍夫圓變換 基本原理  關於基本原理,其思想大概跟霍夫線變換相似,但是有兩種說法。 第一種: 在霍夫線變換中,笛卡爾X-Y直角座標系中的直線,變換到霍夫空間中則為1個點 因此類比可得,笛卡爾X-Y直角座標系中的圓,變換到abr空間中,則為一條曲線,具體如下:

    opencv:tutorial-檢測

    Goal In this tutorial you will learn how to: Use the OpenCV functions cv::HoughLines and cv::HoughLinesP to detect lines in an image. Theory Not

    8.變換:線條——的效果、噪聲對的影響、拓展_5

    目錄 霍夫的效果 噪聲對霍夫的影響 霍夫拓展 本環節結束 霍夫的效果 這裡我將給你們展示一個Hough執行在真實影象上的例子來告訴你們它做得好和做得不好。 這是一張美國足球場的照片: 這是美式足球,你知道,用的球不是圓的。 我們執行一個有味道的邊緣探測器

    完全二叉樹滿二叉樹曼樹

    霍夫曼樹:每個節點要嘛沒有子節點,要麼有兩個子節點 完全二叉樹:滿二叉樹的一部分或者全部。 滿二叉樹:每個父親都有2個葉子。 1 1 / \

    經典線性變換演算法和原始碼

              霍夫變換是一種無需影象內容先驗知識的特徵提取技術,可以廣泛的應用影象中直線、圓、橢圓等形狀的識別。本文主要基於opencv原始碼實現經典的線性霍夫變換。       在直角座標系下,直線被定義為:               y=mx+b    (1)

    OpenCV基於傅立葉變換以及直線檢測的旋轉文字校正

    最近剛好結束了霍夫三部曲以及離散傅立葉變換的總結,剛好了解到它們兩個的結合可以實現一個很有意思的功能 旋轉文字影象的校正,於是參考了幾篇部落格,記錄下來。 主要參考部落格: 標準霍夫直線檢測 以及影象的傅立葉變換 關於傅立葉變換的原理請看我的上一篇部落格,也是為這篇文章

    opencv之變換

    霍夫變換不僅可以找出圖片中的直線,也可以找出圓,橢圓,三角形等等,只要你能定義出直線方程,圓形的方程等等. 不得不說,現在網上的各種部落格質量真的不行,網上一堆文章,亂TM瞎寫,誤人子弟.本身自己就沒有理解的很清楚,又不去讀演算法實現的原始碼,寫的雲山霧罩的,越看越懵逼. 霍夫變換本身的思路是很簡明的.這篇文

    [從今天開始修煉資料結構]樹二叉樹線索二叉樹曼樹

    前面我們已經提到了線性表,棧,佇列等資料結構,他們有一個共同的特性,就是結構中每一個元素都是一對一的,可是在現實中,還有很多一對多的情況需要處理,所以我們需要研究這種一對多的資料結構 —— 樹,並運用它的特性來解決我們在程式設計中遇到的問題。 一、樹的定義   1,樹Tree是n(n >= 0) 個結點