简体   繁体   English

OpenCV C ++检测并裁剪图像上的白色区域

[英]Opencv c++ detect and crop white region on image

I've searched the web nd I already found a few methods to do what I want, but these methods fail in efficiency compared to what I need. 我已经在网上搜索过,并且已经找到了一些可以做我想做的方法,但是与我所需要的相比,这些方法效率低下。

I have a kinect(using Microsoft SDK) which iscurrently acquiring a person removing the background, saving the result in a 3 channel Mat with the person removed from the background. 我有一个kinect(使用Microsoft SDK),当前正在获取一个删除背景的人,并将结果保存在3通道Mat中,该人从背景中删除。 Now I need crop the image to fit only that person, ignoring the black region. 现在,我需要裁剪图像以使其仅适合该人,而忽略黑色区域。

Here's the tricky part: I don't have many time to waste on every operation (I also need to do several other operations and this is supossed to work on real time. What I have currently implemented is a contours finder which give only this region, but it's really slow on real time. Since I only have a white region do detect and that region is really big (50% of the image area) I think there is some faster way to do this, as I only want the minimum and maximum values of x and y of this white area to crop it. 这是棘手的部分:我没有太多时间可以浪费在每个操作上(我还需要执行其他几个操作,并且可以实时工作。我目前实现的是轮廓查找器,它仅提供该区域,但是它的实时性确实很慢。由于我只检测白色区域,而且该区域确实很大(图像区域的50%),因此我认为有一种更快的处理方法,因为我只需要最小区域和裁剪此白色区域的x和y的最大值。

This is my currently my cropping function: 这是我目前的裁剪功能:

cv::Mat thresh_canny;
cv::vector<cv::vector<cv::Point> > contours;
cv::vector<cv::Vec4i> hierarchy;
cv::threshold(src, thresh_canny, 0, 255, 0);
cv::Canny(thresh_canny, thresh_canny, 20, 80, 3);
cv::findContours(thresh_canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));

if (contours.size() != 1)
    return false;

cv::Rect r = cv::boundingRect(contours.at(0));
src(r).copyTo(dst);
return true;

Many thanks!! 非常感谢!!

EDIT: Input image 编辑:输入图像

在此处输入图片说明

If your image has no non-black outlier (like noise) you can ignore the canny and the findContours and instead just create the bounding rect from all non-black pixel locations: 如果您的图像没有非黑色离群值(例如噪点),则可以忽略canny和findContours,而仅从所有非黑色像素位置创建边界矩形:

int main()
{
cv::Mat in = cv::imread("CropWhite.jpg");

// vector with all non-black point positions
std::vector<cv::Point> nonBlackList;
nonBlackList.reserve(in.rows*in.cols);

// add all non-black points to the vector
//TODO: there are more efficient ways to iterate through the image
for(int j=0; j<in.rows; ++j)
    for(int i=0; i<in.cols; ++i)
    {
        // if not black: add to the list
        if(in.at<cv::Vec3b>(j,i) != cv::Vec3b(0,0,0))
        {
            nonBlackList.push_back(cv::Point(i,j));
        }
    }

// create bounding rect around those points
cv::Rect bb = cv::boundingRect(nonBlackList);

// display result and save it
cv::imshow("found rect", in(bb));
cv::imwrite("CropWhiteResult.png", in(bb));


cv::waitKey(-1);
return 0;
}

don't know whether there are more efficient ways to create the vector, given in openCV, but this should still be much faster than canny and findContours. 不知道在openCV中是否有更有效的方法来创建向量,但这应该比canny和findContours快得多。

with this input: 使用此输入:

在此处输入图片说明

I get this result: 我得到这个结果:

在此处输入图片说明

there are some areas around the contour, because you provided a jpg image, where the borders of the contour aren't true black because of compression, I guess. 我猜想,轮廓周围有一些区域,因为您提供了jpg图片,但由于压缩,轮廓的边界并不是真正的黑色。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM