使用 OpenCV 和机器学习进行简单的物体检测

发布于 2024-11-16 08:18:07 字数 559 浏览 3 评论 0原文

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

一些信息:

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

    那么......建议?

    提前致谢。 ;)

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨轻弹 2024-11-23 08:18:07

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

此页面提供了有关如何使用 OpenCV 检测内容的详细信息< /a>.您可能对第 2.5 节更感兴趣。

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

输入
input img

输出
output 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;
}

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

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

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.

Input:
input img

Outputs:
output 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文