尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️
然後這是一張背景圖:
今天的任務很簡單,我要對第一張圖中的人物進行摳圖,然後貼在背景圖上。
這個操作用PS並不複雜,讓我們來看一下這一過程如何用代碼來做到~
私信菜鳥007獲取神秘大獎一份!
素材處理
首先,導入一些工具包
opencv(cv2),用於圖像處理
numpy,用於數據計算。
matplotlib用於出圖。
然後,導入前景圖。
因為opencv的圖片默認使用BGR圖像格式,而我們通常使用的圖片是RGB(紅,綠,藍),所以,需要再轉換一下格式,否則查看時顏色會失真。
最後列印圖片規格和圖片本身
同樣的方法,導入背景圖
#導入背景圖 back_img = cv2.imread('back_img.jpg') #圖片導入 back_img = cv2.cvtColor(back_img,cv2.COLOR_BGR2RGB) #轉換顏色模型 print(back_img.shape) #列印圖片規格 show(back_img) #顯示圖片
效果如下,高1079,長1920,3通道。
我們發現人物圖高度和背景高度差不多,且我們只要中間的人像即可,那麼我們先來適當地裁剪一下圖片
#裁剪圖片 img = img[0:1000,150:550] #裁剪圖片大小 show(img) #顯示圖片
通過切片,裁去了logo
再對圖片縮小10%,這樣大小最為合適
#縮放圖片 print(img.shape) #列印圖片規格 img=cv2.resize(img,None,fx=0.9,fy=0.9) #圖片縮小10% print(img.shape) #列印圖片規格
列印一下圖片尺寸,發現裁剪成功
圖片在計算機中是用數字矩陣形式保存的,紅、綠、藍三個顏色通道每種色各分為256階,分別由0-255這256個數表示。比如900*360的圖片,可以理解為900行360列的像素矩陣,而每個像素又是由R,G,B三個數字確認其顏色的。於是,我們先把圖片的行,列數記錄下來,稍後可以用諸如遍歷的方法讀取每個像素,再對其進行矩陣計算。
#拆分圖片信息 rows,cols,channels = img.shape #拆分圖片信息
▼
摳圖:三種效果
摳圖的方法雷同PS,我們要先建立個蒙版。在開始之前,我們先需要把圖片轉換成HSV格式,這是一種比較直觀的顏色模型,可以更好的數字化處理顏色。
#轉換格式 img_hsv = cv2.cvtColor(img,cv2.COLOR_RGB2HSV) #把圖片轉換成HSV格式,用於摳圖 show(img_hsv) #顯示圖片
看下效果:
雖然不能直視,但做法顯而易見,只要把非藍色的部分提取出來。我們設定一個閾值,在最小閾值以下和最大閾值以上,圖像變為0,而在閾值之間的變為255。
#摳圖 lower_blue=np.array([0,0,0]) #獲取最小閾值 upper_blue=np.array([0,255,255]) #獲取最大閾值 mask = cv2.inRange(img_hsv, lower_blue, upper_blue) #創建遮罩 show(mask) #顯示遮罩
然後,遮罩就這麼給整了出來。
不過,我們發現,人物中間有那麼多小點點,我需要把它們去掉。這里使用形態學圖像處理的基本方法,先腐蝕後膨脹。其原理是在原圖的小區域內取局部最小值和最大值,背後的邏輯為深度學習中的卷積神經網路。
通過嘗試,我發現還可以使用開運算(先腐蝕後膨脹的整合運算)直接完成這一過程,且效果相對較好。
erode=cv2.erode(mask,None,iterations=3) #圖像腐蝕 show(erode) #顯示圖片 dilate=cv2.dilate(erode,None,iterations=1) #圖像膨脹 show(dilate) #顯示圖片 opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8,8))) #開運算 show(opening) #顯示圖片
大家可以自行比較下腐蝕,腐蝕後膨脹和開運算的效果:
▼
圖像合併
最後,終於到了圖像合併環節。先設定人物在背景圖中的起始位置。再遍歷遮罩中的每個像素,如果是0(代表黑色),則把人物圖像上的顏色賦值到背景圖像上。
center = [70,240] #設置前景圖開始位置 for i in range(rows): for j in range(cols): if opening[i,j]==0: #代表黑色 back_img[center[0]+i,center[1]+j] =img[i,j] #賦值顏色 show(back_img) #顯示圖片
運行完畢,顯示結果:
受限於圖片質量和簡化代碼,略顯粗糙,但大體已經達到功能~
最後,調整圖片格式,並保存。
back_img = cv2.cvtColor(back_img,cv2.COLOR_RGB2BGR) #圖像格式轉換 back_img=cv2.resize(back_img,None,fx=0.8,fy=0.8) #圖像縮放20% cv2.imwrite('result.png',back_img) #保存圖像
記得私信菜鳥哦,教程到此為止!