iv67
iv67

Reputation: 4151

What is the meaning of this OpenCV Matrix Expression?

I need help to understand this code snippet about alpha channel blending better. There are 2 Mat data type and both of them are split to get the alpha channel ([3] is the alpha channel of RGBA). Then there is 1 more Mat variable called multiplier which I don't really understand the purpose and how the operation on this variable works.

split(mat1, mat1_split);
split(mat2, mat2_split);
Mat multiplier = (mat1_split[3] & mat2_split[3])/255 + 1;  //Need explanation here

If I extend the definition of & between mat1_split[3] and mat2_split[3] on Visual Studio, it will show this definition CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b); .

This probably looks like a beginner question but I couldn't understand the meaning of multiplier operation above.

Upvotes: 2

Views: 413

Answers (2)

Dr Yuan Shenghai
Dr Yuan Shenghai

Reputation: 1915

You are asking bit/pixel intensity wise operation

& -> And operation it take the highest value of all inputs input 0 0 > 0 0 1>1 1 0 >1 1 1 > 1

there are many others such as

| -> or operation

for others operant such as XOR, NOT, NAND, NOR and XNOR, im not sure opencv allows or not, you are free to try

Upvotes: 0

HansHirse
HansHirse

Reputation: 18895

Let's have a look at the following example:

cv::Mat mat1 = cv::Mat(150, 150, CV_8UC4, cv::Scalar(255, 0, 0, 255));
cv::rectangle(mat1, cv::Point(0, 0), cv::Point(49, 150), cv::Scalar(255, 0, 0, 64), cv::FILLED);
cv::rectangle(mat1, cv::Point(50, 0), cv::Point(99, 150), cv::Scalar(255, 0, 0, 128), cv::FILLED);

cv::Mat mat2 = cv::Mat(150, 150, CV_8UC4, cv::Scalar(0, 0, 255, 255));
cv::rectangle(mat2, cv::Point(0, 0), cv::Point(150, 49), cv::Scalar(0, 0, 255, 64), cv::FILLED);
cv::rectangle(mat2, cv::Point(0, 50), cv::Point(150, 99), cv::Scalar(0, 0, 255, 128), cv::FILLED);

std::vector<cv::Mat> mat1_split;
std::vector<cv::Mat> mat2_split;

cv::split(mat1, mat1_split);
cv::split(mat2, mat2_split);
cv::Mat inter = mat1_split[3] & mat2_split[3];
cv::Mat multiplier = (mat1_split[3] & mat2_split[3]) / 255 + 1;

cv::imwrite("images/mat1.png", mat1);
cv::imwrite("images/mat2.png", mat2);
cv::imwrite("images/inter.png", inter);
cv::imwrite("images/multiplier.png", multiplier);

We have mat1 like this:

mat1

And, we have mat2 like this:

mat2

Partly transparencies for mat1 and mat2 are 64 and 128, see above code.

The intermediate result (inter) of the binary AND operator & looks like this:

inter

Since this is binary AND, you'll get 0 for the combination of 64 and 128 (first row, second column as well as second row, first column), but - for example - you'll get 64 for the combination of 64 and 64 (first row, first column). On the other hand, you'll also get 64 for the combination of 64 and 255 (first row, third column as well as third row, first column).

So, that's the "syntactic" part, but the "semantic" behind that? I guess, you'll need to ask the author of this code snippet. I don't get the point of cancelling out alpha channels, if they don't match (64 and 128), but keeping them if they do (64 and 64). (Especially, if you keep in mind, that combining 64 and 127 would also give 64...)

The multiplier is 1 for all pixels, where the combined value is less or equal 127, and 2 otherwise. Again, for the "semantic" part, ask the author.

Hope that helps - at least a bit.

Upvotes: 4

Related Questions