Ask Your Question
0

Problem Adding a mask to video frames

asked 2019-09-25 09:50:08 -0600

updated 2019-09-26 03:03:11 -0600

Hello,

I have a problem and i need your help, when i read a video, i want to apply a mask in each frame (make pixels black in a ROI (Rectangle),

i used :

  imv.copyTo(ImvMasked, im2MasqueRectangle);

imv : is the frame of the video.

im2MasqueRectangle : is the mask, for me it's a rectangle, that change dimension for every frame, i don't add code how i get the rectangle because it's very long.

ImvMasked : is the result of applying the mask in the image imv.

My problem is the result is not an image masked, but the mask is deformed, it's like instead of showing black pixels it's shows the preview frame.

Problem

  //read the video
   VideoCapture cap("box.mp4");  
    for (;;)
{
    cap >> im; // get a new frame from camera
    if (!im.data)
    {
        //std::cout << "Image not loaded";
        return -1;
    }

//Creation of the mask
 Mat im2MasqueRectangle(im.rows, im.cols, CV_8UC1, Scalar(255, 255, 255));
 //bounding_rect is the ROI i want to mask i don't add how i get it because the code is very long.
 rectangle(im2MasqueRectangle, bounding_rect, cv::Scalar(0, 0, 0),-1);
 //Here i add the mask to the image 
 imv.copyTo(fondEnCours, im2MasqueRectangle);
 imshow("fond en cours", fondEnCours);
}

I can't figure out why i am having this problem, i need your help and thank you.

Edit 1 : I tried this and now it's showing the black rectangle but the dimensions of the rectangle are weird.

        cv::Mat im2MasqueRectangle = Mat(imv.size(), imv.type(), Scalar(255, 255, 255));
        rectangle(im2MasqueRectangle, bounding_rect, cv::Scalar(0, 0, 0), -1);
        imshow("msk", im2MasqueRectangle);
        for (int row = 0; row < imv.rows; row++)
        {
            for (int col = 0; col < imv.cols; col++)
            {
                uchar pixel = im2MasqueRectangle.at<uchar>(row, col);
                if (pixel == 0)
                {
                    imv.at<uchar>(row, col) = pixel;
                }
            }
        }
        imshow("fond en cours", imv);

image description

edit retag flag offensive close merge delete

Comments

I find a solution for my problem :

      //define your mask image
        cv::Mat mask22 = cv::Mat::zeros(imv.size(), imv.type());        
        mask22 = cv::Scalar(255, 255, 255);
        //Define your destination image
        cv::Mat dstImage = cv::Mat::ones(imv.size(), imv.type());

        rectangle(mask22, bounding_rect, cv::Scalar(0, 0, 0), -1);
        imshow("msk", mask22);
        //Now you can copy your source image to destination image with masking
        imv.copyTo(dstImage, mask22);
        imshow("fond en cours", dstImage);
Kitnos gravatar imageKitnos ( 2019-09-26 03:32:02 -0600 )edit
1

imv.at<uchar>(row, col) -- what's imv.type() ? looks like you wrongly only access 1/3 of the (bgr ?) pixels this way.

berak gravatar imageberak ( 2019-09-26 04:37:11 -0600 )edit
2

Thank you berak, yes the for loop was a bad idea, i edited the Mask (code in my first comment) and now it's working.

Kitnos gravatar imageKitnos ( 2019-09-26 04:54:16 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2019-09-27 10:17:38 -0600

Solution to my problem :

//define your mask image
    cv::Mat mask22 = cv::Mat::zeros(imv.size(), imv.type());        
    mask22 = cv::Scalar(255, 255, 255);
    //Define your destination image
    cv::Mat dstImage = cv::Mat::ones(imv.size(), imv.type());

    rectangle(mask22, bounding_rect, cv::Scalar(0, 0, 0), -1);
    imshow("msk", mask22);
    //Now you can copy your source image to destination image with masking
    imv.copyTo(dstImage, mask22);
    imshow("fond en cours", dstImage);
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2019-09-25 09:50:08 -0600

Seen: 1,668 times

Last updated: Sep 27 '19