Examples of OpenCV Mask

The second parameter of Mat's CopyTo method is a mask. The length and width of the mask must be consistent with the source matrix. If the mask value of a pixel is not zero, it will be copied to the target matrix. When applied to an image, only part of the pixels can be copied by the mask to generate various special effects.

The original picture used in this article

1. Display only images near the mouse

Just like looking at the outside effect from a small hole, just draw a circle on the mask and fill the circle with white (the line width of circle function is set to -1 to fill the circle), then call CopyTo.

#include<opencv2/opencv.hpp>
cv::Mat backgroundImg;
cv::Mat resultImg;
cv::Mat foregroundImg;
cv::Mat maskImg;
const char* winName = "Image";
void OnMouseEvent(int event, int x, int y, int flags, void* userdata)
{
	if (event == cv::EVENT_MOUSEMOVE)
	{
		foregroundImg.copyTo(resultImg);//Copy the foreground color to resultImg
		memset(maskImg.data, 0, maskImg.cols * maskImg.rows * maskImg.elemSize());//Reset mask to all 0
		cv::circle(maskImg, cv::Point(x, y), 100, cv::Scalar::all(255), -1);//Draw a circle with a radius of 100 on the mask
		backgroundImg.copyTo(resultImg, maskImg);//Copy background image to resultimg through mask
		cv::imshow(winName, resultImg);
	}
}
int main(int argc, char** arv)
{
	backgroundImg = cv::imread("../Resources/Images/test3.jpg");//Background picture
	foregroundImg = cv::Mat::zeros(backgroundImg.size(), backgroundImg.type());//The foreground picture is all black.
	foregroundImg.copyTo(resultImg);
	maskImg = cv::Mat::zeros(backgroundImg.size(), CV_8U);//Mask plate all 0

	cv::namedWindow(winName);
	cv::imshow(winName, resultImg);
	cv::setMouseCallback(winName, OnMouseEvent);
	cv::waitKey(0);
	return 0;
}

Four matrices are used here, backgroundImg is the picture to be displayed, foregroundImg is the foreground color, here is set to all black, maskImg is the mask, resultImg is the final image to see, every time the mouse moves, the mask should be clear 0, otherwise the already displayed image will not be covered by black, the final effect is as follows.

2. The effect of cleaning glass

When the mouse moves, the mask will be cleared 0. If not cleared 0, it will always be displayed. Here is not clear 0 to achieve the effect of erasing the fog on the glass. The foreground color will be changed into the blurred effect of the background picture. The mouse movement event above will be triggered when the mouse is pressed and moved.

#include<opencv2/opencv.hpp>
cv::Mat backgroundImg;
cv::Mat resultImg;
cv::Mat foregroundImg;
cv::Mat maskImg;
const char* winName = "Image";
void OnMouseEvent(int event, int x, int y, int flags, void* userdata)
{
	static bool bMouseDown = false;
	if (event == cv::EVENT_LBUTTONDOWN)
	{
		bMouseDown = true;
	}
	else if (event == cv::EVENT_LBUTTONUP)
	{
		bMouseDown = false;
	}
	else if (event == cv::EVENT_MOUSEMOVE)
	{
		if (bMouseDown)
		{
			foregroundImg.copyTo(resultImg);
			cv::circle(maskImg, cv::Point(x, y), 20, cv::Scalar::all(255), -1);
			backgroundImg.copyTo(resultImg, maskImg);
			cv::imshow(winName, resultImg);
		}
	}
}
int main(int argc, char** arv)
{
	backgroundImg = cv::imread("../Resources/Images/test3.jpg");
	cv::blur(backgroundImg, foregroundImg, cv::Size(20, 20));//Blur the backgroundImg and assign it to foregroundImg
	foregroundImg.copyTo(resultImg);
	maskImg = cv::Mat::zeros(backgroundImg.size(), CV_8U);

	cv::namedWindow(winName);
	cv::imshow(winName, resultImg);
	cv::setMouseCallback(winName, OnMouseEvent);
	cv::waitKey(0);
	return 0;
}

When the mouse is pressed and moved, the scratched area will show a clear image, just like a scratch, the effect is as follows

The circle above can be changed into any shape, and OpenCV's drawing function can draw contours using drawContours.

 

Tags: Programming OpenCV

Posted on Mon, 12 Aug 2019 05:25:34 -0700 by SuperCam