请考虑下面的 MWE。我有一个对应于图形输出缓冲区和一些层的矩阵(输出),应按特定顺序将其放入该缓冲区。这些层包含 alpha 信息(最后一个字节)。如果所有图层的所有像素的 alpha 字节都设置为 0xFF,则只能看到最上面的图层。如果所有的 alpha 值都设置为 0,则看不到任何一个。 0 到 0xFF 之间可以有一个 alpha 值,所以对应的像素应该是半透明的。
我尝试使用 addWeighted()
,但这没有帮助(见下文):无论 alpha 字节设置为什么值,所有图像都是可见的。
你知道如何实现吗?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
void test(){
namedWindow("window", WINDOW_AUTOSIZE);
Mat output(Size(300, 300), CV_8UC4, Scalar(0));
Mat m1(Size(300, 300), CV_8UC4, Scalar(0));
Mat m2(Size(300, 300), CV_8UC4, Scalar(0));
Mat m3(Size(300, 300), CV_8UC4, Scalar(0));
circle(m1, Point(130, 130), 75, Scalar(0, 0, 0xFF, 0xFF), -1);
circle(m2, Point(150, 150), 75, Scalar(0, 0xFF, 0, 0xFF), -1);
rectangle(m3, Rect(100, 100, 60, 60), Scalar(0xFF, 0, 0, 0xFF), -1);
rectangle(m3, Rect(115, 115, 30, 30), Scalar(0), -1);
/*
Output should look like
[ m3 ] <-- top
[ m2 ]
[ m1 ] <-- bottom
*/
//What I've tried so far (the final solution should work for more than 3 'layers')
m1.copyTo(output);
addWeighted(output, .5, m2, .5, 0, output);
addWeighted(output, .5, m3, .5, 0, output);
imshow("window", output);
cvWaitKey(0);
destroyAllWindows();
}
最佳答案
我不确定这是否是最好的方法,但这也许可以完成这项工作。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
using namespace cv;
void addAlpha(Mat src, Mat input);
void test(){
namedWindow("window", WINDOW_AUTOSIZE);
Mat output(Size(300, 300), CV_8UC4, Scalar(0));
Mat m1(Size(300, 300), CV_8UC4, Scalar(0));
Mat m2(Size(300, 300), CV_8UC4, Scalar(0));
Mat m3(Size(300, 300), CV_8UC4, Scalar(0));
circle(m1, Point(130, 130), 75, Scalar(0, 0, 0xFF, 0xFF), -1);
circle(m2, Point(150, 150), 75, Scalar(0, 0xFF, 0, 0xFF), -1);
rectangle(m3, Rect(100, 100, 60, 60), Scalar(0xFF, 0, 0, 0xFF), -1);
rectangle(m3, Rect(115, 115, 30, 30), Scalar(0), -1);
m1.copyTo(output);
addAlpha(output,m2);
addAlpha(output,m3);
imshow("window", output);
cvWaitKey(0);
destroyAllWindows();
}
void addAlpha(Mat src, Mat input){
if(src.rows != input.rows || src.cols != input.cols){
perror("Not same size");
}
for(int i = 0; i < src.rows; i++){
for(int j = 0; j < src.cols; j++){
src.at<cv::Vec4b>(i,j)[0] = src.at<cv::Vec4b>(i,j)[0] * (1 - input.at<cv::Vec4b>(i,j)[3]/255.0) + input.at<cv::Vec4b>(i,j)[0] * (input.at<cv::Vec4b>(i,j)[3]/255.0);
src.at<cv::Vec4b>(i,j)[1] = src.at<cv::Vec4b>(i,j)[1] * (1 - input.at<cv::Vec4b>(i,j)[3]/255.0) + input.at<cv::Vec4b>(i,j)[1] * (input.at<cv::Vec4b>(i,j)[3]/255.0);
src.at<cv::Vec4b>(i,j)[2] = src.at<cv::Vec4b>(i,j)[2] * (1 - input.at<cv::Vec4b>(i,j)[3]/255.0) + input.at<cv::Vec4b>(i,j)[2] * (input.at<cv::Vec4b>(i,j)[3]/255.0);
}
}
}
关于c++ - OpenCV:使用 C++ 添加包含 alpha 信息 'on top of each other' 的矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23427712/