CV Hough Circle Параметры для обнаружения кругов - PullRequest
1 голос
/ 12 октября 2011

Я пытаюсь обнаружить 22 шара на столе для снукера. У меня есть изображение для тестирования, но программа обнаруживает 2 шара и случайные круги в другом месте. Мой код ниже с алгоритмом обнаружения круга. Кто-нибудь знает, какие параметры должны быть отрегулированы, чтобы получить обнаружение, в котором я нуждался бы? спасибо

#include <cv.h>
#include <highgui.h>
#include <math.h>

int main(int argc, char** argv)
{   int edge_thresh = 1;
    IplImage* img = cvLoadImage("C:\\Users\\Nathan\\Desktop\\SnookerPic.png", 1);;
    IplImage* gray = cvCreateImage(cvGetSize(img), 8, 1);
     IplImage *edge = cvCreateImage( cvSize(img->width,img->height), 8, 1);
    CvMemStorage* storage = cvCreateMemStorage(0);
    cvCvtColor(img, gray, CV_BGR2GRAY);
    cvThreshold(gray,gray, CV_GAUSSIAN, 9, 9);
    cvSmooth(gray, gray, CV_GAUSSIAN, 11, 11); 
    cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 5);
    CvSeq* circles = cvHoughCircles(edge, storage, 
        CV_HOUGH_GRADIENT, 2, 20, 200, 50);
    int i;

    for (i = 0; i < circles->total; i++) 
    {
         float* p = (float*)cvGetSeqElem( circles, i );
         cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 
             3, CV_RGB(0,255,0), -1, 8, 0 );
         cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 
             cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
    }
    cvNamedWindow( "circles", 1 );
    cvShowImage( "circles", img );


    return 0;
}

Ответы [ 2 ]

2 голосов
/ 12 октября 2011

Я подозреваю, что у вас возникли проблемы с параметрами, которые являются слишком ограничивающими или нестабильными. Вы должны играть с параметрами, пока не получите желаемое количество кругов. Кроме того, размытие по Гауссу 11x11 может быть немного агрессивным в зависимости от изображения. Для моего имиджа это приносило больше вреда, чем пользы, но мой имидж как бы идеализирован ...

Я изменил пример OpenCV, который вы используете, чтобы включить полосы треков, позволяющие играть с параметрами Canny. Это должно действительно помочь вам почувствовать, как это работает. Также обратите внимание на параметр minDist. Для моего изображения центры кругов были на расстоянии около 32 пикселей. Вы должны будете приспособить это к своим размерам круга. Итак, вот образец:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int hi = 1, lo = 1;

int main(int argc, char* argv[]) {
    Mat orig = imread("Snooker_balls_triangled.png");
    int key = 0;

    namedWindow("circles", 1);
    createTrackbar("hi", "circles", &hi, 255);
    createTrackbar("lo", "circles", &lo, 255);

    do
    {
        // update display and snooker, so we can play with them
        Mat display = orig.clone();

        Mat snooker;
        cvtColor(orig, snooker, CV_RGB2GRAY);

        vector<Vec3f> circles;

        // also preventing crash with hi, lo threshold here...
        HoughCircles(snooker, circles, CV_HOUGH_GRADIENT, 2, 32.0, hi > 0 ? hi : 1, lo > 0 ? lo : 1 );
        for( size_t i = 0; i < circles.size(); i++ )
        {
             Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
             int radius = cvRound(circles[i][2]);

             // draw the green circle center
             circle( display, center, 3, Scalar(0,255,0), -1, 8, 0 );

             // draw the blue circle outline
             circle( display, center, radius, Scalar(255,0,0), 3, 8, 0 );
        }

        imshow( "circles", display );
        imshow("snooker", snooker);
        key = waitKey(33);
    } while((char)key != 27);
    return 0;
}

Я использовал это снукерное изображение , а это - это вывод, который я получаю.

(П.С. рассмотрите возможность использования интерфейса C ++, он намного превосходит интерфейс C ++, ИМХО:)

