2

cvHoughCircles を使用して、次の画像で 2 つの白い楕円形を見つけています。

ここに画像の説明を入力

最初にしきい値処理を使用して白い領域を特定し、次にハフ変換を使用しました。ただし、以下に示すように、出力は正しくありません。

ここに画像の説明を入力

何が起こっているのか理解できませんか?なぜ 3 つの円が検出され、なぜ 1 つだけが正しく検出されるのですか? 助言がありますか?

以下は私のコードです:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <math.h> 
#include <ctype.h>
#include <stdlib.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include<conio.h>
#include<malloc.h>



using namespace cv;
using namespace std;
int main( ) {
IplImage* image = cvLoadImage( 
"testing.bmp",
  CV_LOAD_IMAGE_GRAYSCALE
);

IplImage* src = cvLoadImage("testing.bmp");
CvMemStorage* storage = cvCreateMemStorage(0);


cvThreshold( src, src,  200, 255, CV_THRESH_BINARY );

CvSeq* results = cvHoughCircles( 
image, 
 storage, 
 CV_HOUGH_GRADIENT, 
 3, 
 image->width/10 
 ); 

 for( int i = 0; i < results->total; i++ ) 
 {
 float* p = (float*) cvGetSeqElem( results, i );
 CvPoint pt = cvPoint( cvRound( p[0] ), cvRound( p[1] ) );
 cvCircle( 
  src,
  pt, 
  cvRound( p[2] ),
  CV_RGB(0xff,0,0) 
);
}
cvNamedWindow( "HoughCircles", 1 );
cvShowImage( "HoughCircles", src);
cvWaitKey(0);
} 

編集:

ハフ変換では満足のいく結果が得られないので、別の方法を試してみます。図の各白いブロブは同じサイズ (サイズは既知) であり、ブロブ間の距離も既知であると想定できます。左の白いブロブの左側に接する垂直線 (接線) を見つけることができる重要な方法はありますか? この接線がわかると、境界の位置がわかります。次に、x=(この位置 + 半径 (既知))、y= この位置に円を描きます。いくつかの重要な方法を使用して、そのような x 座標と y 座標を見つけることはできますか?

以下のように変更することで解決しました。

cvThreshold(image, image,  220, 255, CV_THRESH_BINARY );

cvCanny(image, image, 255, 255, 3);


cvNamedWindow( "edge", 1 );
cvShowImage( "edge", image);
cvWaitKey(0);

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* results = cvHoughCircles( 
             image, 
             storage, 
             CV_HOUGH_GRADIENT, 
             4, 
             image->width/4, 100,100,0,50); 

出力は次のとおりです。

ここに画像の説明を入力

4

2 に答える 2

3

パラメータがすべてです

IplImage* src = cvLoadImage(argv[1]);
if (!src)
{
    cout << "Failed: unable to load image " << argv[1] << endl;
    return -1;
}

//IplImage* image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
IplImage* image = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
cvCvtColor(src, image, CV_RGB2GRAY);

cvThreshold(image, image,  220, 255, CV_THRESH_BINARY );
//  cvNamedWindow( "thres", 1 );
//  cvShowImage( "thres", image);
//  cvWaitKey(0);

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* results = cvHoughCircles( 
                 image, 
                 storage, 
                 CV_HOUGH_GRADIENT, 
                 4, 
                 image->width/3); 

std::cout << "> " << results->total << std::endl;

for( int i = 0; i < results->total; i++ ) 
{
    float* p = (float*) cvGetSeqElem( results, i );
    CvPoint pt = cvPoint( cvRound( p[0] ), cvRound( p[1] ) );
    cvCircle(src,
             pt, 
             cvRound( p[2] ),
             CV_RGB(0xff,0,0));
}

cvNamedWindow( "HoughCircles", 1 );
cvShowImage( "HoughCircles", src);
cvWaitKey(0);

もう少し実験を行った場合、最終的には、異なるパラメーターを使用すると異なる結果が得られることがわかります。

于 2012-05-18T13:48:46.807 に答える
2

しきい値ではなく、エッジ検出画像を入力として使用する必要があります。第二に、円に非常に近い場合を除き、ハフ円は楕円には機能しません。Generalized Hough Transformについて読んで、楕円に実装することをお勧めします。

于 2012-05-22T08:13:16.197 に答える