1. 程式人生 > >OpenCV-Python教程(9)(10)(11): 使用霍夫變換檢測直線 直方圖均衡化 輪廓檢測

OpenCV-Python教程(9)(10)(11): 使用霍夫變換檢測直線 直方圖均衡化 輪廓檢測

OpenCV-Python教程(9、使用霍夫變換檢測直線)

相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++呼叫相應OpenCV函式的不同之處。這篇文章介紹在Python中使用OpenCV的霍夫變換檢測直線。

提示:

  • 轉載請詳細註明原作者及出處,謝謝!
  • 本文介紹在OpenCV-Python中使用霍夫變換檢測直線的方法。
  • 本文不介詳細的理論知識,讀者可從其他資料中獲取相應的背景知識。筆者推薦清華大學出版社的《影象處理與計算機視覺演算法及應用(第2版) 》。

霍夫變換

Hough變換是經典的檢測直線的演算法。其最初用來檢測影象中的直線,同時也可以將其擴充套件,以用來檢測影象中簡單的結構。

OpenCV提供了兩種用於直線檢測的Hough變換形式。其中基本的版本是cv2.HoughLines。其輸入一幅含有點集的二值圖(由非0畫素表示),其中一些點互相聯絡組成直線。通常這是通過如Canny運算元獲得的一幅邊緣影象。cv2.HoughLines函式輸出的是[float, float]形式的ndarray,其中每個值表示檢測到的線(ρ , θ)中浮點點值的引數。下面的例子首先使用Canny運算元獲得影象邊緣,然後使用Hough變換檢測直線。其中HoughLines函式的引數3和4對應直線搜尋的步長。在本例中,函式將通過步長為1的半徑和步長為π/180的角來搜尋所有可能的直線。最後一個引數是經過某一點曲線的數量的閾值,超過這個閾值,就表示這個交點所代表的引數對(rho, theta)在原影象中為一條直線。具體理論可參考

