1胁艰,需求
為了便于項目前端展示用戶頭像款筑,需要將頭像處理為圓形,非圓形區(qū)域設(shè)置為透明腾么。其實奈梳,前端可以在顯示的時候處理,但是前端采用WebGL解虱,暫時搞不定颈嚼,所以由后端進行圖像的一次性加工。
于是饭寺,我們嘗試用Linux工具Convert來完成,但是叫挟,百思無解艰匙,后續(xù)決定采用Python+OpenCV。
2抹恳,實現(xiàn)
優(yōu)秀的代碼不需要解釋员凝,直接看代碼吧,O(∩_∩)O奋献。
#coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt
import glob as gb
# 圖像處理健霹,獲取圖片最大內(nèi)接圓旺上,其他區(qū)域置為透明
def img_deal(input_img):
# cv2.IMREAD_COLOR,讀取BGR通道數(shù)值糖埋,即彩色通道宣吱,該參數(shù)為函數(shù)默認值
# cv2.IMREAD_UNCHANGED,讀取透明(alpha)通道數(shù)值
# cv2.IMREAD_ANYDEPTH瞳别,讀取灰色圖征候,返回矩陣是兩維的
img = cv2.imread(input_img, cv2.IMREAD_UNCHANGED)
rows, cols, channel = img.shape
# 創(chuàng)建一張4通道的新圖片,包含透明通道祟敛,初始化是透明的
img_new = np.zeros((rows,cols,4),np.uint8)
img_new[:,:,0:3] = img[:,:,0:3]
# 創(chuàng)建一張單通道的圖片疤坝,設(shè)置最大內(nèi)接圓為不透明,注意圓心的坐標設(shè)置馆铁,cols是x坐標跑揉,rows是y坐標
img_circle = np.zeros((rows,cols,1),np.uint8)
img_circle[:,:,:] = 0 # 設(shè)置為全透明
img_circle = cv2.circle(img_circle,(cols/2,rows/2),min(rows, cols)/2,(255),-1) # 設(shè)置最大內(nèi)接圓為不透明
# 圖片融合
img_new[:,:,3] = img_circle[:,:,0]
# 保存圖片
cv2.imwrite(input_img+".png", img_new)
# cv2.imencode('.jpg', img)[1].tofile('./9.jpg') # 保存到另外的位置
# 顯示圖片,調(diào)用opencv展示
# cv2.imshow("img_new", img_new)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# 顯示圖片埠巨,調(diào)用matplotlib.pyplot展示
plt.subplot(121), plt.imshow(img_convert(img), cmap='gray'), plt.title('IMG')
plt.subplot(122), plt.imshow(img_convert(img_new), cmap='gray'), plt.title('IMG_NEW')
plt.show()
# cv2與matplotlib的圖像轉(zhuǎn)換历谍,cv2是bgr格式,matplotlib是rgb格式
def img_convert(cv2_img):
# 灰度圖片直接返回
if len(cv2_img.shape) == 2:
return cv2_img
# 3通道的BGR圖片
elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 3:
b, g, r = cv2.split(cv2_img)
return cv2.merge((r, g, b))
# 4通道的BGR圖片
elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 4:
b, g, r, a = cv2.split(cv2_img)
return cv2.merge((r, g, b, a))
# 未知圖片格式
else:
return cv2_img
# 主函數(shù)
if __name__ == "__main__":
img_path = gb.glob("img/*")
for path in img_path:
print path
img_deal(path)
3乖订,效果
4扮饶,參考資料
幫助文檔
- OpenCV的成套資料比較少,遇到問題還需要查看幫助文檔
>>> from matplotlib import pyplot
Backend TkAgg is interactive backend. Turning interactive mode on.
>>> help(pyplot.imshow)
Help on function imshow in module matplotlib.pyplot:
imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, hold=None, **kwargs)
call signature::
imshow(X, cmap=None, norm=None, aspect=None, interpolation=None,
alpha=None, vmin=None, vmax=None, origin=None, extent=None,
**kwargs)
Display the image in *X* to current axes. *X* may be a float
array, a uint8 array or a PIL image. If *X* is an array, *X*
can have the following shapes:
* MxN -- luminance (grayscale, float array only)
* MxNx3 -- RGB (float or uint8 array)
* MxNx4 -- RGBA (float or uint8 array)
The value for each component of MxNx3 and MxNx4 float arrays should be
in the range 0.0 to 1.0; MxN float arrays may be normalised.
An :class:`matplotlib.image.AxesImage` instance is returned.
...
參考網(wǎng)頁
Matplotlib調(diào)用imshow()函數(shù)繪制熱圖
http://blog.csdn.net/Eastmount/article/details/73392106?locationNum=5&fps=1opencv中的Circle函數(shù)
http://blog.csdn.net/yangfengman/article/details/52768862cv2.imshow官方介紹(為什么不能顯示透明圖片乍构,還是不清楚)
http://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html?highlight=imshow#cv2.imshowopencv不規(guī)則ROI——圓形ROI
http://www.cnblogs.com/xiangshancuizhu/archive/2011/11/16/2250931.html