【问题标题】:Layer image with opacity over the top of another image. - OpenCV在另一个图像的顶部叠加不透明度的图像。 - OpenCV
【发布时间】:2016-05-07 10:39:04
【问题描述】:

编辑

任何有类似问题的人 - 我找到了另一个 SO 答案 here,这是一个很好的 Python 解决方案,它利用了 NumPy 的速度。

请考虑以下问题:

我有两张相同大小的图片。一个是具有不同不透明度的红色正方形:

第二个,一个蓝色的正方形,比红色的小,没有不透明但周围是白色的。

到目前为止,我正在为这个项目使用 OpenCV 的 python 绑定(在阅读了关于水印here 之后,我有这个:

redSquare = cv2.imread('redSquare.png', cv2.IMREAD_UNCHANGED)
(rH, rW) = redSquare.shape[:2]

blueSquare = cv2.imread('blueSquare.png')
(h, w) = blueSquare.shape[:2]

blueSquare = np.dstack([blueSquare, np.ones((h,w), dtype = 'uint8') * 255])
overlay = np.zeros((h,w,4), dtype = 'uint8')
overlay[0:rH, 0:rW] = redSquare
output = blueSquare .copy()
cv2.addWeighted(overlay, 0.5, output, 0.5, 0, output)

cv2.imwrite('imageAdded.png', output)

产生以下输出:

然而,想要的效果是:

现在我通过使用加权相加了解到,我使用每个 0.5,而我真的想要每个 1.0,但是当我尝试增加两者的权重时,只有一个增加,另一个减少。

如果有人对我如何实现这一点有所了解,最好是在 Python 中,但如果你知道 C++ 中的一种方法,我相信我可以复制它。

谢谢。

【问题讨论】:

  • 请提供带有alpha通道的红色图像。
  • 好的,请稍等,我会编辑。

标签: python opencv image-manipulation


【解决方案1】:

这里的 C++ 代码给出了你想要的结果。

// http://jepsonsblog.blogspot.be/2012/10/overlay-transparent-image-in-opencv.html
// https://gist.github.com/maximus5684/082f8939edb6aed7ba0a

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "iostream"

using namespace cv;
using namespace std;

void overlayImage(Mat* src, Mat* overlay, const Point& location)
{
    for (int y = max(location.y, 0); y < src->rows; ++y)
    {
        int fY = y - location.y;

        if (fY >= overlay->rows)
            break;

        for (int x = max(location.x, 0); x < src->cols; ++x)
        {
            int fX = x - location.x;

            if (fX >= overlay->cols)
                break;

            double opacity = ((double)overlay->data[fY * overlay->step + fX * overlay->channels() + 3]) / 255;

            for (int c = 0; opacity > 0 && c < src->channels(); ++c)
            {
                unsigned char overlayPx = overlay->data[fY * overlay->step + fX * overlay->channels() + c];
                unsigned char srcPx = src->data[y * src->step + x * src->channels() + c];
                src->data[y * src->step + src->channels() * x + c] = srcPx * (1. - opacity) + overlayPx * opacity;
            }
        }
    }
}

int main( int argc, char** argv )
{
    Mat overlay = imread("ZuWDz.png",IMREAD_UNCHANGED);
    Mat underlay = imread("CtBAe.png",IMREAD_UNCHANGED);

    if( underlay.empty() || overlay.empty() )
    {
        return -1;
    }

    overlayImage( &underlay, &overlay, Point() );
    imshow("underlay result",underlay);

    waitKey();

    return 0;
}

【讨论】:

  • 如果您能够重建 OpenCV,我还可以展示如何将此代码添加到 OpenCV 库并从 Python 调用。
  • 但是我使用的是 OpenCV 3.1.0,因为我注意到它似乎包含 opencv2,这会导致任何问题吗?
  • 我很快就会提出一个拉取请求来将此功能添加到 OpenCV。我希望它会被接受和合并。否则你可以添加你的 OpenCV 源代码并重建库。
  • 太好了,我希望它也能被接受。很有用!
  • here 您可以找到如何将功能添加到 OpenCV。我认为它太原始了,无法合并到库中,但我分享了它以显示方式。
猜你喜欢
  • 2018-10-11
  • 2020-07-12
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多