从身体提取掩码计算边界框

Posted

技术标签:

【中文标题】从身体提取掩码计算边界框【英文标题】:Calculate the bounding box from a body extraction mask 【发布时间】:2014-02-20 13:05:31 【问题描述】:

我有一个二进制 mat 文件,它只包含黑白像素。基本上是一个身体提取面具,我想计算边界框。如何从该二进制图像中计算最小和最大白色值以计算所计算的形状的边界框?我的代码:

Mat bodyEx(string filename)

cv::Mat matInput=cv::imread(filename);

//Set mask
cv::Mat matMask = cv::Mat::ones(matInput.size(), CV_8U) * cv::GC_BGD;
cv::Rect area;
area.x=int(matInput.cols*0.1);  area.y=int(matInput.rows*0.05);
area.width=int(matInput.cols-2*area.x);
area.height=int(matInput.rows-2*area.y);
rectangle(matMask, area , cv::Scalar(cv::GC_PR_FGD),-1,8,0);
area.x=int(matInput.cols*0.35); area.y=int(matInput.rows*0.25);
area.width=matInput.cols-2*area.x;
area.height=matInput.rows-2*area.y;
rectangle(matMask, area , cv::Scalar(cv::GC_FGD),-1,8,0);

//Segmentation
cv::Mat bgd,fgd;
cv::grabCut(matInput, matMask, area, bgd, fgd, 1, cv::GC_INIT_WITH_MASK);
matMask= matMask&1;
cv::compare(matMask,cv::GC_FGD,matMask,cv::CMP_EQ);
cv::Mat matSegmented=cv::Mat::zeros(matInput.size(),CV_8UC3);
matInput.copyTo(matSegmented,matMask);


int lowestWhite_x;  int lowestWhite_y;
cout << "Rows " << matMask.rows << " and cols: "<< matMask.cols << endl;
for (int row=0;row<matMask.rows;row++) 
     
       for (int col=0;col<matMask.cols;col++) 
        
            if(matMask.at<uchar>(row,col) != 0)lowestWhite_x = row; lowestWhite_y = col;
         
    

cout << "Rows " << lowestWhite_x << " and cols: "<< lowestWhite_y << endl;
//Display
/*cv::imshow("InputImage",matInput);
cv::imshow("mask",matMask);
cv::imshow("Segmented",matSegmented);
cvWaitKey();*/

return matSegmented;

编辑:

Rect faceRect, brect;
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours( matMask, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_TC89_KCOS);
for ( size_t i=0; i<contours.size(); ++i )

    cv::drawContours( matInput, contours, i, Scalar(0,255,0), 1, 8, hierarchy, 0, Point() ); 
    cv::Rect brect = cv::boundingRect(contours[i]);
    cv::rectangle(matInput, brect, Scalar(0,255,0));
    cout << brect.size() << endl;

它计算所有的轮廓。最后我想保持bb。 4 点不是图像的所有轮廓。我该怎么做?

【问题讨论】:

【参考方案1】:

使用findContours 函数查找二值图像上的轮廓,使用boundingRect 函数查找边界矩形。

可以在此处找到用法示例:How to draw a rectangle around the contours?

回复您的编辑: 尝试Rect myRect = boundingRect(contours[i]); 而不是Rect myRect = boundingRect(contours); 是错误的。

【讨论】:

我使用 findContours 究竟计算了什么? 在您的蒙版图像中,此人将为白色,背景为黑色。考虑有两个白色的物体,它们都是分开的。使用该函数,它区分不同的非连接对象并输出所有对象的边界点。因此,您可以在图像中获得一个人的边界点。 boundingRect 绘制一个连接这些边界点的矩形。 vector > 等高线;矢量 层次结构; findContours(matMask, 轮廓, 层次结构, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));矩形 myRect = boundingRect(contours); 矩形 myRect = boundingRect(contours[i]); 好的,我知道了,最后我要找到最大宽度和高度的轮廓。

以上是关于从身体提取掩码计算边界框的主要内容,如果未能解决你的问题,请参考以下文章

Opencv检测边界和ROI掩码

如何使用 mask-RCNN 在 python 中计算(x,y)(质心)和掩码的宽度和高度?

Python:如何从 3D numpy/torch 数组中提取连接的组件(边界框)?

使用掩码从特定坐标处的图像(2d数组)中提取像素值

网络基础---子网掩码

网络基础---子网掩码