私は次のコードに取り組んでいます:
_#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
Mat src, grey;
int thresh = 10;
const char* windowName = "Contours";
void detectContours(int,void*);
int main()
{
src = imread("C:/Users/Public/Pictures/Sample Pictures/Penguins.jpg");
//Convert to grey scale
cvtColor(src,grey,CV_BGR2GRAY);
//Remove the noise
cv::GaussianBlur(grey,grey,Size(3,3),0);
//Create the window
namedWindow(windowName);
//Display the original image
namedWindow("Original");
imshow("Original",src);
//Create the trackbar
cv::createTrackbar("Thresholding",windowName,&thresh,255,detectContours);
detectContours(0,0);
waitKey(0);
return 0;
}
void detectContours(int,void*)
{
Mat canny_output,drawing;
vector<vector<Point>> contours;
vector<Vec4i>heirachy;
//Detect edges using canny
cv::Canny(grey,canny_output,thresh,2*thresh);
namedWindow("Canny");
imshow("Canny",canny_output);
//Find contours
cv::findContours(canny_output,contours,heirachy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
//Setup the output into black
drawing = Mat::zeros(canny_output.size(),CV_8UC3);
//Draw contours
for(int i=0;i<contours.size();i++)
{
cv::drawContours(drawing,contours,i,Scalar(255,255,255),1,8,heirachy,0,Point());
}
imshow(windowName,drawing);
}
_
理論的には、Contours
は曲線を検出することを意味します。 _Edge detection
_は、エッジの検出を意味します。上記のコードでは、Canny
を使用したエッジ検出とfindContours()
による曲線検出を実行しました。結果の画像は次のとおりです
キャニー画像
輪郭画像
ご覧のとおり、違いはありません!では、これら2つの実際の違いは何ですか? OpenCVチュートリアルでは、コードのみが提供されています。 「輪郭」とは何かについての説明を見つけましたが、この問題に対処していません。
Edgesは、勾配の方向における画像勾配の極値である点として計算されます。役立つ場合は、1D関数の最小点と最大点と考えることができます。重要なのは、エッジピクセルはローカルな概念であるということです。つまり、隣接するピクセル間の大きな違いを指しているだけです。
Contoursは、多くの場合、エッジから取得されますが、オブジェクトの輪郭であることを目的としています。したがって、それらは閉じた曲線である必要があります。それらはboundariesと考えることができます(一部の画像処理アルゴリズムとライブラリはそれらをそのように呼び出します)。エッジから取得する場合、閉じた輪郭を取得するためにエッジを接続する必要があります。
エッジとカントリーの検索の主な違いは、エッジの検索を実行すると、出力が新しい画像になることです。この新しい(エッジ画像)画像では、エッジが強調表示されます。エッジを検出するための多くのアルゴリズムがあります wikiもご覧ください 。
たとえば、Sobel演算子は滑らかな「霧」の結果をもたらします。特定のケースでは、キャッチはCanny Edge Detectorを使用していることです。これは、他の検出器よりも数ステップ先に進みます。実際には、さらにエッジの洗練ステップを実行します。したがって、Canny検出器の出力は、エッジの代わりに1ピクセル幅の線を含むバイナリイメージです。
一方、Contours
アルゴリズムは任意のバイナリイメージを処理します。だから、黒い背景に白い塗りつぶされた正方形を入れると。 Contours
アルゴリズムを実行した後、白い空の正方形、境界のみが得られます。
輪郭検出のその他の追加のボーナスは、実際にポイントのセットを返すことです!これらのポイントをさらに処理するために使用できるため、これは素晴らしいことです。
特定のケースでは、両方の画像が一致するのは偶然です。それはルールではなく、あなたの場合、それはCannyアルゴリズムのユニークな特性によるものです。
輪郭は、実際には「単なる」エッジの検出以上のことができます。アルゴリズムは実際に画像のエッジを検出しますが、階層に配置します。これは、画像で検出されたオブジェクトの外側の境界線をリクエストできることを意味します。このようなことは、エッジのみをチェックする場合は(直接)不可能です。
ドキュメントで読むことができるように、輪郭は主にオブジェクト認識に使用されます。この場合、エッジ検出器はより「グローバル」な操作です。輪郭アルゴリズムが何らかの種類のエッジ検出を使用していても驚かないでしょう。
輪郭の概念は、エッジデータを操作するためのツールとして使用されます。すべてのエッジが同じではありません。しかし、多くの場合、例えば単峰性の色分布(つまり1色)を持つオブジェクト、エッジは実際の輪郭(輪郭、形状)です。
[1]国境追跡によるデジタル化されたバイナリ画像のトポロジカル構造解析、鈴木S、1985年。