ハフ変換
定義
ハフ変換は特徴抽出の一種であり、画像分析
、コンピュータービジョン、デジタル画像処理で広く使用されています。
ハフ変換はオブジェクトの特徴を識別するために使用され、プロセスはおおよそ次のとおりです。
区別される形状のタイプであるオブジェクトが与えられると、アルゴリズムはパラメータ空間で投票を実行してオブジェクトの形状を決定します。これは、決定されたアキュムレータ空間の極大値によって決定されます。
一般的に使用されるハフ変換
-
1.ハフライン変換:画像内で直線を見つけます
-
2.ハフ円変換:画像内で円を見つけます。
ハフ線形変換
- ハフライン変換は直線検出に使用されます
- 前提条件-
キャニーエッジ検出が完了している、入力8ビット画像、出力シングルチャネル8ビットグレースケール画像 - 平面空間から極座標空間への変換
検出された線が直線であることを知る方法は?
画像は最初に極座標に変換されます極座標の
中点はrとθによって特徴付けられます。
つまり
、上記の式に従って、次の式を導出できます。
導出プロセスは次のようになります。
式は何をしますか?
たとえば
、上記の直線の場合、次の5つの点が直線上にあります。
したがって、5つの直線を取得できます。
θを横軸、rを縦軸とすると、これら5本の直線を同じ座標系で描くと次のようになります。
これらの5本の直線が同じ点で交差していることがわかりました。これが直線の特徴です。この機能を使用してすべての直線を累積します。交点はすべての直線の合計であるため、ピクセル値を最大にする必要があります。 。私たちは知っています、ピクセルが高いほど、画像は明るくなり、255に達すると、最も明るくなります。つまり、白になります。したがって、この方法で直線を検出できます。
視覚的な説明
このような画像があり、対応する極座標画像は次のとおりです。
白い点は直線が交差する場所です。
極座標を使用して直線の位置を推測できます。
HoughLines
このAPIの最終出力は極座標の座標です。つまり
、(θ、r)の最終結果を計算し直すのは難しいため、opencvにHoughLines
があり、ここでHoughLinesを紹介します。
HoughLines(
InputArray image,
OutputArray lines,
double rho,
double theta,
int threshold,
double srn = 0,
double stn = 0,
double min_theta = 0,
double max_theta = CV_PI
);
(1)InputArrayタイプsrc、8ビット、シングルチャネルバイナリソースイメージ(グレースケールイメージ)。
(2)直線の出力ベクトルであるOutputArrayタイプの線。各直線は、2要素のベクトルで表されます。rhoは、座標の原点(画像の左上隅)からの距離(0,0)です。シータは、ラジアン単位の線の回転角です。
(3)ダブルタイプロー、アキュムレータの距離分解能(ピクセル)、通常1
(4)ダブルタイプシータ、アキュムレータの角度分解能(ラジアン)。一般的な値はCV_PI / 180で、毎回1度です。
(5)int型のしきい値、アキュムレータしきい値パラメータ。アキュムレータが十分にあるリターンラインのみ。通常は10を使用します。10ピクセルをラインとしてカウントします。ラインが十分に長い場合は、100に変更できます。
(6)ダブルタイプsrn、マルチスケールハフ変換の場合、距離分解能rhoの約数、粗いアキュムレータ距離分解能はrho、正確なアキュムレータ分解能はrho / srnです。srn = 0およびstn = 0の場合、古典的なハフ変換が使用されます。それ以外の場合、これらのパラメーターは両方とも正である必要があります。マルチスケールハフ変換を使用しない場合は0に設定します
(7)ダブルタイプsth、マルチスケールハフ変換の場合、距離分解能θの約数です。マルチスケールハフ変換を使用しない場合は0に設定します
(8)double型のmin_thetaは、直線の最小角度をチェックするための標準およびマルチスケールのハフ変換に使用されます。0からmaxθの間でなければなりません。
(9)標準およびマルチスケールのハフ変換に使用されるダブルタイプmax_thetaは、線の最大角度をチェックするために使用されます。最小θとCVπの間にある必要があります。
HoughLinesP
この関数は座標を直接返します。
このAPIを使用することをお勧めします
HoughLines(
InputArray image,
OutputArray lines,
double rho,
double theta,
int threshold,
double minLineLength = 0,
double maxLineGap = 0
);
(1)InputArrayタイプsrc、8ビット、シングルチャネルバイナリソースイメージ(グレースケールイメージ)。
(2)直線の出力ベクトルであるOutputArrayタイプの線。各直線は、2要素のベクトルで表されます。rhoは、座標の原点(画像の左上隅)からの距離(0,0)です。シータは、ラジアン単位の線の回転角です。
(3)ダブルタイプのローの場合、アキュムレータの距離分解能(ピクセル)は通常1です。
(4)ダブルタイプシータの場合、アキュムレータの角度分解能(ラジアン)は通常CV_PI / 180で、毎回1度です。
(5)int型のしきい値、アキュムレータしきい値パラメータ。十分なアキュムレータがあるラインのみを返します。通常は10、10ピクセルを直線として数えますが、直線が十分に長い場合は100に変更できます。
(6)double型のminLineLength、最小行長。この値よりも小さい線分は拒否されます。
(7)ダブルタイプmaxLineGap、同じライン上のポイントをリンクすることによって許可される最大距離。
コード
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src, src_gray, dst;
src = imread("C:/Users/86176/Pictures/pics/lines.jpg");
if (!src.data)
{
cout << "could not load image !";
return -1;
}
imshow("【输入图像】", src);
GaussianBlur(src, src, Size(3, 3), 0, 0);
Canny(src, src_gray, 0, 255);
cvtColor(src_gray, dst, CV_GRAY2BGR);
imshow("【获取边缘】", src_gray);
vector<Vec4f> plines;
HoughLinesP(src_gray, plines, 1, CV_PI / 180.0, 100, 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("【输出图像】", dst);
waitKey(0);
return 0;
}