konstantin_doncov
konstantin_doncov

Reputation: 2879

Make all transparent outside the mask

I have jpg image and polygon which I want to use as mask in this way: image inside this polygon should be displayed, and all outside this polygon should be 100% transparent. Now I achieved only first goal - I can display image inside polygon, but all outside of it is black:

cv::Mat image;

//load image

image.convertTo(image, CV_8UC3, 255.0);

std::vector<cv::Point> contour;

//load polygon

const cv::Point* elementPoints[1] = { &contour[0] };
int numberOfPoints = (int)contour.size();

cv::Mat mask = cv::Mat::zeros(image.size(), image.type());

cv::fillPoly(mask, elementPoints, &numberOfPoints, 1, cv::Scalar( 255, 255, 255), 8);

cv::Mat dstImage = cv::Mat::zeros(image.size(), image.type());

cv::bitwise_and(image, mask, dstImage);

imwrite("test.jpg", dstImage);

I know that I need to use alpha channel, but it's unclear what I need to do next and how to implement this.

How can I get transparent background outside the mask?

Upvotes: 0

Views: 450

Answers (1)

Aconcagua
Aconcagua

Reputation: 25526

First, create your image with four channels as described in this answer. Use negative source for fourth channel to get it zeroed out already. You now have a totally transparent image.

Create your mask just as you did before, just using different RGBA values (be aware that Scalar has a fourth constructor parameter for alpha values):

cv::fillPoly(mask, elementPoints, &numberOfPoints, 1, cv::Scalar(0, 0, 0, 255), 8);

Finally, apply the mask to set the region in question to totally opaque:

cv::bitwise_or(image, mask, dstImage);

You might want to retain the RGB values of the original image (so you can operate on later) or you might clear them out (which will result in higher compression and thus smaller file size). If the latter, use an inverted mask with RGBA set to 0, 0, 0, 0 and apply that with bitwise_and...

Upvotes: 1

Related Questions