目錄
一、霍夫變換簡介
1、霍夫變換的原理
2、霍夫變換的優(yōu)點(diǎn)
3、霍夫變換的缺點(diǎn)
4、霍夫變換的應(yīng)用場景
5、使用霍夫變換的步驟
二、霍夫變換—直線檢測
1、霍夫直線變換介紹
2、霍夫直線變換的例子
3、相關(guān)API學(xué)習(xí)(代碼例子)
三、霍夫變換—圓檢測
1、霍夫圓檢測原理
2、相關(guān)API學(xué)習(xí)(代碼例子)
一、霍夫變換簡介
霍夫變換(Hough Transform)是一種在圖像處理中常用的技術(shù),用于檢測圖像中的直線、圓或其他形狀。
在霍夫變換中,直線通常由兩個參數(shù)表示:斜率和截距。對于每個圖像中的點(diǎn),都可以在參數(shù)空間中繪制出與該點(diǎn)相關(guān)的曲線。當(dāng)多個點(diǎn)共線時,它們在參數(shù)空間中的曲線會相交于同一個點(diǎn),從而形成一個峰值。通過尋找參數(shù)空間中的峰值,我們可以確定圖像中存在的直線。
1、霍夫變換的原理
它的原理是將圖像中的每個點(diǎn)轉(zhuǎn)換為參數(shù)空間中的曲線或曲面,并通過對這些曲線或曲面進(jìn)行累加來找到圖像中的特定形狀。
(1)霍夫空間:對于待檢測的形狀,霍夫變換將其在參數(shù)空間中表示。對于直線檢測,參數(shù)空間通常是極坐標(biāo)空間,其中兩個參數(shù)分別表示直線的長度和角度。對于圓和橢圓檢測,參數(shù)空間則包括圓心和半徑或橢圓參數(shù)。
(2)累加過程:對于圖像中的每個邊緣點(diǎn),通過遍歷參數(shù)空間,將其轉(zhuǎn)換為參數(shù)空間中的曲線或曲面。當(dāng)多個邊緣點(diǎn)共線或共圓時,在參數(shù)空間中會出現(xiàn)峰值。這些峰值表示了可能存在的形狀。
(3)閾值和篩選:根據(jù)設(shè)定的閾值,選擇參數(shù)空間中的峰值作為檢測結(jié)果。通常選擇峰值強(qiáng)度高于閾值的部分,并進(jìn)行進(jìn)一步的篩選和優(yōu)化。
(4)反變換:根據(jù)檢測到的參數(shù),在原始圖像中繪制出相應(yīng)的形狀。對于直線檢測,可以通過計算兩個端點(diǎn)的坐標(biāo);對于圓和橢圓檢測,可以通過計算圓心和半徑或橢圓參數(shù)。
通過以上步驟,霍夫變換可以在圖像中檢測出特定形狀的位置和參數(shù)。
2、霍夫變換的優(yōu)點(diǎn)
(1)霍夫變換是一種基于幾何特征的圖像處理方法,對于形狀檢測具有較好的魯棒性。它不依賴于形狀的大小、方向和位置,能夠在圖像中準(zhǔn)確地檢測出各種形狀。
(2)霍夫變換可以應(yīng)用于不同類型的形狀檢測,包括直線、圓、橢圓等。通過適當(dāng)選擇參數(shù)表示方式和累加過程,可以擴(kuò)展到其他形狀的檢測。
(3)霍夫變換可以應(yīng)用于圖像中存在噪聲或部分遮擋的情況下。通過合適的預(yù)處理和參數(shù)設(shè)置,可以提高對形狀的檢測準(zhǔn)確性。
3、霍夫變換的缺點(diǎn)
(1)霍夫變換的計算復(fù)雜度較高,特別是對于大尺寸圖像和復(fù)雜形狀的檢測。這會導(dǎo)致算法的執(zhí)行時間較長,不適用于實(shí)時應(yīng)用或?qū)τ嬎阗Y源要求較高的場景。
(2)霍夫變換對圖像中的噪聲比較敏感,因此需要進(jìn)行預(yù)處理來降低噪聲的影響。這可能會引入額外的步驟和計算開銷。
(3)霍夫變換對參數(shù)的選擇較為敏感,不同形狀的檢測可能需要不同的參數(shù)設(shè)置。這對于非專業(yè)用戶來說可能會增加使用的難度。
(4)霍夫變換在處理曲線或曲面交叉的情況下可能會出現(xiàn)誤檢測或漏檢的問題。特別是當(dāng)形狀之間存在相似性或重疊時,可能會導(dǎo)致結(jié)果的不準(zhǔn)確性。
總體而言,霍夫變換是一種強(qiáng)大的圖像處理技術(shù),但在實(shí)際應(yīng)用中需要綜合考慮其優(yōu)點(diǎn)和缺點(diǎn),并結(jié)合具體場景進(jìn)行參數(shù)調(diào)整和算法改進(jìn)。
4、霍夫變換的應(yīng)用場景
(1)直線檢測:霍夫變換最常用的應(yīng)用之一是檢測圖像中的直線。通過將圖像中的每個點(diǎn)轉(zhuǎn)換為參數(shù)空間中的曲線,可以找到共線點(diǎn)形成的峰值,從而確定直線的位置和方向。
(2)圓檢測:除了直線,霍夫變換也可以用于檢測圖像中的圓。通過將圖像中的每個點(diǎn)轉(zhuǎn)換為參數(shù)空間中的曲面,可以找到共圓心的曲面交點(diǎn),從而確定圓的位置和半徑。
(3)橢圓檢測:類似地,霍夫變換還可以用于檢測圖像中的橢圓。通過將圖像中的每個點(diǎn)轉(zhuǎn)換為參數(shù)空間中的曲面,可以找到共橢圓參數(shù)的曲面交點(diǎn),從而確定橢圓的位置、長軸和短軸。
(4)形狀匹配:除了檢測特定形狀,霍夫變換還可以用于形狀匹配。通過將待匹配形狀在參數(shù)空間中表示,并與圖像中的曲線或曲面進(jìn)行匹配,可以找到與待匹配形狀相似的圖像區(qū)域。
5、使用霍夫變換的步驟
(1)邊緣檢測:首先對圖像進(jìn)行邊緣檢測,例如使用Canny邊緣檢測算法。這可以幫助減少噪聲和提取出形狀的邊緣。
(2)參數(shù)空間設(shè)置:根據(jù)待檢測的形狀類型,選擇合適的參數(shù)空間。對于直線檢測,通常使用極坐標(biāo)空間,其中兩個參數(shù)分別表示直線的長度和角度。對于圓和橢圓檢測,參數(shù)空間則包括圓心和半徑或橢圓參數(shù)。
(3)累加過程:遍歷邊緣點(diǎn),并將其轉(zhuǎn)換為參數(shù)空間中的曲線或曲面。通過累加過程,找到在參數(shù)空間中出現(xiàn)峰值的位置,這些峰值表示可能存在的形狀。
(4)閾值和篩選:根據(jù)設(shè)定的閾值,選擇參數(shù)空間中的峰值作為檢測結(jié)果。通常選擇峰值強(qiáng)度高于閾值的部分,并進(jìn)行進(jìn)一步的篩選和優(yōu)化。
(5)反變換:根據(jù)檢測到的參數(shù),在原始圖像中繪制出相應(yīng)的形狀。對于直線檢測,可以通過計算兩個端點(diǎn)的坐標(biāo);對于圓和橢圓檢測,可以通過計算圓心和半徑或橢圓參數(shù)。
(6)參數(shù)調(diào)優(yōu):根據(jù)實(shí)際需求,可能需要對參數(shù)進(jìn)行調(diào)優(yōu),以獲得更好的檢測結(jié)果。這包括閾值的選擇、參數(shù)空間的分辨率等。
(7)結(jié)果分析和后處理:對于檢測到的形狀,可以進(jìn)行進(jìn)一步的分析和處理。例如,可以根據(jù)形狀的位置和特征進(jìn)行分類或其他操作。
需要注意的是:霍夫變換對圖像中的噪聲比較敏感,因此在應(yīng)用之前通常需要進(jìn)行預(yù)處理,如邊緣檢測或?yàn)V波操作。
二、霍夫變換—直線檢測
1、霍夫直線變換介紹
(1)Hough Line Transform用來做直線檢測
(2)前提條件 – 邊緣檢測已經(jīng)完成 (cv::Canny,輸入的是8位的圖像可以是單通道或多通道,輸出的是8位單通道的灰度圖像,再通過threshold轉(zhuǎn)化為二值化圖像)
(3)平面空間到極坐標(biāo)空間轉(zhuǎn)換????????
? ? ? ? 極坐標(biāo)也就是霍夫空間的坐標(biāo)。
2、霍夫直線變換的例子
(1)對于任意一條直線上的所有點(diǎn)來說
(2)變換到極坐標(biāo)中,從[0~360]空間,可以得到r的大小
(3)屬于同一條直線上點(diǎn)在極坐標(biāo)空(r, theta)必然在一個點(diǎn)上有最強(qiáng)的信號出現(xiàn),根據(jù)此反算到平面坐標(biāo)中就可以得到直線上各點(diǎn)的像素坐標(biāo)。從而得到直線
(4)從平面坐標(biāo)變換到霍夫空間(極坐標(biāo))
3、相關(guān)API學(xué)習(xí)(代碼例子)
(1)標(biāo)準(zhǔn)的霍夫變換 cv::HoughLines從平面坐標(biāo)轉(zhuǎn)換到霍夫空間,最終輸出是極坐標(biāo)空間;表示形式為:。
cv::HoughLines(
InputArray src, // 輸入圖像,必須8-bit的灰度圖像
OutputArray lines, // 輸出的極坐標(biāo)來表示直線
double rho, // 生成極坐標(biāo)時候的像素掃描步長
double theta, //生成極坐標(biāo)時候的角度步長,一般取值CV_PI/180
int threshold, // 閾值,只有獲得足夠交點(diǎn)的極坐標(biāo)點(diǎn)才被看成是直線
double srn=0;// 是否應(yīng)用多尺度的霍夫變換,如果不是設(shè)置0表示經(jīng)典霍夫變換
double stn=0;//是否應(yīng)用多尺度的霍夫變換,如果不是設(shè)置0表示經(jīng)典霍夫變換
double min_theta=0; // 表示角度掃描范圍 0 ~180之間, 默認(rèn)即可
double max_theta=CV_PI
) // 一般情況是有經(jīng)驗(yàn)的開發(fā)者使用,需要自己反變換到平面空間(少用)
(2)霍夫變換直線概率 cv::HoughLinesP最終輸出是直線的兩個點(diǎn)(常用)
cv::HoughLinesP(
InputArray src, // 輸入圖像,必須8-bit的灰度圖像
OutputArray lines, // 輸出的極坐標(biāo)來表示直線
double rho, // 生成極坐標(biāo)時候的像素掃描步長
double theta, //生成極坐標(biāo)時候的角度步長,一般取值
CV_PI/180 int threshold, // 閾值,只有獲得足夠交點(diǎn)的極坐標(biāo)點(diǎn)才被看成是直線
double minLineLength=0;// 最小直線長度
double maxLineGap=0;// 最大間隔
)文章來源:http://www.zghlxwxcb.cn/news/detail-831502.html
(3)檢測結(jié)果
(4)代碼演示:
#include<opencv2\opencv.hpp>
#include<iostream>
#include <math.h>
using namespace cv;
using namespace std;
// Hough Line霍夫直線檢測
int main(int argc, char** argv) {
Mat src, src_gray, dst;
src = imread("line.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char INPUT_TITLE[] = "input image";
char OUTPUT_TITLE[] = "hough-line-detection";
namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
imshow(INPUT_TITLE, src);
// extract edge
Canny(src, src_gray, 150, 200);
cvtColor(src_gray, dst, CV_GRAY2BGR);
imshow("edge image", src_gray);
vector<Vec2f> lines;
HoughLines(src_gray, lines, 1, CV_PI / 180, 150, 0, 0);
for (size_t i = 0; i < lines.size(); i++) {
float rho = lines[i][0]; // 極坐標(biāo)中的r長度
float theta = lines[i][1]; // 極坐標(biāo)中的角度
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a * rho, y0 = b * rho;
// 轉(zhuǎn)換為平面坐標(biāo)的四個點(diǎn)
pt1.x = cvRound(x0 + 1000 * (-b));
pt1.y = cvRound(y0 + 1000 * (a));
pt2.x = cvRound(x0 - 1000 * (-b));
pt2.y = cvRound(y0 - 1000 * (a));
line(dst, pt1, pt2, Scalar(0, 0, 255), 1, CV_AA);
}
/*
vector<Vec4f> plines;
HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 10, 0, 10);
Scalar color = Scalar(0, 0, 255);
for (size_t i = 0; i < plines.size(); i++) {
Vec4f hline = plines[i];
line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA);
}*/
imshow(OUTPUT_TITLE, dst);
waitKey(0);
return 0;
}
效果展示:
三、霍夫變換—圓檢測
1、霍夫圓檢測原理
(1)從平面坐標(biāo)到極坐標(biāo)轉(zhuǎn)換三個參數(shù)
(2)假設(shè)平面坐標(biāo)的任意一個圓上的點(diǎn),轉(zhuǎn)換到極坐標(biāo)中: ? ? ? ? ? ? ? ? ? ? ? ? 處有最大值,霍夫變換正是利用這個原理實(shí)現(xiàn)圓的檢測。
2、相關(guān)API學(xué)習(xí)(代碼例子)
(1)cv::HoughCircles
因?yàn)榛舴驁A檢測對噪聲比較敏感,所以首先要對圖像做中值濾波。
基于效率考慮,Opencv中實(shí)現(xiàn)的霍夫變換圓檢測是基于圖像梯度的實(shí)現(xiàn),分為兩步: ?? ?
? ? ? ? 1)檢測邊緣,發(fā)現(xiàn)可能的圓心 ?? ?
? ? ? ? 2)基于第一步的基礎(chǔ)上從候選圓心開始計算最佳半徑大小
HoughCircles(
InputArray image, // 輸入圖像 ,必須是8位的單通道灰度圖像
OutputArray circles, // 輸出結(jié)果,發(fā)現(xiàn)的圓信息
Int method, // 方法 - HOUGH_GRADIENT
Double dp, // dp = 1;
Double mindist, // 10 最短距離-可以分辨是兩個圓的,否則認(rèn)為是同心圓- src_gray.rows/8 Double param1, // canny edge detection low threshold
Double param2, // 中心點(diǎn)累加器閾值 – 候選圓心
Int minradius, // 最小半徑 Int maxradius//最大半徑
)
(2)代碼演示:文章來源地址http://www.zghlxwxcb.cn/news/detail-831502.html
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("circle.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char INPUT_TITLE[] = "input image";
char OUTPUT_TITLE[] = "hough circle demo";
namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
imshow(INPUT_TITLE, src);
// 中值濾波
Mat moutput;
medianBlur(src, moutput, 3);
cvtColor(moutput, moutput, CV_BGR2GRAY);
// 霍夫圓檢測
vector<Vec3f> pcircles;
HoughCircles(moutput, pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 30, 5, 50);
src.copyTo(dst);
for (size_t i = 0; i < pcircles.size(); i++) {
Vec3f cc = pcircles[i];
circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 2, LINE_AA);
circle(dst, Point(cc[0], cc[1]), 2, Scalar(198, 23, 155), 2, LINE_AA);
}
imshow(OUTPUT_TITLE, dst);
waitKey(0);
return 0;
}
到了這里,關(guān)于13- OpenCV:霍夫檢測:直線、圓檢測的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!