使用OpenCV的多种颜色物体检测 [英] Multiple color object detection using OpenCV

查看:416
本文介绍了使用OpenCV的多种颜色物体检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图同时检测红墙下两个白色的墙红色上衣和白色的上岗的画面的白色方块的图像中的位置:

I am attempting to detect the position in the image of both the red walls and the white squares in the picture below of two white wall with red tops and white "posts":

我的方法是做阈值找到红墙,我现在可以轻松地从这个输出检测:

My approach was to do thresholding to find the red walls which I can now easily detect from this output:

现在我的问题是检测的白色方块的位置,但是这是比较困难的考虑白色的墙壁。如果基于白光I阈我仍然保留不需要的白墙在白色方形立柱之间。

Now my problem is detecting the locations of the white squares, but this is more difficult considering the white walls. If I threshold based on white I still retain the undesired white walls in between the white square posts.

任何帮助将大大AP preciated。

Any help would be greatly appreciated.

推荐答案

一种方法中包含的阈值的有输入图像的简历:: INRANGE ()

cv::Mat image = cv::imread(argv[1]);
if (image.empty())
{
    std::cout << "!!! Failed imread()" << std::endl;
    return -1;
}

cv::Mat red_image;
cv::inRange(image, cv::Scalar(40, 0, 180), cv::Scalar(135, 110, 255), red_image);
//cv::imwrite("out1.png", red_image);

输出

我们可以使用 CV :: findContours 检索阈值的图像的轮廓,能够为他们创造,<一个包围盒href=\"http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html\">which在这里描述的技术的:

We can use cv::findContours to retrieve the contours of the thresholded image to be able to create bounding boxes for them, which is a technique described here:

std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours( red_image, 
                  contours, 
                  hierarchy, 
                  CV_RETR_TREE, 
                  CV_CHAIN_APPROX_SIMPLE, 
                  cv::Point(0, 0) );

std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
std::vector<cv::Rect> boundRect( contours.size() );
for( int i = 0; i < contours.size(); i++ )
    { 
        cv::approxPolyDP( cv::Mat(contours[i]), contours_poly[i], 3, true );
        boundRect[i] = cv::boundingRect( cv::Mat(contours_poly[i]) );
    }   


// Debug purposes: draw bonding rects
//cv::Mat tmp = cv::Mat::zeros( red_image.size(), CV_8UC3 );
//for( int i = 0; i< contours.size(); i++ )
//  rectangle( tmp, boundRect[i].tl(), boundRect[i].br(), cv::Scalar(0, 255, 0), 2, 8, 0 );
//cv::imwrite("out2.png", tmp);  

输出

在图像中显示的所有矩形上面存储为 CV ::矩形 boundRect 矢量对象内。每个矩形是由2对 CV ::点<中/ code>对象,所以我们反复对这个载体建立由 CV ::点对象只:

All the rectangles displayed in the image above are stored as cv::Rect object inside the boundRect vector. Each rectangle is made of 2 opposite cv::Point objects, so we iterate on this vector to create a new vector made up of cv::Point objects only:

// Two opposite cv::Point can be used to draw a rectangle.
// Iterate on the cv::Rect vector and retrieve all cv::Point 
// and store them in a cv::Point vector.
std::vector<cv::Point> rect_points; 
for( int i = 0; i < contours.size(); i++ )
{
    rect_points.push_back(boundRect[i].tl());
    rect_points.push_back(boundRect[i].br());
}

//cv::Mat drawing = cv::Mat::zeros( red_image.size(), CV_8UC3 );
cv::Mat drawing = image.clone();

找到白格子的逻辑是:假定对方的25×25范围内2个像素定义一个白色方形:

The logic to find the white squares is: assume that 2 pixels within 25x25 distance of each other define a white square:

// Draw a rectangle when 2 points are less than 25x25 pixels of 
// distance from each other
for( int i = 0; i < rect_points.size(); i++ )
{
    for( int j = 0; j < rect_points.size(); j++ )
    {
        if (i == j) 
            continue;

        int x_distance = (rect_points[i].x - rect_points[j].x);
        if (x_distance < 0) 
            x_distance *= -1;

        int y_distance = (rect_points[i].y - rect_points[j].y);
        if (y_distance < 0) 
            y_distance *= -1;

        if ( (x_distance < 25) && (y_distance < 25) )
        {
            std::cout << "Drawing rectangle " << i << " from " 
                      << rect_points[i] << " to " << rect_points[j] 
                      << " distance: " << x_distance << "x" << y_distance << std::endl;

            cv::rectangle( drawing, 
                           rect_points[i], 
                           rect_points[j], 
                           cv::Scalar(255, 50, 0), 
                           2 );
            break;
        }
    }

}

    //cv::imwrite("out3.png", drawing);
cv::imshow("white rectangles", drawing);    
cv::waitKey();

输出

这算法是pretty原在底部错过了2白色方块,因为下面还有他们没有红色的墙,只有在他们之上。

This algorithm is pretty raw and misses the 2 white squares at the bottom because there are no red walls below them, only above them.

所以我把它留给你来改善这种方法:)

So I leave it up to you to improve this approach :)

祝你好运。

这篇关于使用OpenCV的多种颜色物体检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