修改
任何有类似问题的人 - 我发现了另一个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 ++中知道一种方法,我相信我可以复制它。
感谢。
答案 0 :(得分:2)
这里是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;
}