在opencv面罩

时间:2014-03-15 17:53:19

标签: c++ opencv computer-vision mask

输入:面部图片

问题:在应用Canny查找轮廓但不返回面罩之前的阈值图像

所需输出如果输入了不同的面部,则应生成正确的面罩(面部区域为白色且背景为白色)

尝试用苹果图片。工作正常

            #include <opencv2/highgui/highgui.hpp>
            #include <opencv2/core/core.hpp>
            #include <opencv2/imgproc/imgproc.hpp>

            using namespace cv;
            using namespace std;

            int main(){
              Mat right=imread("front.jpg");
              Mat img1;
              cvtColor(right, img1, CV_RGB2GRAY);
              threshold(img1,img1,160,255,cv::THRESH_BINARY);
              Canny(img1, img1, 128, 350);
              vector< vector<Point> > contours;
              findContours(img1, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
              Mat mask = Mat::zeros(img1.rows, img1.cols, CV_8UC1);
              drawContours(mask, contours, -1, Scalar(255), CV_FILLED);
              normalize(mask.clone(), mask, 0.0, 255.0, CV_MINMAX, CV_8UC1);

              imshow("original", right);
              imshow("thresh",img1);
              imshow("mask", mask);

              waitKey(0);
              return 0;
    }

这是我用过的图片

enter image description here

请忽略下面的前3条评论

1 个答案:

答案 0 :(得分:3)

使用下面的代码,掩码创建非常适合您在上面的代码中提供的示例图像。

这里假设您的背景是任何颜色而没有其他对象。

以下代码将执行

  • 查找边缘

  • 通过morphology操作加强优势。

  • 在边缘找到最大轮廓(始终是前景的边界)并通过填充绘制它。

有时你的轮廓可能不会在底部闭合(底部没有边缘),所以填充轮廓不起作用,所以为了使它关闭,代码首先找到最大轮廓(前景)的边界矩形,然后画出rect的底部到边缘图像,然后再次找到最大轮廓将为您提供正确的蒙版图像。

Rect R;

Mat findLargestContour(Mat thr){

vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
int largest_contour_index=0;
int largest_area=0;
Mat dst(thr.rows,thr.cols,CV_8UC1,Scalar::all(0)); //create destination image

findContours( thr, contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
      {
       double a=contourArea( contours[i],false);  //  Find the area of contour
       if(a>largest_area){
       largest_area=a;
       largest_contour_index=i;                //Store the index of largest contour
       }
      }
drawContours( dst,contours, largest_contour_index, Scalar(255,255,255),CV_FILLED, 8, hierarchy );
R= boundingRect( contours[largest_contour_index]);
return dst;

}

int main( )
{

              Mat right=imread("1.jpg");
           // blur(right,right,Size(3,3));
              Mat gray;
              cvtColor(right, gray, CV_RGB2GRAY);

              int borderW=10;
              //Mat ROI=gray(Rect(borderW,borderW,img1.cols-2*borderW,img1.rows-2*borderW));
              Canny(gray, gray, 30, 255);

              Size kernalSize (5,5);
              Mat element = getStructuringElement (MORPH_RECT, kernalSize, Point(1,1)  );
              morphologyEx(gray, gray, MORPH_CLOSE, element );
              imshow("canny", gray);

              Mat largestCon=findLargestContour(gray.clone());
              line(largestCon, Point(R.x,R.y+R.height), Point(R.x+R.width,R.y+R.height), Scalar(255),2,8,0);

              Mat mask=findLargestContour(largestCon.clone());

              Mat A;
              right.copyTo(A,mask);
              imshow("original", right);
              imshow("dst", A);
              imshow("mask", mask);

              waitKey(0);


  return 0;
  }

查看一些样本掩码

enter image description here enter image description here

enter image description here enter image description here