好!纯python的opencv的照片背景颜色更换探索
1 说明:
=====
1.1 对照片进行背景颜色替换,用处比较多。目前用python和opencv来看看。
1.2 纯python和opencv代码来试试看,一起探索和思考,提高自己的思维能力。
蓝底原图:1111.jpeg
参考文章1:https://blog.csdn.net/weixin_45192980/article/details/107724733?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.add_param_isCf
2 bluetored:蓝底变红底
===================
2.1 图片:上图来自今日头条图库:蓝底原图:1111.jpeg
2.2 bluetored.py代码:import cv2 import numpy as np #读取蓝底原图 img=cv2.imread("/home/xgj/Desktop/pic-bg/1111.jpeg") #缩放 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([90,70,70]) #提示蓝色底 upper_blue=np.array([110,255,255]) #提示蓝色底 mask = cv2.inRange(hsv, lower_blue, upper_blue) cv2.imshow("Mask", mask) #显示mask掩膜图 #腐蚀膨胀 erode=cv2.erode(mask,None,iterations=1) cv2.imshow("erode",erode) #显示erode图 dilate=cv2.dilate(erode,None,iterations=1) cv2.imshow("dilate",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()
2.3 效果图:
3 whitetored:白底变红底
====================
3.1 图片:来自今日头条图库
白底原图:2222.jpeg
3.2 效果图:
有bug了
3.3 whitetored.py代码:import cv2 import numpy as np #白底原图读取 img=cv2.imread("/home/xgj/Desktop/pic-bg/2222.jpeg") #缩放 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_white = np.array([0, 0, 200]) #白底 upper_white = np.array([180, 40, 255]) #白底 #掩膜 mask = cv2.inRange(hsv, lower_white, upper_white) 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通道,背景颜色为红底 #img[i,j]=(255,0,0) #背景颜色为蓝底,假如白底变蓝底,附加 cv2.imshow("res",img) cv2.waitKey(0) cv2.destroyAllWindows()
参考文章2:https://blog.csdn.net/shenglong456/article/details/71174175?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf
4 greentocolor:绿色背景变色
=======================
4.1 图片:来自今日头条图库
绿色背景图:ls.jpeg
4.2 代码:import cv2 import numpy #绿色背景照片 img=cv2.imread("/home/xgj/Desktop/pic-bg/mask/ls.jpeg",1) # opencv 将BGR 转换成 HSV imgHSV=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) #遍历 for i in range(img.shape[0]): for j in range(img.shape[1]): #判断是否绿色 50和75参数可以改变 应该不是最好 if imgHSV[i,j,0]<75 and imgHSV[i,j,0]>50: #难点:判断背景颜色 #下面是可变背景颜色,附带几种,color #img[i,j]=[255,255,255] #变白色 #img[i,j]=[0,0,255] #变红色 img[i,j]=[255,0,0] #变蓝色 cv2.namedWindow("Image",cv2.WINDOW_NORMAL) cv2.imshow("Image",img) cv2.waitKey(0) cv2.destoryAllWindows()
4.3 效果图:
小bug
===以上都是单一背景颜色的改变===
5 复杂背景的改色或改背景图片:
=========================
5.1 图片:来自今日头条图库
bw1.jpeg
5.2 先抠图,代码如下:交互式抠图import numpy as np import cv2 #定义全局变量 n = 0 #定义鼠标按下的次数 ix = 0 # x,y 坐标的临时存储 iy = 0 rect = (0,0,0,0) #前景区域 #鼠标回调函数 def draw_rectangle(event,x,y,flags,param): global n,ix,iy,rect if event==cv2.EVENT_LBUTTONDOWN : if n == 0: #首次按下保存坐标值 n+=1 ix,iy = x,y else: #第二次按下显示矩形 n+=1 rect = (ix,iy,(x-ix),(y-iy))#前景区域 #读取图像 img = cv2.imread("/home/xgj/Desktop/pic-bg/ppp/bw1.jpeg") mask = np.zeros(img.shape[:2],np.uint8) bgdModel = np.zeros((1,65),np.float64) fgdModel = np.zeros((1,65),np.float64) #选择区域 左上到右下矩形 cv2.namedWindow("img") cv2.setMouseCallback("img",draw_rectangle)#绑定鼠标 while(n != 2): cv2.imshow("img",img) cv2.waitKey(2) #前景提取 cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT) mask2 = np.where((mask==2)|(mask==0),0,1).astype("uint8") img = img*mask2[:,:,np.newaxis] #显示图像 cv2.imshow("img",img) #保存,抠图后的图片 cv2.imwrite("/home/xgj/Desktop/pic-bg/ppp/bw2.jpeg",img) cv2.waitKey() cv2.destroyAllWindows()
5.3 操作如下图:
上述得到的图:bw2.jpeg
需要设置背景图片:back.jpeg
5.4 更换背景图片:
=============
5.4.1 参考文章3:https://blog.csdn.net/haofan_/article/details/76687238
5.4.2 代码:import cv2 import numpy as np #人物图 img=cv2.imread("/home/xgj/Desktop/pic-bg/ppp/bw2.jpeg") #需要更改成的背景图片 img_back=cv2.imread("/home/xgj/Desktop/pic-bg/ppp/back.jpeg") #日常缩放 rows,cols,channels = img_back.shape img_back=cv2.resize(img_back,None,fx=0.7,fy=0.7) cv2.imshow("img_back",img_back) #原人物图片缩放40% img=cv2.resize(img,None,fx=0.4,fy=0.4) cv2.imshow("img",img) rows,cols,channels = img.shape #rows,cols最后一定要是前景图片的,后面遍历图片需要用到 #转换hsv hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) #获取mask lower_black = np.array([0, 0, 0]) upper_black = np.array([180, 255, 46]) mask = cv2.inRange(hsv, lower_black, upper_black) 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) #遍历替换 #center=[50,50]#在新背景图片中的位置 center=[int(img.shape[0]/2),50] for i in range(rows): for j in range(cols): if dilate[i,j]==0:#0代表黑色的点 img_back[center[0]+i,center[1]+j]=img[i,j]#此处替换颜色,为BGR通道 cv2.imshow("res",img_back) #显示效果图 cv2.imwrite("/home/xgj/Desktop/pic-bg/ppp/bw3back.png",img_back) #保存合成图 cv2.waitKey(0) cv2.destroyAllWindows()
5.4.3 操作效果图:
===自己整理并分享出来===
喜欢的人,请点赞,关注、评论、转发和收藏。