0 голосов
/ 28 ноября 2013

Если вы используете iOS, вам нужно включить ios.h или просто написать свои собственные методы класса для обработки img proc из cvMat в UIImage и наоборот.

Пожалуйста, извините за комментарииони только для тех, у кого, возможно, есть те же самые «бредовые» исследования, что и у меня.Каждое изображение потребует совершенно разных настроек.Не сдавайся.Houghcircles - это лучший алгоритм обнаружения.Я собираюсь объединить некоторый игровой код с обнаружением, чтобы сделать его лучше, проще, быстрее.

    #import "JmBViewController.h"

@interface JmBViewController ()

@end

@implementation JmBViewController

- (void)viewDidLoad {
[super viewDidLoad];
_imgtest = [UIImage imageNamed:@"IMG_0424.PNG"];

cv::Mat cvImage;
UIImageToMat(_imgtest, cvImage);
if (!cvImage.empty()) {
    cv::Mat gray;
  //  cv::Mat filteredMat;
    cv::cvtColor(cvImage, gray, CV_BGRA2GRAY);
   // cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.2, 1.2);
    cv::vector<cv::Vec3f> circles;
    //cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, 50);
    /*
    for(size_t i = 0; i < circles.size(); i++)
    {
        cv::Point center((cvRound(circles[i][0]), cvRound(circles[i][1])));
        int radius = cvRound(circles[i][2]);
        cv::circle(gray, center, 3, cv::Scalar(0,255,0));
        cv::circle(gray, center, radius, cv::Scalar(0,0,255));
    }
   */

 //  for ( int i = 1; i < 15; i = i + 2 )

        cv::GaussianBlur(gray, gray, cv::Size(9, 9), 1.5, 1.5);

        cv::Mat edges;
        cv::Canny(gray, edges, 0, 50);
        //gray.setTo(cv::Scalar::all(0));
        //gray.setTo(cv::Scalar::all(255), edges);
        cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, gray.rows/30, 100, 50, 10, 30 );
        for(size_t i = 0; i < circles.size(); i++)
        {
            cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
            int radius = cvRound(circles[i][2]);
            cv::circle(cvImage, center, 5, cv::Scalar::all(200), -1, 8, 0 );//center
            cv::circle(cvImage, center, radius, cv::Scalar::all(255), 3, 8, 0 );//diamter
        NSLog(@"Circles: %ld", i+1);

       // cv::imshow(&"circles i " [ i], gray);
    }


    _imgView.image = MatToUIImage(cvImage);
    }
    /*
cv::Mat cvImage;
cv::Mat grey;
cv::Mat filteredMat;
cv::vector<cv::Vec3f> circles;
// cv::cvtColor(_imgtest, cvImage, CV_BGR2GRAY);
cv::threshold(grey, filteredMat, 100, 255, CV_THRESH_BINARY);
[UIImageCVMatConverter cvMatGrayFromUIImage:_imgtest];
//  cv::cvtColor(cvImage, grey, CV_RGBA2GRAY);
// UIImageToMat(_imgtest, cvImage);
cv::HoughCircles(cvImage, circles, CV_HOUGH_GRADIENT, 1, 50);
//  MatToUIImage(cvImage);
_imgView.image = [UIImageCVMatConverter UIImageFromCVMat:cvImage];
_imgView.image = MatToUIImage(cvImage);
*/

// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*

UIImage* MatToUIImage(const cv::Mat& image) {
NSData *data = [NSData dataWithBytes:image.data length:image.elemSize()*image.total()];
CGColorSpaceRef colorSpace;
if (image.elemSize() == 1) {
    colorSpace = CGColorSpaceCreateDeviceGray();
}else { colorSpace = CGColorSpaceCreateDeviceRGB();
 }
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

CGImageRef imageRef = CGImageCreate(image.cols, image.rows, 8, 8*image.elemSize(), image.step.p[0], colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, FALSE, kCGRenderingIntentDefault);
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];

return finalImage;
 }
 */


@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...