OpenCV获取仅红色矩形区域

时间:2015-06-11 12:22:17

标签: c++ opencv image-processing

我通过以下算法完成了仅红色过滤的以下输出:

cv::Mat findColor(const cv::Mat & inputBGRimage, int rng=20)
{
    // Make sure that your input image uses the channel order B, G, R (check not implemented).
    cv::Mat mt1, mt2;
    cv::Mat input = inputBGRimage.clone();
    cv::Mat imageHSV; //(input.rows, input.cols, CV_8UC3);
    cv::Mat imgThreshold, imgThreshold0, imgThreshold1; //(input.rows, input.cols, CV_8UC1);

    assert( ! input.empty() );

    // blur image
    cv::blur( input, input, Size(11, 11) );

    // convert input-image to HSV-image
    cv::cvtColor( input, imageHSV, cv::COLOR_BGR2HSV );

    // In the HSV-color space the color 'red' is located around the H-value 0 and also around the
    // H-value 180. That is why you need to threshold your image twice and the combine the results.
    cv::inRange( imageHSV, cv::Scalar( H_MIN, S_MIN, V_MIN ), cv::Scalar( H_MAX, S_MAX, V_MAX ), imgThreshold0 );

    if ( rng > 0 )
    {
        // cv::inRange(imageHSV, cv::Scalar(180-rng, 53, 185, 0), cv::Scalar(180, 255, 255, 0), imgThreshold1);
        // cv::bitwise_or( imgThreshold0, imgThreshold1, imgThreshold );
    }
    else
    {
        imgThreshold = imgThreshold0;
    }

    // cv::dilate( imgThreshold0, mt1, Mat() );

    // cv::erode( mt1, mt2, Mat() );

    return imgThreshold0;

}

这是输出:

enter image description here

我想检测矩形的四个坐标。正如您所看到的,输出并不完美,之前我将cv::findContourscv::approxPolyDP结合使用,但它已不再适用了。

是否有任何滤镜可以应用于输入图像(模糊,扩张,侵蚀除外)以使图像更适合处理?

有什么建议吗?

更新

当我像这样使用findContours时:

findContours( src, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );

double largest_area = 0;

for( int i = 0; i < contours.size(); i++) {  // get the largest contour
    area = fabs( contourArea( contours[i] ) );
    if( area >= largest_area ) {
        largest_area = area;
        largestContours.clear();
        largestContours.push_back( contours[i] );
    }
}

if( largest_area > 5000 ) {
    cv::approxPolyDP( cv::Mat(largestContours[0]), approx, 100, true );
    cout << approx.size() << endl; /* ALWAYS RETURN 2 ?!? */
}

approxPolyDP未按预期运行。

1 个答案:

答案 0 :(得分:3)

我认为你的结果非常好,也许你可以使用Image Moments选择具有最大面积的轮廓,然后找到更大轮廓的最小旋转矩形。

vector<cv::RotatedRect> cv::minRect( contours.size() );

for( size_t = 0; i < contours.size(); i++ )
{
    minRect[i] = minAreaRect( cv::Mat(contours[i]) );
}

Rotated Rect类已经有一个Point2f向量来存储点。

RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
Point2f vertices[4];
rRect.points(vertices);

for(int i = 0; i < 4; i++){
    std::cout << vertices[i] << " ";
}