這篇文章

  1. #coding=utf-8
  2. import cv2  
  3. import numpy as np    
  4. img = cv2.imread("/home/sunny/workspace/images/road.jpg"0)  
  5. img = cv2.GaussianBlur(img,(3,3),0)  
  6. edges = cv2.Canny(img, 50150, apertureSize = 3)  
  7. lines = cv2.HoughLines(edges,1,np.pi/180,118#這裡對最後一個引數使用了經驗型的值
  8. result = img.copy()  
  9. for line in lines[0]:  
  10.     rho = line[0#第一個元素是距離rho
  11.     theta= line[1#第二個元素是角度theta
  12.     print rho  
  13.     print theta  
  14.     if  (theta < (np.pi/4. )) or (theta > (3.*np.pi/4.0)): #垂直直線
  15.                 #該直線與第一行的交點
  16.         pt1 = (int(rho/np.cos(theta)),0)  
  17.         #該直線與最後一行的焦點
  18.         pt2 = (int((rho-result.shape[0]*np.sin(theta))/np.cos(theta)),result.shape[0])  
  19.         #繪製一條白線
  20.         cv2.line( result, pt1, pt2, (255))  
  21.     else#水平直線
  22.         # 該直線與第一列的交點
  23.         pt1 = (0,int(rho/np.sin(theta)))  
  24.         #該直線與最後一列的交點
  25.         pt2 = (result.shape[1], int((rho-result.shape[1]*np.cos(theta))/np.sin(theta)))  
  26.         #繪製一條直線
  27.         cv2.line(result, pt1, pt2, (255), 1)  
  28. cv2.imshow('Canny', edges )  
  29. cv2.imshow('Result', result)  
  30. cv2.waitKey(0)  
  31. cv2.destroyAllWindows()  

結果如下:


注意:

在C++中,HoughLines函式得到的結果是一個向量lines,其中的元素是由兩個元素組成的子向量(rho, theta),所以lines的訪問方式類似二維陣列。因此,可以以類似:

  1. std::vector<cv::Vec2f>::const_iterator it= lines.begin();  
  2. float rho= (*it)[0];  
  3. float theta= (*it)[1];  

這樣的方式訪問rho和theta。

而在Python中,返回的是一個三維的np.ndarray!。可通過檢驗HoughLines返回的lines的ndim屬性得到。如:

  1. lines = cv2.HoughLines(edges,1,np.pi/180,118)  
  2. print lines.ndim  
  3. #將得到3
至於為什麼是三維的,這和NumPy中ndarray的屬性有關(關於NumPy的相關內容,請移步至NumPy簡明教程),如果將HoughLines檢測到的的結果輸出,就一目瞭然了:
  1. #上面例子中檢測到的lines的資料
  2. 3#lines.ndim屬性
  3. (152#lines.shape屬性
  4. #lines[0]
  5. [[  4.20000000e+012.14675498e+00]  
  6.  [  4.50000000e+012.14675498e+00]  
  7.  [  3.50000000e+012.16420817e+00]  
  8.  [  1.49000000e+021.60570288e+00]  
  9.  [  2.24000000e+021.74532920e-01]]  
  10. ===============  
  11. #lines本身
  12. [[[  4.20000000e+012.14675498e+00]  
  13.   [  4.50000000e+012.14675498e+00]  
  14.   [  3.50000000e+012.16420817e+00]  
  15.   [  1.49000000e+021.60570288e+00]  
  16.   [  2.24000000e+021.74532920e-01]]]  

概率霍夫變換

觀察前面的例子得到的結果圖片,其中Hough變換看起來就像在影象中查詢對齊的邊界畫素點集合。但這樣會在一些情況下導致虛假檢測,如畫素偶然對齊或多條直線穿過同樣的對齊畫素造成的多重檢測。

要避免這樣的問題,並檢測影象中分段的直線(而不是貫穿整個影象的直線),就誕生了Hough變化的改進版,即概率Hough變換(Probabilistic Hough)。在OpenCV中用函式cv::HoughLinesP 實現。如下:

  1. #coding=utf-8
  2. import cv2  
  3. import numpy as np    
  4. img = cv2.imread("/home/sunny/workspace/images/road.jpg")  
  5. img = cv2.GaussianBlur(img,(3,3),0)  
  6. edges = cv2.Canny(img, 50150, apertureSize = 3)  
  7. lines = cv2.HoughLines(edges,1,np.pi/180,118)  
  8. result = img.copy()  
  9. #經驗引數
  10. minLineLength = 200
  11. maxLineGap = 15
  12. lines = cv2.HoughLinesP(edges,1,np.pi/180,80,minLineLength,maxLineGap)  
  13. for x1,y1,x2,y2 in lines[0]:  
  14.     cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)  
  15. cv2.imshow('Result', img)  
  16. cv2.waitKey(0)  
  17. cv2.destroyAllWindows()  
結果如下:

未完待續。。。

參考資料:

1、《Opencv2 Computer Vision Application Programming Cookbook》

2、《OpenCV References Manule》


OpenCV-Python教程(10、直方圖均衡化)

相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++呼叫相應OpenCV函式的不同之處。這篇文章介紹在Python中使用OpenCV和NumPy對直方圖進行均衡化處理。

提示:

本文內容:

  • 使用查詢表拉伸直方圖
  • 使用OpenCV和NumPy的函式以不同的方式進行直方圖均衡化

在某些情況下,一副影象中大部分畫素的強度都集中在某一區域,而質量較高的影象中,畫素的強度應該均衡的分佈。為此,可將表示畫素強度的直方圖進行拉伸,將其平坦化。如下:


圖來自維基百科

實驗資料

本節的實驗資料來自維基百科,原圖如下:

其直方圖為:


使用查詢表來拉伸直方圖

在影象處理中,直方圖均衡化一般用來均衡影象的強度,或增加影象的對比度。在介紹使用直方圖均衡化來拉伸影象的直方圖之前,先介紹使用查詢表的方法。

觀察上圖中原始影象的直方圖,很容易發現大部分強度值範圍都沒有用到。因此先檢測影象非0的最低(imin)強度值和最高(imax)強度值。將最低值imin設為0,最高值imax設為255。中間的按255.0*(i-imin)/(imax-imin)+0.5)的形式設定。

相關推薦

OpenCV-Python教程91011 使用變換檢測直線 直方圖均衡化 輪廓檢測

OpenCV-Python教程(9、使用霍夫變換檢測直線) 相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++呼叫相應OpenCV函式的不同之處。這篇文章介紹在Python中使用OpenCV的霍夫變換檢

Opencv2.4學習變換1變換

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

Opencv2.4學習變換2變換

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

利用變換直線檢測的原理及OpenCV程式碼實現

說白了,以直線檢測為例,霍夫變換實際上就是把使每個畫素座標點經過變換都變成都直線特質有貢獻的統一度量(這種度量以我目前的理解與笛卡爾(極坐系)並無區別,即極半徑和極角),並對轉換後的度量進行累計(可以理解為投票),當一個波峰出現時候,說明有直線存在。如果要了解更詳細的,大

OpenCV-Python教程11輪廓檢測

相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++呼叫相應OpenCV函式的不同之處。這篇文章介紹在Python中使用OpenCV檢測並繪製輪廓。 提示: 轉載請詳細註明原作者及出處,謝謝!本文介紹在OpenCV

OpenCV Python教程345 直方圖的計算與顯示 形態學處理 初級濾波內

OpenCV Python教程(3、直方圖的計算與顯示) 本篇文章介紹如何用OpenCV Python來計算直方圖,並簡略介紹用NumPy和Matplotlib計算和繪製直方圖 直方圖的背景知識、用途什麼的就直接略過去了。這裡直接介紹方法。 計算並顯

OpenCV-Python教程7、Laplacian運算元

本篇文章介紹如何用OpenCV-Python來使用Laplacian運算元。 提示: 轉載請詳細註明原作者及出處,謝謝!本文介紹使用在OpenCV-Python中使用Laplacian函式本文不介詳細的理論知識,讀者可從其他資料中獲取相應的背景知識。筆者推薦清華大學出版社的

OpenCV Python教程1、影象的載入、顯示和儲存

轉載請詳細註明原作者及出處,謝謝! 本文是OpenCV  2 Computer Vision Application Programming Cookbook讀書筆記的第一篇。在筆記中將以Python語言改寫每章的程式碼。 PythonOpenCV的配置這裡就不介紹了。 注

基於輪廓提取影象文字2---OpenCV-Python教程11輪廓檢測

https://blog.csdn.net/sunny2038/article/details/12889059相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++呼叫相應OpenCV函式的不同之處。這篇文章介紹在Py

python入門習題——9,迴文數簡單

判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。 示例 1: 輸入: 121 輸出: true 示例 2: 輸入: -121 輸出: false 解釋: 從左向右讀, 為 -121 。 從右向左讀, 為 121- 。因此它不是一個迴文

Opencv Python版學習筆記 字元識別-分類器SVM,KNearest,RTrees,Boost,MLP

Opencv提供了幾種分類器,例程裡通過字元識別來進行說明的 1、支援向量機(SVM):給定訓練樣本,支援向量機建立一個超平面作為決策平面,使得正例和反例之間的隔離邊緣被最大化。 函式原型:訓練原型 cv2.SVM.train(trainData, responses[, varIdx[,

python+OpenCV影象處理變換簡單圖形檢測

霍夫變換 霍夫變換(Hough Transform)是影象處理中從影象中識別幾何形狀的基本方法之一,應用很廣泛,也有很多改進演算法。主要用來從影象中分離出具有某種相同特徵的幾何形狀(如:直線、圓等)。最基本的霍夫變換是從黑白影象中檢測直線。 霍夫變換是經典的檢測直線的演算

OpenCV入門教程之十】 形態學影象處理膨脹與腐蝕

本系列文章由@淺墨_毛星雲 出品,轉載請註明出處。 寫作當前博文時配套使用的OpenCV版本: 2.4.8本篇文章中,我們一起探究了影象處理中,最基本的形態學運算——膨脹與腐蝕。淺墨在文章開頭友情提醒,用人物照片做腐蝕和膨脹的素材圖片得到的效果會比較驚悚,毀三觀的,不建議嘗試

opencv 簡單的實現變換改進版

//霍夫變換 輸入單通道二值影象 檢測直線數量 void HoughLines(Mat &img,int n) { int i,j; //行列 int row = img.rows; int col = img.cols; //極徑最大值為 對角線+寬 int max_r

OpenCV(C++) 基礎-- 邊緣檢測變換

1. 邊緣檢測 Sobel():靈活調整水平或者垂直邊緣檢測,基於高斯平滑和微分求導 void Sobel(src, dst, depth, dx, dy, ksize=3); // depth: 對應影象型別 // dx, dy: x,y方向的差分階數,控制在x,y軸上

變換鐳射線中心提取基於opencv

平臺: VS2017 C++ OPENCV3庫 效果: 原圖 結果: 原圖: 結果: 步驟: 1.圖片預處理,引數可以自己調整 //邊緣檢測 Canny(srcImage, dstImage, 210, 250, 3); //灰度化 cvtCo

pandas21 讀csv檔案read_csv9.浮點轉換和NA值詳細 tcy

浮點轉換和NA值 2018/12/26 目錄: 第1部分:csv文字檔案讀寫 pandas 讀csv檔案read_csv(1.文字讀寫概要)https://mp.csdn.net/postedit/85289371 pandas 讀csv檔案read_csv(2.read

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

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

OpenCV系列後篇-統計概率變換HoughLinesP

 之前我也忽視了這個統計概率霍夫變換-作為霍夫系列的完結篇,今天終於算是結束了。 原理+Samples+原始碼分析 其實網上關於統計概率霍夫變換的介紹真的不多,大多數就是介紹一下引數,弄個例程式跑一下就行了。 主要參考部落格: 1.原理分析: 標準霍夫變換本質上是

【學習opencv】實現變換1檢測直線

目前想對於霍夫圓檢測進行修改,想法是若能在固定圓心的橫座標的情景下去搜索圓,若要實現就需要對霍夫檢測有一定的深入瞭解。 霍夫變換原理 霍夫變換原理實則就是引數空間的轉變。 極座標轉換 首先因為直角座標系中垂直於x軸的直線不存在,即轉換用極座標表示