我需要帮助来更好地理解有关Alpha通道混合的此代码段。有2种Mat数据类型,并且它们都被拆分以获得alpha通道([3]
是RGBA的alpha通道)。然后还有1个名为multiplier
的Mat变量,我不太了解其目的以及对该变量的操作方式。
split(mat1, mat1_split);
split(mat2, mat2_split);
Mat multiplier = (mat1_split[3] & mat2_split[3])/255 + 1; //Need explanation here
如果我在Visual Studio的&
和mat1_split[3]
之间扩展mat2_split[3]
的定义,它将显示此定义CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
。
这可能看起来像是一个初学者的问题,但是我无法理解上面multiplier
操作的含义。
答案 0 :(得分:3)
让我们看看以下示例:
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);
我们有mat1
这样的人:
而且,我们有mat2
像这样:
mat1
和mat2
的部分透明胶片为64
和128
,请参见上面的代码。
二进制AND运算符inter
的中间结果(&
)如下:
由于这是二进制AND,因此0
和64
(第一行,第二列以及第二行,第一列)的组合将得到128
-例如-您将获得64
和64
的组合的64
(第一行,第一列)。另一方面,对于64
和64
(第一行,第三列以及第三行,第一列)的组合,您还将获得255
。
那么,那是“句法”部分,但是背后的“语义”部分呢?我想,您需要询问此代码段的作者。如果它们不匹配(64
和128
),我不打算取消alpha通道,但如果不匹配则保留它们(64
和{{1} }。 (特别是,如果您牢记,将64
和64
结合使用也会得到127
...)
对于所有像素,64
为multiplier
,组合值小于或等于1
,否则为127
。同样,对于“语义”部分,请问作者。
希望有帮助-至少有一点。
答案 1 :(得分:1)
您要对位/像素强度进行明智的操作
&->并取所有输入中的最大值输入0 0> 0 0 1> 1 1 0> 1 1 1> 1
还有很多其他的,例如
| ->或操作
对于其他操作(例如XOR,NOT,NAND,NOR和XNOR),不确定opencv是否允许,您可以自由尝试