快過(guò)年了,各種互聯(lián)網(wǎng)產(chǎn)品都出來(lái)撒紅包。某寶一年一度的“集五?;顒?dòng)”更是成為每年的必備活動(dòng)之一。
雖然到最后每人大概也就分個(gè)兩塊錢(qián),但作為一個(gè)全民話(huà)題,大多數(shù)人還是愿意湊湊熱鬧。
!
畢竟對(duì)于如今生活在大城市的人來(lái)說(shuō),集福領(lǐng)紅包和空蕩的地鐵車(chē)廂或許已是最大的“年味”了。
既然是湊熱鬧,怎么能少得了我。
之前我(GitPython公眾號(hào))發(fā)過(guò)一篇:《10幾行代碼,用python打造實(shí)時(shí)截圖識(shí)別OCR》,介紹的是OCR文字識(shí)別的使用。
本篇文章再來(lái)對(duì)“?!弊肿鑫恼?,演示下如何用python圖像處理功能,把一幅“?!弊謭D片轉(zhuǎn)出 5 種不同的效果:
?
python最圖像處理最常用的兩個(gè)模塊是PIL和OpenCV,這里我們選擇 OpenCV。
讀取圖片及展示代碼:
import?cv2
from?matplotlib?import?pyplot?as?plt
img?=?cv2.imread('fu.png')
#?轉(zhuǎn)換顏色模式,顯示原圖
img?=?cv2.cvtColor(img,?cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()
因?yàn)?OpenCV 和 matplotlib 的顏色模式不一樣,所以需要做一次轉(zhuǎn)換,如果是直接通過(guò) cv2 展示和保存圖片則不需要。
上面的效果分別用到了以下功能:
01
灰度福
這里沒(méi)有選擇直接將圖片轉(zhuǎn)出灰度圖,因?yàn)檫@樣會(huì)導(dǎo)致福字不明顯。而是通過(guò)將紅、綠、藍(lán)三通道分離后,選擇色差最大的紅色通道。
r,g,b?=?cv2.split(img)
02
輪廓福
使用了 OpenCV 自帶的圖像輪廓提取功能。為了更好的效果,這里對(duì)紅色通道進(jìn)行二值化后,再查找輪廓。
_,?img_bin?=?cv2.threshold(r,?50,?255,?cv2.THRESH_BINARY)
_,?contours,?_?=?cv2.findContours(img_bin,?cv2.RETR_TREE,?cv2.CHAIN_APPROX_SIMPLE)
img_cont?=?np.zeros(img_bin.shape,?np.uint8)????
cv2.drawContours(img_cont,?contours,?-1,?255,?3)
03
反色福
發(fā)色的實(shí)現(xiàn)是將每個(gè)像素值 x 轉(zhuǎn)成 255-x。如果遍歷像素計(jì)算會(huì)比較慢,于是用了一個(gè)小技巧:轉(zhuǎn)成numpy的ndarray再進(jìn)行矩陣運(yùn)算。
img_i?=?np.asarray(img)
img_i?=?255?-?img_i
04
膨脹福
這里其實(shí)是“圖像腐蝕”操作(與“圖像膨脹”操作相反)。因?yàn)樵谖覀冞x取的紅色通道中,白色是背景,黑色才是福字,所以對(duì)白色的“腐蝕”也就是對(duì)黑色的“膨脹”。這也是OpenCV的內(nèi)置功能。
做完這一步,又對(duì)圖像進(jìn)行了切割,直接通過(guò)列表的切片操作實(shí)現(xiàn)。
kernel?=?cv2.getStructuringElement(cv2.MORPH_RECT,(25,?25))
eroded?=?cv2.erode(r,?kernel)
size?=?img.shape
eroded?=?eroded[int(size[1]*0.15):int(size[1]*0.7),int(size[0]*0.2):int(size[0]*0.85)]
05
福到了
OpenCV 提供了翻轉(zhuǎn)操作,第二個(gè)參數(shù)是旋轉(zhuǎn)軸的選取,你可以試試 0 和 1 的效果。
img_r?=?cv2.flip(img,?-1)