使用 OpenCV 和机器学习进行简单的对象检测

我必须使用 OpenCV 编写一个对象检测器(在本例中为一个球).问题是,谷歌上的每一次搜索都会给我返回一些带有人脸检测的东西.所以我需要关于从哪里开始、使用什么等方面的帮助.

I have to code an object detector (in this case, a ball) using OpenCV. The problem is, every single search on google returns me something with FACE DETECTION in it. So i need help on where to start, what to use etc..

一些信息:

  • 球没有固定的颜色,它可能是白色的,但可能会改变.
  • 我必须使用机器学习,不一定是复杂可靠的机器学习,建议是 KNN(它更简单、更容易).
  • 经过我的所有搜索,我发现计算样本球图像的直方图并将其教授给机器学习可能很有用,但我在这里主要担心的是球的大小可能并且将会改变(离球越来越近,越来越远)相机),我不知道要传递给 ML 什么来为我分类,我的意思是..我不能(或者我可以?)只测试每个可能尺寸的图像的每个像素(从,可以说,5x5 到 WxH)并希望找到一个积极的结果.
  • 可能存在不统一的背景,例如人、球后面的布料等.
  • 正如我所说,我必须使用机器学习算法,这意味着没有 Haar 或 Viola 算法.

所以...建议?

提前致谢.;)

推荐答案

嗯,基本上你需要检测圈子.你见过 cvHoughCircles() 吗?可以使用吗?

Well, basically you need to detect circles. Have you seen cvHoughCircles()? Are you allowed to use it?

这个页面有关于如何检测东西的很好的信息使用 OpenCV.您可能对第 2.5 节.

This page has good info on how detecting stuff with OpenCV. You might be more interested on section 2.5.

这是我刚写的一个小演示,用于检测这张图片中的硬币.希望您可以利用代码的某些部分来发挥自己的优势.

This is a small demo I just wrote to detect coins in this picture. Hopefully you can use some part of the code to your advantage.

输入:

输出:

// compiled with: g++ circles.cpp -o circles `pkg-config --cflags --libs opencv`
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>

int main(int argc, char** argv)
{
    IplImage* img = NULL;

    if ((img = cvLoadImage(argv[1]))== 0)
    {
        printf("cvLoadImage failed
");
    }

    IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
    CvMemStorage* storage = cvCreateMemStorage(0);

    cvCvtColor(img, gray, CV_BGR2GRAY);

    // This is done so as to prevent a lot of false circles from being detected
    cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7);

    IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
    IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
    cvCanny(gray, canny, 50, 100, 3);

    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, gray->height/3, 250, 100);
    cvCvtColor(canny, rgbcanny, CV_GRAY2BGR);

    for (size_t i = 0; i < circles->total; i++)
    {
         // round the floats to an int
         float* p = (float*)cvGetSeqElem(circles, i);
         cv::Point center(cvRound(p[0]), cvRound(p[1]));
         int radius = cvRound(p[2]);

         // draw the circle center
         cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0 );

         // draw the circle outline
         cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0 );

         printf("x: %d y: %d r: %d
",center.x,center.y, radius);
    }


    cvNamedWindow("circles", 1);
    cvShowImage("circles", rgbcanny);

    cvSaveImage("out.png", rgbcanny);
    cvWaitKey(0);

    return 0;
}

圆的检测很大程度上取决于cvHoughCircles()的参数.请注意,在这个演示中,我也使用了 Canny.

The detection of the circles depend a lot on the parameters of cvHoughCircles(). Note that in this demo I used Canny as well.

相关文章