简述
生活中经常要用到各种要求的证件照电子版,红底,蓝底,白底等,大部分情况我们只有其中一种,所以通过技术手段进行合成,用ps处理证件照,由于技术不到位,有瑕疵,所以想用python&opencv通过代码的方式实现背景颜色替换,加强一下对于opencv的学习,锻炼一下编码水平。
软件环境:
python3.5
opencv2
windows 10
图像载入
导入opencv库,使用imread函数读取图片
1
2
3
4
|
import cv2
import numpy as np
img = cv2.imread( 'zjz.jpg' )
|
由于证件照太大,不方便显示,故进行缩放
1
2
3
4
5
|
#缩放
rows,cols,channels = img.shape
img = cv2.resize(img,none,fx = 0.5 ,fy = 0.5 )
rows,cols,channels = img.shape
cv2.imshow( 'img' ,img)
|
原图如下
(图片源于网络,已经马赛克处理,如有侵权,私信立即删除)
获取背景区域
首先将读取的图像默认bgr格式转换为hsv格式,然后通过inrange函数获取背景的mask。
hsv颜色范围参数可调节根据这篇文章
1
2
3
4
5
|
hsv = cv2.cvtcolor(img,cv2.color_bgr2hsv)
lower_blue = np.array([ 78 , 43 , 46 ])
upper_blue = np.array([ 110 , 255 , 255 ])
mask = cv2.inrange(hsv, lower_blue, upper_blue)
cv2.imshow( 'mask' , mask)
|
获得的mask如下图
如图所示蓝色的背景在图中用白色表示,白色区域就是要替换的部分,但是黑色区域内有白点干扰,所以进一步优化。
腐蚀和膨胀
1
2
3
4
5
|
#腐蚀膨胀
erode = cv2.erode(mask,none,iterations = 1 )
cv2.imshow( 'erode' ,erode)
dilate = cv2.dilate(erode,none,iterations = 1 )
cv2.imshow( 'dilate' ,dilate)
|
经过腐蚀和膨胀操作后如下图
处理后图像单独白色点消失。
替换背景色
遍历全部像素点,如果该颜色为dilate里面为白色(255)则说明该点所在背景区域,于是在原图img中进行颜色替换。
1
2
3
4
5
6
|
#遍历替换
for i in range (rows):
for j in range (cols):
if dilate[i,j] = = 255 :
img[i,j] = ( 0 , 0 , 255 ) #此处替换颜色,为bgr通道
cv2.imshow( 'res' ,img)
|
最终结果如下
(图片源于网络,已经马赛克处理,如有侵权,私信立即删除)
总结
最开始想直接通过遍历全图进行替换背景色,但是图像中难免有些像素点和背景色一样,造成了干扰,导致最后结果不尽人意,所以想通过这种方法进行处理。显然最后有明显的ps痕迹。
最后贴上完整代码,不足之处欢迎各位指正!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import cv2
import numpy as np
img = cv2.imread( 'zjz.jpg' )
#缩放
rows,cols,channels = img.shape
img = cv2.resize(img,none,fx = 0.5 ,fy = 0.5 )
rows,cols,channels = img.shape
cv2.imshow( 'img' ,img)
#转换hsv
hsv = cv2.cvtcolor(img,cv2.color_bgr2hsv)
lower_blue = np.array([ 78 , 43 , 46 ])
upper_blue = np.array([ 110 , 255 , 255 ])
mask = cv2.inrange(hsv, lower_blue, upper_blue)
cv2.imshow( 'mask' , mask)
#腐蚀膨胀
erode = cv2.erode(mask,none,iterations = 1 )
cv2.imshow( 'erode' ,erode)
dilate = cv2.dilate(erode,none,iterations = 1 )
cv2.imshow( 'dilate' ,dilate)
#遍历替换
for i in range (rows):
for j in range (cols):
if dilate[i,j] = = 255 :
img[i,j] = ( 0 , 0 , 255 ) #此处替换颜色,为bgr通道
cv2.imshow( 'res' ,img)
cv2.waitkey( 0 )
cv2.destroyallwindows()
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/haofan_/article/details/76618362