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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6416117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:05:48  来源:igfitidea点击:

Simple object detection using OpenCV and machine learning

c++copencvimage-processingobject-detection

提问by hfingler

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..

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

Some info:

一些信息:

  • The ball doesn't have a fixed color, it will probably be white, but it might change.
  • I HAVE to use machine learning, doesn't have to be a complex and reliable one, suggestion is KNN (which is WAY simpler and easier).
  • After all my searching, i found that calculating the histogram of samples ball-only images and teaching it to the ML could be useful, but my main concern here is that the ball size can and will change (closer and further from the camera) and i have no idea on what to pass to the ML to classify for me, i mean.. i can't (or can I?) just test every pixel of the image for every possible size (from, lets say, 5x5 to WxH) and hope to find a positive result.
  • There might be a non-uniform background, like people, cloth behind the ball and etc..
  • As I said, i have to use a ML algorithm, that means no Haar or Viola algorithms.
  • Also, I thought on using contours to find circles on a Canny'ed image, just have to find a way to transform a contour into a row of data to teach the KNN.

    So... suggestions?

    Thanks in advance. ;)

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

    所以……建议?

    提前致谢。;)

回答by karlphillip

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

好吧,基本上你需要检测circles。你见过cvHoughCircles()吗?你被允许使用它吗?

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

这个页面有关于如何用 OpenCV 检测东西的好信息。您可能对第 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.

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

Input: input img

输入输入图片

Outputs: output opencv img

输出输出opencv img

// 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\n");
    }

    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\n",center.x,center.y, radius);
    }


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

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

    return 0;
}

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

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