【问题标题】:OpenCV: "draw" image on another imageOpenCV:在另一个图像上“绘制”图像
【发布时间】:2021-12-19 11:02:20
【问题描述】:

我有 2 张透明图片。图像具有相同的格式和大小。 如何使用 C++ OpenCV 将像素从第二个图像复制到第一个图像? 这个想法是在第一张图像上绘制第二张图像。

谢谢

【问题讨论】:

标签: c++ opencv


【解决方案1】:

来自上述评论链接的代码(针对我的情况进行了修改) L. Scott Johnson 再次感谢您!

void alphaBlend(Mat& foreground, Mat& background, Mat& alpha, Mat& outImage)
{
    // Find number of pixels.
    int numberOfPixels = foreground.rows * foreground.cols * foreground.channels();

    // Get floating point pointers to the data matrices

    float* fptr = reinterpret_cast<float*>(foreground.data);
    float* bptr = reinterpret_cast<float*>(background.data);
    float* aptr = reinterpret_cast<float*>(alpha.data);
    float* outImagePtr = reinterpret_cast<float*>(outImage.data);


    // Loop over all pixesl ONCE

    for (
        int i = 0;
        i < numberOfPixels;
        i++, outImagePtr++, fptr++/*, aptr++*/,  bptr++
        )
    {
        if (i!= 0 && (i % 3) == 0)
            aptr++;

        *outImagePtr = (*fptr) * (*aptr) + (*bptr) * (1 - *aptr);
    }
}


void Mix()
{
    Mat layer = imread("images\\leyer.png", IMREAD_UNCHANGED);
    Mat image = imread("images\\bg.jpg");
    
    std::vector<cv::Mat> bgra_planes;
    cv::split(layer, bgra_planes);
    
    Mat alpha = bgra_planes[3];

    bgra_planes.pop_back();
    cv::merge(bgra_planes, layer);

    alpha.convertTo(alpha, CV_32FC3, 1.0 / 255);
    layer.convertTo(layer, CV_32FC3);
    image.convertTo(image, CV_32FC3);


    Mat result(layer.size(), CV_32FC3);

    alphaBlend(layer, image, alpha, result);

    result.convertTo(result, CV_8UC3);

    // previous tries
    //cv::copyTo(layer, image, );
    //cv::addWeighted(image, 1, layer, 1, 0.5, result);

    String windowName = "alpha blending"; 
    namedWindow(windowName, WINDOW_NORMAL); 
    imshow(windowName, result); 
    waitKey(0); 
    destroyWindow(windowName); 
}

【讨论】:

  • 那是糟糕的代码。所有的指针算术都没有道理。 cv::Mat::at&lt;&gt;() 存在是有原因的。
【解决方案2】:

您可以尝试以下方法:

加载您的第一张图片

cv::Mat img = cv::imread("img.jpeg");

找到你的小图片 - 我只是在调整同一张图片的大小

cv::Mat img_resize;
cv::resize(img, img_resize, cv::Size(), 0.3, 0.3);

选择 xy 原点位置

const cv::Point origin(100, 100);

创建一个感兴趣的区域

cv::Rect roi(origin, img_resize.size());

复制矩阵数据

img_resize.copyTo(img(roi));

【讨论】:

  • 此代码没有显示使用 Alpha 通道或进行任何混合的提示。
猜你喜欢
  • 2012-06-15
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多