最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

OpenCV霍夫變換(Hough Transform)直線檢測詳解

 更新時(shí)間:2018年12月26日 09:45:50   作者:Joy_Shen  
這篇文章主要為大家詳細(xì)介紹了OpenCV霍夫變換直線檢測的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

霍夫變換(Hough Transform)的主要思想:

一條直線在平面直角坐標(biāo)系(x-y)中可以用y=ax+b式表示,對于直線上一個(gè)確定的點(diǎn)(x0,y0),總符合y0-ax0=b,而它可以表示為參數(shù)平面坐標(biāo)系(a-b)中的一條直線。因此,圖像中的一個(gè)點(diǎn)對應(yīng)參數(shù)平面的一條直線,同樣,圖像中的一條直線對應(yīng)參數(shù)平面上的一個(gè)點(diǎn)。

基本Hough變換檢測直線:

由于同一條直線上的不同點(diǎn)在參數(shù)平面中是會(huì)經(jīng)過同一個(gè)點(diǎn)的多條線。對圖像的所有點(diǎn)作霍夫變換,檢測直線就意味著找到對應(yīng)參數(shù)平面中的直線相交最多的點(diǎn)。對這些交點(diǎn)做票數(shù)累計(jì),然后取出票數(shù)大于最小投票數(shù)的點(diǎn),即為原坐標(biāo)系里檢測出的直線。

一般,直線的參數(shù)方程為 ρ=xcosθ+ysinθ

OpenCV中的基本霍夫變換直線檢測函數(shù) cv::HoughLines:

函數(shù)輸入為一幅二值圖像(有很多待檢測點(diǎn)),其中一些點(diǎn)排列后形成直線,通常這是一幅邊緣圖像,比如來自Sobel算子或Canny算子。函數(shù)的輸出是cv::Vec2f的向量,每個(gè)元素都是一對代表檢測到的直線的浮點(diǎn)數(shù)(ρ, θ)。函數(shù)的作法是先求出原圖像中每點(diǎn)的極坐標(biāo)方程,若相交于一點(diǎn)的極坐標(biāo)曲線的個(gè)數(shù)大于最小投票數(shù),則將該點(diǎn)(ρ, θ)(參數(shù)坐標(biāo)系點(diǎn))放入輸出向量。

#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
 
#define PI 3.1415926
 
class LineFinder{
private:
 std::vector<cv::Vec2f> lines;
 double deltaRho; // 參數(shù)坐標(biāo)系的步長(theta表示與直線垂直的角度)
 double deltaTheta;
 int minVote;  // 判斷是直線的最小投票數(shù) 
public:
 LineFinder() {
 deltaRho = 1;
 deltaTheta = PI / 180;
 minVote = 80;
 }
 void setAccResolution(double dRho, double dTheta) {
 deltaRho = dRho;
 deltaTheta = dTheta;
 }
 void setMinVote(int minv) {
 minVote = minv;
 }
 // Hough變換檢測直線;rho=1,theta=PI/180參數(shù)坐標(biāo)系里的步長,threshold=最小投票數(shù)
 void findLines(cv::Mat& binary){
 lines.clear();
 cv::HoughLines(binary, lines, deltaRho, deltaTheta, minVote);
 }
 
 void drawDetectedLines(cv::Mat& result){
 std::vector<cv::Vec2f>::const_iterator it = lines.begin();
 while (it != lines.end())
 {
 // 以下兩個(gè)參數(shù)用來檢測直線屬于垂直線還是水平線
 float rho = (*it)[0];
 float theta = (*it)[1];
 if (theta < PI / 4. || theta > 3.*PI / 4.)
 { // 若檢測為垂直線,直線交于圖片的上下兩邊,先找交點(diǎn)
 cv::Point pt1(rho / cos(theta), 0);
 cv::Point pt2((rho - result.rows*sin(theta)) / cos(theta), result.rows);
 cv::line(result, pt1, pt2, cv::Scalar(255), 1); //
 }
 else // 若檢測為水平線,直線交于圖片的左右兩邊,先找交點(diǎn)
 {
 cv::Point pt1(0, rho / sin(theta));
 cv::Point pt2(result.cols, (rho - result.cols*cos(theta)) / sin(theta));
 cv::line(result, pt1, pt2, cv::Scalar(255), 1);
 }
 ++it;
 }
 }
};
 
