简体   繁体   English

如何使用透明背景的opencv将png图像固定到另一个图像上

[英]how to fix png image onto another image with opencv with transparent background

I want to add glasses PNG image onto another image, but i get the PNG image with white background which hides the face.我想将眼镜 PNG 图像添加到另一张图像上,但我得到了带有白色背景的 PNG 图像,它隐藏了脸部。

I need to know what i did wrong please.我需要知道我做错了什么。

Original face image原始人脸图像

原始人脸图像

Original glasses image原始眼镜图片

原始眼镜图像

Expected result预期结果

这是我得到的结果

import cv2
import numpy
img = cv2.imread("barack-obama.jpg")
lunette = cv2.imread("lunette.png", cv2.IMREAD_UNCHANGED)
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

eyes = eye_cascade.detectMultiScale(img, scaleFactor = 1.1, minNeighbors = 5)   

r = 500.0 / img.shape[1]
dim = (500, int(img.shape[0] * r))
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)

 grey = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(grey, 1.3, 5)

for (x,y,w,h) in faces:

roi_grey = grey[y:y+h, x:x+w]
roi_color = resized[y:y + h, x:x + w]
eyes = eye_cascade.detectMultiScale(roi_grey)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

lunette = cv2.resize(lunette , (w,h))
w, h, c = lunette.shape 
for i in range(0, w):
for j in range(0, h):

    if lunette[i, j][0] != 0:
        resized[y + i, x + j] = lunette[i, j][1]
#help please
cv2.imshow('img',resized)

cv2.waitKey(0)

You can use cvzone library for solve this problem.您可以使用 cvzone 库来解决这个问题。

  1. install cvzone library安装 cvzone 库

    pip install cvzone
  2. import cvzone in your project在您的项目中导入 cvzone

     import cvzone
  3. imread your emoji with following format使用以下格式读取您的表情符号

    lunette = cv2.imread("lunette.png", cv2.IMREAD_UNCHANGED)
  4. now replace the your emoji like this:现在像这样替换你的表情符号:

     YOUR BACKGROUND PICTURE = cvzone.overlayPNG(YOUR BACKGROUND PICTURE, lunette , [x, y])

Here is one way to do that in Python/OpenCV/Numpy:这是在 Python/OpenCV/Numpy 中执行此操作的一种方法:

  • Read the background image (Obama)阅读背景图片(奥巴马)
  • Read the overlay image (glasses) unchanged读取覆盖图像(眼镜)不变
  • Extract the base BGR channels from the overlay image从叠加图像中提取基本 BGR 通道
  • Extract the alpha channel from the overlay image as a mask从叠加图像中提取 alpha 通道作为蒙版
  • Insert the BGR channels of the overlay into the background image at the desired location将叠加层的 BGR 通道插入到所需位置的背景图像中
  • Insert the mask into a black image the size of the background image at the desired location将蒙版插入到所需位置的背景图像大小的黑色图像中
  • Use Numpy where to composite the new background and overlay images using the new mask image使用 Numpy where 合成新背景并使用新蒙版图像覆盖图像
  • Save the result保存结果
import cv2
import numpy as np

# read background image
img = cv2.imread("obama.jpg")
ht, wd = img.shape[:2]

# read overlay image
img2 = cv2.imread("sunglasses.png", cv2.IMREAD_UNCHANGED)
ht2, wd2 = img2.shape[:2]

# extract alpha channel as mask and base bgr images
bgr = img2[:,:,0:3]
mask = img2[:,:,3]

# insert bgr into img at desired location and insert mask into black image
x = 580
y = 390

bgr_new = img.copy()
bgr_new[y:y+ht2, x:x+wd2] = bgr

mask_new = np.zeros((ht,wd), dtype=np.uint8)
mask_new[y:y+ht2, x:x+wd2] = mask
mask_new = cv2.cvtColor(mask_new, cv2.COLOR_GRAY2BGR)

# overlay the base bgr image onto img using mask
result = np.where(mask_new==255, bgr_new, img)

# save results
cv2.imwrite('obama_glasses.jpg', result)

# display results
cv2.imshow('bgr', bgr)
cv2.imshow('mask', mask)
cv2.imshow('bgr_new', bgr_new)
cv2.imshow('mask_new', mask_new)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM