- 深度學習技術圖像處理入門
- 楊培文
- 1575字
- 2019-12-06 14:13:44
3.3 使用OpenCV“摳圖”——基于顏色通道以及形態特征
3.2節用簡單的矩陣操作方法對二維碼圖片進行了一系列操作,包括去Logo、降低像素等。本節談一談如何對圖片進行一些比較復雜的操作,比如我們3.1.1節中用數組切片來抓取足球,使用的命令是:
ball = img[280:340, 330:390]
為什么是這個坐標?這個坐標是我們人眼看出來的,能否讓計算機自動識別這個足球的位置?這里提供一種基于OpenCV的“套路”。
首先,還是需要認真觀察數據,就是剛才抓下來的球(如圖3-11所示):

圖3-11 從原圖中截取足球區域
plt.imshow(ball)
這個球具有以下特點:
- 看起來是個圓形。
- 顏色是黃色+藏藍色。
- 由于在草地上,因此背景是綠色。
根據這三個特點,我們大致確定思路,幾個步驟依次對應下面幾個特點:
- 看看有沒有圓形的識別算法——Hough變換。
- 用黃色+藏藍色將球從背景提取出來。
- 用綠色過濾背景色。
我們觀察這張球小型圖片中的60×60 =3600個像素,其中RGB的分布如何。這里仿照第2章用過的seaborn的pairplot函數來表達RGB三種顏色的兩兩組合,其結果如圖3-12所示:


圖3-12 圖3-11中各像素點RGB的分布情況
圖中的黃色與藍黑色均為足球的顏色,而綠色則是足球場的顏色。我們接下來要做的就是找一個規則來區分足球與足球場。這里簡單地寫一個規則組合,其結果如圖3-13所示:
fig = plt.figure(figsize=(15, 5)) ax1 = fig.add_subplot(131) ax2 = fig.add_subplot(132) ax3 = fig.add_subplot(133) ax1.imshow( (ball[:,:,0]>200) ) ax2.imshow( (ball[:,:,0]>130)+(ball[:,:,0]<50) ) ax3.imshow( (ball[:,:,0]>130)+(ball[:,:,0]<50)+(ball[:,:,1]<120) )

圖3-13 使用顏色規則對球的區域進行二值化(黑色代表球的區域)
好了,根據顏色規則,我們已經依稀得到了一個圓形物體。下一步,將這一規則推廣到整張圖片中,其結果如圖3-14所示。
fig = plt.figure(figsize=(12, 5)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122)
img1 = ((img[:,:,0]>130)+(img[:,:,0]<50)+(img[:,:,1]<120)).astype(np.uint8) ax1.imshow(img) ax2.imshow(img1)

圖3-14 使用顏色規則對整張圖片球的區域進行二值化(黑色代表球的區域)
由此可見,對整張圖片進行的顏色二值化處理還是比較有效的,至少球這里出現了圓形的形狀,我們經過簡單的處理后,將這里的圓形提取出來即可。但是這里任務并不輕松,因為圖中還是比較雜亂:首先,球中間的黑色部分含有白色,需要填充掉;其次,背景部分有很多觀眾、標語造成的白色環狀噪點,這些噪點不大,但會在圓形檢測環節干擾結果。
為了讓圖片結果減少噪點,我們這里利用OpenCV進行一組侵蝕(erode)稀釋(dilute)操作,如圖3-15(對圖3-14的結果先進行2像素侵蝕,再進行8像素的稀釋,最后進行3像素的侵蝕的整個過程)所示。形象地說,可以將圖中的黑色區域看成是海島,白色看成是海洋。進行侵蝕操作后,海水上漲,白色區域變多,將孤立的黑色區域“淹沒”;然后進行稀釋操作。此時海水退去,沒有被完全淹沒的、面積較大的海島基本恢復以前的樣子,而被完全淹沒的、面積小的海島則從此消失。


圖3-15 侵蝕、稀釋操作
經過侵蝕、稀釋操作后,圖中的黑色部分將會完全連在一起,面積較小的噪點則會被完全淹沒在背景中。此時,下面的兩個黑色圓形物體正是我們需要識別的球。現在先不著急,因為OpenCV的圓形識別算法識別的并非圓形物體,而是圓形的線條。因此還需要將這張圖片的邊緣提取出來,提取邊緣的方法就是對整張圖片計算梯度,此時如果一張像素周圍全是黑色或者全是白色,則梯度為0;而旁邊既有黑色又有白色,則會產生一個顏色梯度,即圖片邊緣。我們可以用Sobel算子分別對圖像的橫向、縱向計算顏色梯度,然后求平方根,得到總梯度。Sobel算子是一個3×3的卷積核,定義如下:

計算過程如下:

Opencv-python的對應代碼如下:
sobelx = cv2.Sobel(img_ede*255, cv2.CV_64F, 1, 0) sobely = cv2.Sobel(img_ede*255, cv2.CV_64F, 0, 1) img_sob = np.sqrt(sobelx**2+sobely**2).astype(np.uint8) plt.imshow(img_sob)
其結果如圖3-16所示。

圖3-16 對圖3-15的結果使用Sobel算子找出其邊緣位置所在
此時已經得到了圓形的邊緣,接下來調用OpenCV的圓形檢測函數——cv2.HoughCircle,用Hough變換提取圖中的圓形物體即可,如圖3-17所示。


圖3-17 成功識別圖3-14中球所在的位置
最后多說幾句:
(1)Hough變換可以在圖中檢索線段以及圓形,具體原理與利用極坐標系來表示線段、圓上的點有關,大家可以另行學習。常見的應用場景包括自動駕駛系統檢測道路線(直線檢測),以及顯微鏡下觀察細胞(圓形檢測)。
(2)通常情況下,Hough變換可以直接用在灰度圖上,即上一個代碼框里的gray = img_sob可以是gray = img_gray。這里之所以沒有這么做,是因為背景部分同樣有很多類似圓形的物體,造成了很多干擾,可能需要調試很多參數才能得到想要的結果,讀者不妨試一試。如果通過顏色選擇將特征二值化,進而通過侵蝕、稀釋操作進一步去除背景噪聲之后,可以讓輸入的圖形更加簡單,更加方便參數的調試。
- OpenStack實戰指南
- SOLIDWORKS 2021中文版基礎入門一本通
- Drupal 6 Panels Cookbook
- Seam 2 Web Development: LITE
- Oracle 11g Streams Implementer's Guide
- After Effects 2022從入門到精通
- SVG動畫
- Plone 3 for Education
- Adobe創意大學InDesign產品專家認證標準教材(CS6修訂版)
- Photoshop CS6淘寶美工完全實例教程(培訓教材版)
- Photoshop CS6淘寶美工完全實例教程(全視頻彩色版)
- 剪輯師寶典:視頻剪輯思維與案例實戰
- 玩轉國潮:Procreate插畫創作及實例教程
- Photoshop CC 從入門到精通
- Photoshop CC中文版案例培訓教程