概要
通过python带大家通过罩层对彩图进行二值化操作,最终实现抠图与图像拼接的功能。
关键字:罩层 MASK 二值化 抠图
最终抠图效果:
![f99ba82765a8061f9606763e1fa8d820.png](https://i-blog.csdnimg.cn/blog_migrate/65b5ff444b0c4b5c2f1fd3a34df557c7.png)
通过罩层对彩图进行二值化操作,实现抠图与图像拼接
- 概要
- 图像二值化
- 数学形态学处理
- 筛选连通域
- 抠图-带罩层的二值化与操作
- 换背景颜色
- 图片合并 cv2.add
- 高斯模糊
图像二值化
import cv2
# 载入原图
img = cv2.imread('cat.jpeg')
from matplotlib import pyplot as plt
# 展示图像
plt.imshow(img[:, :, ::-1])
![9a6c868d0a5791f842864020be2149e4.png](https://i-blog.csdnimg.cn/blog_migrate/1c7a96ca95fd27f63cb2333de5a20511.png)
# 图像二值化
img_bin = cv2.inRange(img, lowerb=(9, 16, 84), upperb=(255, 251, 255))
plt.imshow(img_bin, cmap='gray')
![bb08ef0f3e776e631e5a95a41d13e9fb.png](https://i-blog.csdnimg.cn/blog_migrate/ddfc510e99c2908943964be571d08ee7.png)
数学形态学处理
# 数学形态学预处理
import numpy as np
kernel = np.ones((5,5), np.uint8)
img_bin = cv2.erode(img_bin, kernel, iterations=1)
img_bin = cv2.dilate(img_bin, kernel, iterations=2)
plt.imshow(img_bin, cmap='gray')
![c89d53b792e218b5b17821efaa3b82ea.png](https://i-blog.csdnimg.cn/blog_migrate/9bc74af7f989ae00f73e80c9d0e3fa66.png)
筛选连通域
# 过滤掉小的contours
# 获取边缘信息
_, contours, hierarchy = cv2.findContours(image=img_bin,mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
def contours_area(cnt):
# 计算countour的面积
(x, y, w, h) = cv2.boundingRect(cnt)
return w * h
# 获取面积最大的contour
max_cnt = max(contours, key=lambda cnt: contours_area(cnt))
# 创建空白画布
mask = np.zeros_like(img_bin)
# 获取面积最大的 contours
mask = cv2.drawContours(mask,[max_cnt],0,255,-1)
# 打印罩层
plt.imshow(mask, cmap='gray')
![99b2f60c190eeb25b861a046b169b231.png](https://i-blog.csdnimg.cn/blog_migrate/520e5506f24a71649de9113b567a407b.png)
抠图-带罩层的二值化与操作
img跟它本身进行或/与操作(其实他们的结果是一样的) 在罩层区域(MASK)内进行。罩层区域为0, 黑色。
二值化操作就是 如果两个img的该点的像素点都不为零则保留原来的取值,否则就是黑色。
# 使用罩层对原来的图像进行抠图
sub_img = cv2.bitwise_or(img,img,mask=mask)
# sub_img = cv2.bitwise_and(img,img,mask=mask)
plt.imshow(sub_img[:,:,::-1])
![86e00fefce3d935be2babd2fcfd91dd9.png](https://i-blog.csdnimg.cn/blog_migrate/47a68074a254753cb3966ca8d69aa77e.png)
哇, 大白猫就抠出来了,是不是很惊艳!!!!!
换背景颜色
# 给大白猫换个背景
background = np.zeros_like(img)
background[:,:,:] = (150, 198, 12)
plt.imshow(background[:,:,::-1])
![3a21a12288d7db476a90b4988ef50686.png](https://i-blog.csdnimg.cn/blog_migrate/2640f88d76322232f357e7bd9d16cd8f.png)
# 获取新的背景
new_background = cv2.bitwise_or(background, background, mask=cv2.bitwise_not(mask))
plt.imshow(new_background[:,:,::-1])
![afec1b53151060015d73889914bca709.png](https://i-blog.csdnimg.cn/blog_migrate/cf5396ff074c4bd328b643a5b74d3cdd.png)
图片合并 cv2.add
new_img = cv2.add(new_background, sub_img)
plt.imshow(new_img[:,:,::-1])
![690c25f6a4e14499d8771f39dd30fbf9.png](https://i-blog.csdnimg.cn/blog_migrate/95ab61054b218be328272d2e1a336764.png)
高斯模糊
拼接感太强,做一下高斯模糊
# 用5*5的kernel进行高斯模糊
new_img_blur = cv2.GaussianBlur(new_img, (9,9), 5)
plt.imshow(new_img_blur[:,:,::-1])
![faf781d24faca7f4d1a0844c3e038e53.png](https://i-blog.csdnimg.cn/blog_migrate/c4ad222346dac4e27bd07bf06e6794e5.png)
![a6e0ae988e826fe4f6827383fcc1d15e.png](https://i-blog.csdnimg.cn/blog_migrate/88c481e4a8b4b6532a84baa517327f7c.png)
原文链接:
python大展身手带你通过罩层对彩图进行二值化操作,实现抠图与图像拼接_ywsydwsbn的博客-CSDN博客_python 以二值化区域抠图blog.csdn.net![2a636e0cddd0b2d43c657c9f5fcf3cc7.png](https://i-blog.csdnimg.cn/blog_migrate/94f3d6151dc4079201792fc3b1c5e9ad.jpeg)