Better ways to create a rectangular mask by openCV

2019-03-11 02:00发布

Creating a mask in openCV

      /** result I want
          0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0
          0 0 1 1 1 1 0 0
          0 0 1 1 1 1 0 0
          0 0 1 1 1 1 0 0
          0 0 1 1 1 1 0 0
          0 0 0 0 0 0 0 0
          0 0 0 0 0 0 0 0
      */    
cv::Mat mask = cv::Mat::zeros(8, 8, CV_8U);
std::cout<<"before : \n"<<mask<<std::endl;
for(int i = 2; i != 6; ++i)
{
     auto ptr = mask.ptr<uchar>(i) + 2;
     for(int j = 0; j != 4; ++j)
     {
         *ptr++ = 1;
     }
}
std::cout<<"after : \n"<<mask<<std::endl;   

Do openCV provide us any build in function to create a mask like this? It is trivial to create a function fot this task, but the function of openCV always faster than naive handcrafted codes

标签: c++ opencv
2条回答
太酷不给撩
2楼-- · 2019-03-11 02:29

sure, there's an easier way, use the roi operator:

cv::Mat mask = cv::Mat::zeros(8, 8, CV_8U); // all 0
mask(Rect(2,2,4,4)) = 1;

done!

查看更多
Summer. ? 凉城
3楼-- · 2019-03-11 02:49

If some one is looking for creating a non rectangular mask and then to apply it on the image then have a look here :

Mat& obtainIregularROI(Mat& origImag, Point2f topLeft, Point2f topRight, Point2f botLeft, Point2f botRight){

        static Mat black(origImag.rows, origImag.cols, origImag.type(), cv::Scalar::all(0));
        Mat mask(origImag.rows, origImag.cols, CV_8UC1, cv::Scalar(0));
        vector< vector<Point> >  co_ordinates;
        co_ordinates.push_back(vector<Point>());
        co_ordinates[0].push_back(topLeft);
        co_ordinates[0].push_back(botLeft);
        co_ordinates[0].push_back(botRight);
        co_ordinates[0].push_back(topRight);
        drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

        origImag.copyTo(black,mask);
        return black;
    }

"black" is the image where we will finally obtain the result by cropping out the irregular ROI from the original image.

 static Mat black(origImag.rows, origImag.cols, origImag.type(), cv::Scalar::all(0));

The "mask" is a Mat, initialized as the same size of original image and filled with 0. Mat mask(origImag.rows, origImag.cols, CV_8UC1, cv::Scalar(0));

Putting the coordinates in ANTICLOCKWISE direction

    vector< vector<Point> >  co_ordinates;
    co_ordinates.push_back(vector<Point>());
    co_ordinates[0].push_back(topLeft);
    co_ordinates[0].push_back(botLeft);
    co_ordinates[0].push_back(botRight);
    co_ordinates[0].push_back(topRight);

Now generating the mask actually

drawContours( mask,co_ordinates,0, Scalar(255),CV_FILLED, 8 );

At the end copy the masked portion/ROI from original image (origImag) and paste on the portion of ROI from the original image (using mask) into image named as "black"

origImag.copyTo(black,mask);
查看更多
登录 后发表回答