c++ - OpenCV:使用 C++ 添加包含 alpha 信息 'on top of each other' 的矩阵

标签 c++ opencv matrix colors

请考虑下面的 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/

相关文章:

c++ - new分配了多少字节?

c++ - Windows::工具栏::NM_CUSTOMDRAW。更改工具栏背景颜色

c++ - set<Vec3b> 的错误行为

python - 通过平均多个单元格来简化矩阵

C-制作梯形矩阵?

C++,这会导致内存泄漏吗?

c++ - 获取对 std::thread::_M_start_thread 的 undefined reference

c++ - 段错误,找不到我做错的地方

opencv - 如何提高特征脸算法的准确率

c - 为什么矩阵不能用 5,3 而用 3,5?