opencv 实现png透明图像叠加在jpg图像上
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv
免费下载资源
·
效果图:
背景图:前景图:
import cv2
import numpy as np
'''
叠加图片
'''
def image_overlay():
# 加载背景图像
background = cv2.imread('background.jpg')
# 加载前景图像
foreground = cv2.imread('foreground.png', cv2.IMREAD_UNCHANGED)
# 确保前景图像和背景图像尺寸相同
foreground = cv2.resize(foreground, (background.shape[1], background.shape[0]))
# 获取前景图像的 alpha 通道(如果有的话)
alpha = foreground[:, :, 3] / 255.0
# 分离前景和背景的颜色通道
foreground = foreground[:, :, 0:3]
background = background[:, :, 0:3]
# 扩展 alpha 通道的维度,以便进行乘法运算
alpha = np.expand_dims(alpha, axis=2)
# 根据 alpha 通道对前景图像和背景图像进行混合
blended = (background * (1 - alpha) + foreground * alpha).astype(np.uint8)
# 在背景图像上覆盖混合后的图像
result = background.copy()
result[:,:,:] = blended
# 显示结果
cv2.imshow('Overlay Image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
using OpenCvSharp;
using System;
namespace OpenCVNet.Utility
{
public static class OpenCVUtility
{
/// <summary>
/// 叠加图片(循环像素点)
/// </summary>
/// <param name="bgPath">背景图像</param>
/// <param name="fgPath">前景图像</param>
/// <param name="dstPath">目标图像</param>
/// <returns></returns>
public static void OverlayImage2(string bgPath, string fgPath, string dstPath)
{
// 加载背景图像
Mat background = Cv2.ImRead(bgPath,ImreadModes.Color);
// 加载前景图像
Mat foreground = Cv2.ImRead(fgPath, ImreadModes.Unchanged);
// 确保前景图像和背景图像尺寸相同
Cv2.Resize(foreground, foreground, new Size(background.Cols, background.Rows));
// 将前景图片覆盖在背景图片上
for (int y = 0; y < foreground.Rows; y++)
{
for (int x = 0; x < foreground.Cols; x++)
{
Vec4b foregroundPixel = foreground.Get<Vec4b>(y, x);
Vec3b backgroundPixel = background.Get<Vec3b>(y, x);
// 获取前景图像的RGB通道值和alpha通道值
int foregroundB = foregroundPixel.Item0;
int foregroundG = foregroundPixel.Item1;
int foregroundR = foregroundPixel.Item2;
// 将alpha值归一化到0到1之间
double alpha = foregroundPixel.Item3 / 255.0;
// 混合RGB通道值
int mixedB = (int)(foregroundB * alpha + backgroundPixel.Item0 * (1 - alpha));
int mixedG = (int)(foregroundG * alpha + backgroundPixel.Item1 * (1 - alpha));
int mixedR = (int)(foregroundR * alpha + backgroundPixel.Item2 * (1 - alpha));
// 更新背景图像的RGB通道值
background.Set(y, x, new Vec3b((byte)mixedB, (byte)mixedG, (byte)mixedR));
//if (foregroundPixel[3] > 0) // 只处理不透明的像素
//{
// background.Set<Vec3b>(y, x, new Vec3b(foregroundPixel[0], foregroundPixel[1], foregroundPixel[2]));
//}
}
}
// 显示结果
Cv2.ImShow("Overlay Image", background);
Cv2.WaitKey(0);
Cv2.DestroyAllWindows();
//保存合成的图像
//result.SaveImage(dstPath);
}
/// <summary>
/// 叠加图片
/// </summary>
/// <param name="bgPath"></param>
/// <param name="fgPath"></param>
/// <param name="dstPath"></param>
/// <returns></returns>
public static string OverlayImage(string bgPath, string fgPath, string dstPath)
{
// 加载背景图像
Mat background = Cv2.ImRead("D:/test/Image376.jpg");// ImreadModes.Color
// 加载前景图像
Mat foreground = Cv2.ImRead("D:/test/4330_PhotoStand003_2023-05-19_101659.png", ImreadModes.Unchanged);
// 确保前景图像和背景图像尺寸相同
Cv2.Resize(foreground, foreground, new Size(background.Cols, background.Rows));
// 分离前景图像的RGB通道和alpha通道
Mat[] foregroundChannels = Cv2.Split(foreground);
Mat alpha = (foregroundChannels.Length == 4) ? foregroundChannels[3] : null;
// 分离前景和背景的颜色通道
Mat blended = new Mat();
Cv2.Merge(foregroundChannels[0..3], blended);
if (alpha != null)
{
// 扩展 alpha 通道的维度,以便进行位运算
Mat expandedAlpha = new Mat();
Cv2.CvtColor(alpha, expandedAlpha, ColorConversionCodes.GRAY2BGR);
// 对 alpha 通道进行取反操作
Mat invAlpha = new Mat();
Cv2.BitwiseNot(expandedAlpha, invAlpha);
// 根据 alpha 通道对前景图像和背景图像进行混合
Cv2.BitwiseAnd(background, invAlpha, background);
Cv2.BitwiseAnd(blended, expandedAlpha, blended);
Cv2.BitwiseOr(background, blended, blended);
}
// 在背景图像上覆盖混合后的图像
Mat result = background.Clone();
blended.CopyTo(result);
// 显示结果
Cv2.ImShow("Overlay Image", result);
Cv2.WaitKey(0);
Cv2.DestroyAllWindows();
//保存合成的图像
//result.SaveImage(dstPath);
}
}
}
GitHub 加速计划 / opencv31 / opencv
77.34 K
55.71 K
下载
OpenCV: 开源计算机视觉库
最近提交(Master分支:25 天前 )
e1fec156
features2d: fixed out of bounds access in SIFT 3 天前
63087396 - 3 天前
更多推荐
已为社区贡献2条内容
所有评论(0)