【python】OpenCV—findContours


文章目录

  • 【1】 cv2.addWeighted
  • 【2】cv2.findContours
  • 漫画风


根据 mask 标签(跟原图一样大小的二值图),1)把 mask(cv2.addWeighted) 画在原图上,2)把 mask 轮廓(cv2.findContours)画在原图上

【1】 cv2.addWeighted

【python】OpenCV—findContours_第1张图片
来自 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)

1.bmp
【python】OpenCV—findContours_第2张图片
cat.jpg
【python】OpenCV—findContours_第3张图片
效果图如下
【python】OpenCV—findContours_第4张图片

【2】cv2.findContours

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 版本不同而不一样,我的版本是三个返回值,有的版本是两个

效果图如下
【python】OpenCV—findContours_第5张图片
我们把其他的 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 具体形式如下所示

2.bmp
【python】OpenCV—findContours_第6张图片3.bmp
【python】OpenCV—findContours_第7张图片4.bmp
【python】OpenCV—findContours_第8张图片
最终效果图

【python】OpenCV—findContours_第9张图片

漫画风

代码来自 https://mp.weixin.qq.com/s/6q5AZRhLKlu1yqf3PTPkHQ

理论
【python】OpenCV—findContours_第10张图片

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")

【python】OpenCV—findContours_第11张图片
【python】OpenCV—findContours_第12张图片
【python】OpenCV—findContours_第13张图片

你可能感兴趣的:(Python)