1. 程式人生 > >OpenCV影象處理--將影象裁剪為圓形

OpenCV影象處理--將影象裁剪為圓形

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,效果

cut_img1.png

cut_img2.png

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.
    ...

參考網頁