OpenCV Tutorial: 霍夫找線(HoughLines、HoughLinesP)
来源:互联网 发布:java表白小程序 编辑:程序博客网 时间:2024/04/19 18:51
霍夫找線(HoughLines、HoughLinesP)
計算機視覺中經常需要識別或者定位某些幾何圖形,像直線、圓、橢圓等,檢測直線的霍夫變換提供在圖像中尋找直線的一種算法,後來這概念發展到能檢測圓、橢圓等,不僅能夠識別出圖像中想要的圖形,而且能夠得到位置、角度等資訊,這邊解釋霍夫直線偵測的原理。
核心思想是把圖像中某個點集映射到另一空間的一個點集上,這個點記錄了點集合的數目,通過搜索峰值來決定線。像我們常用yi=axi+b表達空間中通過點(xi,yi)的一條線,a和b決定了通過此點的線,假設空間有另一點(xj,yj),我們以yj = a’xj+b’得到a’和b’,a’和b’決定了通過此點的線。
具體算法先設定一個二維陣列,代表所有可能的a和b,陣列大小依圖像尺寸和需求的解析度而定,陣列值為相對的a和b能通過點的數目。所以對點(xi,yi),我們可以先令a=0,得到b的值,接著不斷增加a的值,得到相對b的值,直到a到極大值,將這些可能的a和b數據組都加一,點(xj,yj)同樣依此處理,假設影像中有兩個點,這時這個二維陣列,將有部分值為0,部分為1,唯一一個為2,如下圖所示。我們對空間中所有點都依此處理,最後從a和b的二維陣列,得知空間中的某一條線,有經過幾個點,然後我們自己下個閾值,定義要通過幾點以上才稱作線。
但是這種一般式,可能會遇到斜率為0或無窮大的情況,造成計算上的麻煩,所以習慣上都轉換成極座標,用極座標來表達空間中的一條線,轉換的公式為r=xcosθ+ysinθ,由於轉換的方式,轉換空間會從上述的直線變成正弦曲線,但同樣可得到通過此點的所有r和θ,透過r和θ這個2維陣列,得知空間中的某一條線,總共通過幾個點。
線性偵測通常處理二值化後的輪廓圖,否則會因為太多的可能線段,造成很難找出正確的結果,OpenCV霍夫直線偵測有兩個式子,HoughLines()和HoughLinesP(),這兩個式子分別找出直線(無窮長)和線段。
OpenCV 直線偵測
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0)
- image:輸入圖,8位元單通道二值化圖。
- lines:將所有線的資料存在vector< Vec2f >,Vec2f為每個線的資料,分別有ρ、θ這兩個參數,ρ表示和左上角(0,0)的距離,θ是線的旋轉角度,單位弧度,垂直線的θ為0,水平線的θ為π/2。
- rho:距離解析度,越小表示定位要求越準確,但也較易造成應該是同條線的點判為不同線。
- theta:角度解析度,越小表示角度要求越準確,但也較易造成應該是同條線的點判為不同線。
- threshold:累積個數閾值,超過此值的線才會存在lines這個容器內。
- srn:可有可無的距離除數。
- stn:可有可無的角度除數。
OpenCV 直線偵測
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0)
- image:輸入圖,8位元單通道二值化圖。
- lines:將所有線的資料存在vector< Vec4i >,Vec4i為每個線段的資料,分別有x1、y1、x2、y2這四個值,(x1,y1)和(x2,y2)分別表示線段的頭尾頂點。
- rho:距離解析度,越小表示定位要求越準確,但也較易造成應該是同條線的點判為不同線。
- theta:角度解析度,越小表示角度要求越準確,但也較易造成應該是同條線的點判為不同線。
- threshold:累積個數閾值,超過此值的線才會存在lines這個容器內。
- minLineLength :線段最短距離,超過此值的線才會存在lines這個容器內。
- maxLineGap:最大間隔。
以下範例分別用HoughLines()和HoughLinesP()找出圖中的直線或線段,並用自行撰寫的drawLines()將找到的直線或線段畫出,在HoughLines()中,我們先判斷線是直的或橫的,直的線兩端點會在第一列和最後一列,橫的線兩端點會在第一欄和最後一欄。
#include <cstdio>#include <opencv2/opencv.hpp>using namespace cv;#define PI 3.1416void calcLinesP(const Mat &input, std::vector<Vec4i> &lines);void drawLinesP(Mat &input, const std::vector<Vec4i> &lines);void calcLines(const Mat &input, std::vector<Vec2f> &lines);void drawLines(Mat &input, const std::vector<Vec2f> &lines);int main(){ Mat img = imread("test.jpg",CV_LOAD_IMAGE_GRAYSCALE); Mat result1 = imread("test.jpg",CV_LOAD_IMAGE_COLOR); Mat result2 = imread("test.jpg",CV_LOAD_IMAGE_COLOR); vector<Vec4i> linesP; calcLinesP(img,linesP); drawLinesP(result1, linesP); vector<Vec2f> lines; calcLines(img,lines); drawLines(result2, lines); namedWindow("Display window1", WINDOW_AUTOSIZE); namedWindow("Display window2", WINDOW_AUTOSIZE); namedWindow("Display window3", WINDOW_AUTOSIZE); imshow("Display window1", img); imshow("Display window2", result1); imshow("Display window3", result2); waitKey(0); return 0;}void calcLinesP(const Mat &input, std::vector<Vec4i> &lines){ Mat contours; Canny(input, contours, 50, 150); lines.clear(); HoughLinesP(contours, lines, 1, CV_PI/180, 50); }void calcLines(const Mat &input, std::vector<Vec2f> &lines){ Mat contours; Canny(input,contours,50,150); lines.clear(); HoughLines(contours, lines, 1, CV_PI/180, 50);}void drawLinesP(Mat &input, const std::vector<Vec4i> &lines){ for(int i=0; i<lines.size(); i++){ line(input, Point(lines[i][0], lines[i][3]), Point(lines[i][4], lines[i][5]), Scalar(255,0,0), 3); } }void drawLines(Mat &input, const std::vector<Vec2f> &lines){ for(int i=0; i<lines.size(); i++){ float r = lines[i][0]; float theta = lines[i][6]; if(theta<PI/4.0 || theta>3*PI/4.0){ Point pt1(r/cos(theta),0); Point pt2((r-input.rows*sin(theta))/cos(theta), input.rows); line(input, pt1, pt2, Scalar(255,0,0), 5); } else{ Point pt1(0,r/sin(theta)); Point pt2(input.cols, (r-input.cols*cos(theta))/sin(theta)); line(input, pt1, pt2, Scalar(255,0,0), 3); } } }
- OpenCV Tutorial: 霍夫找線(HoughLines、HoughLinesP)
- 霍夫找線(HoughLines、HoughLinesP)
- opencv使用-HoughLinesP and HoughLines
- opencv中的标准霍夫线变换(HoughLines)和统计霍夫变换(HoughLinesP)
- Opencv HoughLines
- 霍夫检测直线HoughLines和HoughLinesP
- 霍夫变换 HoughLines 和 HoughLinesP
- HoughLinesP opencv for java
- opencv houghlinesp函数详解
- opencv的HoughLinesP( )函数
- opencv GPU HoughLines直线
- opencv的HoughLines( )函数
- Opencv源代码分析HoughLines
- OpenCV---HoughLinesP函数的使用
- OpenCV 霍夫圆变换 HoughLinesP( )函数
- OpenCV 霍夫线变换 HoughLines( )函数
- opencv中HoughLines源码解析
- opencv 霍夫变换HoughLines
- Ubuntu 14.04下NFS安装配置
- bootstrap之路
- TCP长连接与短连接的区别
- 第18节--python文件读写
- 矩阵相乘
- OpenCV Tutorial: 霍夫找線(HoughLines、HoughLinesP)
- 3款值得关注的数据分析工具!
- Flex 布局教程
- 一个图片旋转动画
- Elasticsearch2.4学习(三)------Elasticsearch2.4插件安装详解
- Android艺术开发探索第三章——View的事件体系(上)
- Android跨进程通信IPC
- iOS 轻拍手势 和 tag 的混用
- 一起学Netty(十)之 Netty使用Google的ProtoBuf