OpenCV影象處理--將影象裁剪為圓形
阿新 • • 發佈:2019-01-07
1,需求
為了便於專案前端展示使用者頭像,需要將頭像處理為圓形,非圓形區域設定為透明。其實,前端可以在顯示的時候處理,但是前端採用WebGL,暫時搞不定,所以由後端進行影象的一次性加工。
於是,我們嘗試用Linux工具Convert來完成,但是,百思無解,後續決定採用Python+OpenCV。
2,實現
優秀的程式碼不需要解釋,直接看程式碼吧,O(∩_∩)O。
#coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt
import glob as gb
# 影象處理,獲取圖片最大內接圓,其他區域置為透明
def img_deal(input_img):
# cv2.IMREAD_COLOR,讀取BGR通道數值,即彩色通道,該引數為函式預設值
# cv2.IMREAD_UNCHANGED,讀取透明(alpha)通道數值
# cv2.IMREAD_ANYDEPTH,讀取灰色圖,返回矩陣是兩維的
img = cv2.imread(input_img, cv2.IMREAD_UNCHANGED)
rows, cols, channel = img.shape
# 建立一張4通道的新圖片,包含透明通道,初始化是透明的
img_new = np.zeros((rows,cols,4 ),np.uint8)
img_new[:,:,0:3] = img[:,:,0:3]
# 建立一張單通道的圖片,設定最大內接圓為不透明,注意圓心的座標設定,cols是x座標,rows是y座標
img_circle = np.zeros((rows,cols,1),np.uint8)
img_circle[:,:,:] = 0 # 設定為全透明
img_circle = cv2.circle(img_circle,(cols/2,rows/2),min(rows, cols)/2,(255),-1) # 設定最大內接圓為不透明
# 圖片融合
img_new[:,:,3 ] = img_circle[:,:,0]
# 儲存圖片
cv2.imwrite(input_img+".png", img_new)
# cv2.imencode('.jpg', img)[1].tofile('./9.jpg') # 儲存到另外的位置
# 顯示圖片,呼叫opencv展示
# cv2.imshow("img_new", img_new)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# 顯示圖片,呼叫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的影象轉換,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
# 主函式
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.
...