aki*_*uri 2 python transparency opencv crop
我正在尝试从图像中裁剪对象,然后将其粘贴到另一个图像上。检查此答案中的方法,我已经成功地做到了。例如:
代码(show_mask_applied.py):
import sys
from pathlib import Path
from helpers_cv2 import *
import cv2
import numpy
img_path = Path(sys.argv[1])
img = cmyk_to_bgr(str(img_path))
threshed = threshold(img, 240, type=cv2.THRESH_BINARY_INV)
contours = find_contours(threshed)
mask = mask_from_contours(img, contours)
mask = dilate_mask(mask, 50)
crop = cv2.bitwise_or(img, img, mask=mask)
bg = cv2.imread("bg.jpg")
bg_mask = cv2.bitwise_not(mask)
bg_crop = cv2.bitwise_or(bg, bg, mask=bg_mask)
final = cv2.bitwise_or(crop, bg_crop)
cv2.imshow("debug", final)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
from pathlib import Path
import cv2
import numpy
from PIL import Image
from PIL import ImageCms
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
def cmyk_to_bgr(cmyk_img):
img = Image.open(cmyk_img)
if img.mode == "CMYK":
img = ImageCms.profileToProfile(img, "Color Profiles\\USWebCoatedSWOP.icc", "Color Profiles\\sRGB_Color_Space_Profile.icm", outputMode="RGB")
return cv2.cvtColor(numpy.array(img), cv2.COLOR_RGB2BGR)
def threshold(img, thresh=128, maxval=255, type=cv2.THRESH_BINARY):
if len(img.shape) == 3:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
threshed = cv2.threshold(img, thresh, maxval, type)[1]
return threshed
def find_contours(img):
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
contours = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
return contours[-2]
def mask_from_contours(ref_img, contours):
mask = numpy.zeros(ref_img.shape, numpy.uint8)
mask = cv2.drawContours(mask, contours, -1, (255,255,255), -1)
return cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
def dilate_mask(mask, kernel_size=11):
kernel = numpy.ones((kernel_size,kernel_size), numpy.uint8)
dilated = cv2.dilate(mask, kernel, iterations=1)
return dilated
Run Code Online (Sandbox Code Playgroud)
现在,我要使用锋利的/平滑的边缘来代替锋利的边缘。例如(右图;在Photoshop中创建):
我怎样才能做到这一点?
在此存储库中可以找到所有图像和代码。
您正在使用遮罩选择覆盖图像的一部分。遮罩目前看起来像这样:
首先让我们向该蒙版添加高斯模糊。
mask_blurred = cv2.GaussianBlur(mask,(99,99),0)
Run Code Online (Sandbox Code Playgroud)
我们可以做到这一点:
现在,剩下的任务是使用蒙版中的alpha值来混合图像,而不是像您当前一样将其用作逻辑运算符。
mask_blurred_3chan = cv2.cvtColor(mask_blurred, cv2.COLOR_GRAY2BGR).astype('float') / 255.
img = img.astype('float') / 255.
bg = bg.astype('float') / 255.
out = bg * (1 - mask_blurred_3chan) + img * mask_blurred_3chan
Run Code Online (Sandbox Code Playgroud)
上面的代码段非常简单。首先,将蒙版转换为3通道图像(因为我们要对所有通道进行蒙版)。然后将图像转换为浮动图像,因为遮罩是在浮动点完成的。最后一行完成实际工作:对于每个像素,根据遮罩中的值混合bg和img图像。结果看起来像这样:
羽化的数量由高斯模糊中的内核大小控制。请注意,它必须是一个奇数。
此后,out(最终图像)仍处于浮点状态。可以使用以下命令将其转换回int:
out = (out * 255).astype('uint8')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
225 次 |
| 最近记录: |