int main(int argc, char *argv[])
{
 cv::Mat image = cv::imread("D:/VS_exercise/images/road1.jpg");
 cv::Mat imageGray;
 cv::Mat contours;
 cv::cvtColor(image, imageGray, cv::COLOR_RGB2GRAY);
 cv::Canny(imageGray, contours, 190, 300);
 // 在原圖的拷貝上畫直線
 cv::Mat result(contours.rows, contours.cols, CV_8U, cv::Scalar(255));
 image.copyTo(result);
 // Hough變換檢測
 LineFinder finder;
 finder.setMinVote(130);
 finder.findLines(contours);
 finder.drawDetectedLines(result);
 
 // 顯示
 cv::namedWindow("Detected Lines with Hough");
 cv::imshow("Detected Lines with Hough", result);
 cv::waitKey(0);
 return 0;
}

概率Hough變換檢測線段:

霍夫變換檢測直線的目的,是找到二值圖像中經(jīng)過足夠多數(shù)量點(diǎn)的所有直線,當(dāng)同一直線穿過許多點(diǎn),便意味著這條線的存在足夠明顯。

概率霍夫變換在原算法的基礎(chǔ)上增加了一些改動(dòng),主要是:

1. 不再系統(tǒng)地逐行掃描圖像,而是隨機(jī)挑選(輪廓圖像的)前景點(diǎn),一旦累加器中的某一項(xiàng)交點(diǎn)的票數(shù)達(dá)到給定的最小值,就搜索輪廓圖像在對應(yīng)直線上的前景點(diǎn),連成線段(要小于maxLineGap),然后記錄線段參數(shù)(起終點(diǎn)),最后刪除所有經(jīng)過的點(diǎn)(即使它們并未投過票)。

2. 概率霍夫變換定義了兩個(gè)額外的參數(shù):一個(gè)是可以接受的最小線段長度(minLineLength),另一個(gè)是允許組成連續(xù)線段的最大像素間隔(maxLineGap),雖然額外步驟增加了算法的復(fù)雜度,但由于參與投票的點(diǎn)數(shù)有所減少,因此得到了一些補(bǔ)償。

openCV中的概率霍夫變換直線檢測函數(shù) cv::HoughLinesP:

函數(shù)的輸出是cv::Vec4i組成的向量,每個(gè)元素是檢測到的線段的兩個(gè)坐標(biāo)點(diǎn)(pt1x, pt1y, pt2x, pt2y)。

#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
 
#define PI 3.1415926 
 
class LineFinder{
private:
 std::vector<cv::Vec4i> lines;
 double deltaRho; // 步長(theta表示與直線垂直的角度)
 double deltaTheta;
 int minVote;  // 判斷是直線的最小投票數(shù) 
 double minLength; // 判斷是直線的最小線段長度 
 double maxGap; // 允許組成連續(xù)線段的最大像素間隔
public:
 LineFinder() {
 deltaRho = 1;
 deltaTheta = PI / 180;
 minVote = 10;
 minLength = 0.0;
 maxGap = 0.0;
 }
 void setAccResolution(double dRho, double dTheta) {
 deltaRho = dRho;
 deltaTheta = dTheta;
 }
 void setMinVote(int minv) {
 minVote = minv;
 }
 void setLineLengthAndGap(double length, double gap) {
 minLength = length;
 maxGap = gap;
 }
 
 // Hough變換檢測線段
 void findLines(cv::Mat& binary) {
 lines.clear();
 cv::HoughLinesP(binary, lines, deltaRho, deltaTheta, minVote, minLength, maxGap);
 }
 
 void drawDetectedLines(cv::Mat &image, cv::Scalar color = cv::Scalar(255)) {
 std::vector<cv::Vec4i>::const_iterator it2 = lines.begin();
 while (it2 != lines.end()) {
 cv::Point pt1((*it2)[0], (*it2)[1]);
 cv::Point pt2((*it2)[2], (*it2)[3]);
 cv::line(image, pt1, pt2, color, 1.5); //畫線段
 ++it2;
 }
 }
};
 
int main(int argc, char *argv[])
{
 cv::Mat image = cv::imread("D:/VS_exercise/images/road1.jpg");
 cv::Mat imageGray;
 cv::Mat contours;
 cv::cvtColor(image, imageGray, cv::COLOR_RGB2GRAY);
 // 邊緣檢測
 cv::Canny(imageGray, contours, 190, 300);
 // Hough變換檢測
 LineFinder finder;
 finder.setMinVote(80);
 finder.setLineLengthAndGap(100, 10); //概率Hough變換增加的兩個(gè)參數(shù)
 finder.findLines(contours);
 finder.drawDetectedLines(image);
 
 // 顯示
 cv::imshow("Detected Lines with Hough", image);
 cv::waitKey(0);
 return 0;
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解C語言未初始化的局部變量是多少

    詳解C語言未初始化的局部變量是多少

    這篇文章主要給大家介紹了關(guān)于C語言未初始化的局部變量是多少,文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • C語言實(shí)現(xiàn)YUV文件轉(zhuǎn)JPEG格式

    C語言實(shí)現(xiàn)YUV文件轉(zhuǎn)JPEG格式

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)將YUV文件轉(zhuǎn)為JPEG格式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 深入解析C++和JAVA的字符串

    深入解析C++和JAVA的字符串

    這篇文章主要介紹了C++和JAVA的字符串,JAVA 中String 和StringBuffer的區(qū)別,需要的朋友可以參考下
    2015-07-07
  • C語言數(shù)據(jù)結(jié)構(gòu)進(jìn)階之棧和隊(duì)列的實(shí)現(xiàn)

    C語言數(shù)據(jù)結(jié)構(gòu)進(jìn)階之棧和隊(duì)列的實(shí)現(xiàn)

    棧和隊(duì)列,嚴(yán)格意義上來說,也屬于線性表,因?yàn)樗鼈円捕加糜诖鎯壿嬯P(guān)系為 "一對一" 的數(shù)據(jù),但由于它們比較特殊,因此將其單獨(dú)作為一章,做重點(diǎn)講解
    2021-11-11
  • C++指針學(xué)習(xí)詳解

    C++指針學(xué)習(xí)詳解

    指針在 C\C++ 語言中是很重要的內(nèi)容,并且和指針有關(guān)的內(nèi)容一向令初學(xué)者頭大,這篇文章主要給大家介紹了關(guān)于C/C++中指針的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • C++中對象&類的深入理解

    C++中對象&類的深入理解

    這篇文章主要給大家介紹了關(guān)于C++中對象&類的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • C++中如何實(shí)現(xiàn)回調(diào)的方法示例

    C++中如何實(shí)現(xiàn)回調(diào)的方法示例

    這篇文章主要給大家介紹了關(guān)于C++中如何實(shí)現(xiàn)回調(diào)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用c++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • C++映像劫持后門實(shí)例分析

    C++映像劫持后門實(shí)例分析

    這篇文章主要介紹了C++映像劫持后門,實(shí)例分析了C++映像劫持后門的原理與相關(guān)實(shí)現(xiàn)技巧,有助于進(jìn)一步了解后門的原理,需要的朋友可以參考下
    2015-04-04
  • C++ Boost Heap使用實(shí)例詳解

    C++ Boost Heap使用實(shí)例詳解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個(gè)可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • VC多線程編程詳解

    VC多線程編程詳解

    這篇文章主要介紹了VC多線程編程,實(shí)例形式詳細(xì)分析了多線程編程的原理與實(shí)現(xiàn)方法,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-10-10

最新評論

新乡县| 仁化县| 定南县| 玉田县| 哈尔滨市| 新干县| 车致| 新民市| 呼伦贝尔市| 上林县| 尼木县| 吴忠市| 滦南县| 正安县| 丽水市| 彰化县| 突泉县| 成都市| 鄂州市| 乐昌市| 南投市| 新泰市| 龙井市| 青岛市| 且末县| 南华县| 娄底市| 包头市| 隆子县| 云林县| 盱眙县| 武威市| 长治县| 遂昌县| 台山市| 博罗县| 海安县| 太和县| 苍南县| 桂平市| 礼泉县|