根据 mask 标签(跟原图一样大小的二值图),1)把 mask(cv2.addWeighted
) 画在原图上,2)把 mask 轮廓(cv2.findContours
)画在原图上
来自 Python-OpenCV 图像叠加or图像混合加权(cv2.addWeighted)
import numpy as np
img1 = cv2.imread("/home/Downloads/cat.jpg")
img2 = cv2.imread("/home/Downloads/1.bmp") # 颜色通道顺序为 BGR
img2[:,:,0] *= 0 # 蓝色通道为0
img2[:,:,1] *= 0 # 绿色通道为0
img2[:,:,2] *= 1 # 保留红色通道
imgadd = cv2.addWeighted(img1,1,img2,0.5,0) # 原图权重1,mask 权重 0.5(调透明度)
cv2.imshow("image",imgadd)
cv2.waitKey(3000)
import cv2
import numpy as np
img1 = cv2.imread("/home/yanmeng/Downloads/cat.jpg")
img2 = cv2.imread("/home/yanmeng/Downloads/1.bmp") # BGR
gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 彩色图变灰度图
_,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) # 灰度图变二值图
_, contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 根据二值图找轮廓
cv2.drawContours(img1,contours,-1,(0,0,255),3) # 把轮廓画在原图上(0,0,255) 表示 RGB 三通道,红色
cv2.imshow("image",img1) # 显示原图
cv2.waitKey(3000)
注意 cv2.findContours
的返回值个数可能因 opencv 版本不同而不一样,我的版本是三个返回值,有的版本是两个
效果图如下
我们把其他的 mask 的轮廓也都画在原图上,有 1.bmp~4.bmp
import cv2
def bgr2binary(image): # 彩色转二值
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
return binary
binarys = []
img = cv2.imread("/home/yanmeng/Downloads/cat.jpg") # 原图
for i in range(1,5): # 遍历 mask 图片
mask_path = "/home/yanmeng/Downloads/{}.bmp".format(str(i))
mask = cv2.imread(mask_path)
binarys.append(bgr2binary(mask)) # 读 mask 并转换为二值图
for binary_mask in binarys: # 遍历二值化后的 mask
_, contours, _ = cv2.findContours(binary_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 找轮廓,并用红色标记出来
cv2.drawContours(img,contours,-1,(0,0,255),3) # 把轮廓画在原图上
cv2.imshow("image",img) # 显示原图
cv2.waitKey(3000)
mask 具体形式如下所示
代码来自 https://mp.weixin.qq.com/s/6q5AZRhLKlu1yqf3PTPkHQ
import cv2
def Pic2Cartton(path):
downsampleNum = 2 # 金字塔下采样
bilateralNum = 7 # 双边滤波
img = cv2.imread(path)
shape = tuple(list(((i // 4) * 4 for i in img.shape))[:2])[::-1]
img = cv2.resize(img, dsize=shape)
imgColor = img
# 通过不断的双边滤波来降低色彩的数量
for i in range(downsampleNum):
imgColor = cv2.pyrDown(imgColor)
for i in range(bilateralNum): # 利用较小的核不断进行双边滤波,减少图片颜色
imgColor = cv2.bilateralFilter(imgColor, d=9, sigmaColor=5, sigmaSpace=7)
for i in range(downsampleNum):
imgColor = cv2.pyrUp(imgColor)
# 开始寻找轮廓
imgBinary = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
imgMedianBlur = cv2.medianBlur(imgBinary, 7) # 中值滤波去除噪点
imgContour = cv2.adaptiveThreshold(imgMedianBlur,
255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
blockSize=9,
C=2) # 二值化
imgContour = cv2.cvtColor(imgContour, cv2.COLOR_GRAY2RGB)
cv2.imwrite("C://Users/Administrator/Desktop/2.jpg", imgContour)
img_cartoon = cv2.bitwise_and(imgColor, imgContour) # 采用与操作,边缘保留褐色,其它case
cv2.imwrite("C://Users/Administrator/Desktop/3.jpg", img_cartoon)
Pic2Cartton("C://Users/Administrator/Desktop/1.jpg")