[ 導語 ] 人眼可以看到圖像的視覺信息,包括顏色特徵、紋理特徵、形狀特徵和空間關係特徵,但這種信息並不能讓計算機「看見」。想要讓計算機處理這種視覺信息,就要將圖像的視覺信息轉化成計算機能夠識別和處理的定量形式,也就是圖像特徵提取。下面將介紹兩種方法--基於結構形態的特徵提取與基於幾何分布的特徵提取。
研究方向:圖像處理,特徵提取
通常情況下,基於結構形態的特徵有兩類表示方法,一類是輪廓特徵,另一類是區域特徵。基於結構形態的特徵提取方法主要是將字符圖像的結構形態轉化為特徵向量,主要包括邊界特徵法、傅立葉特徵算子法、形狀不變矩法以及幾何參數法。原始圖片
#coding=utf-8import cv2import numpy as npim = cv2.imread('hough.png')edges = cv2.Canny(im, 50, 150, apertureSize=3)result = im.copy()minLineLength = 10maxLineGap = 30lines = cv2.HoughLinesP(edges, 1, np.pi/180, 200, minLineLength, maxLineGap)for x1, y1, x2, y2 in lines[0]: cv2.line(result, (x1, y1), (x2, y2), (0, 0, 255), 2)cv2.imwrite("hough_result.png", result)首先利用常見的圖像邊緣檢測算子求得圖像的邊緣,然後做出關於邊緣大小和方向的直方圖。通常的方法是構造圖像灰度梯度方向矩陣。圖像邊緣檢測。常用的邊緣檢測算子有Laplacian算子、Sobel算子、Prewitt算子、Canny算子等。一幅圖像是由很多個離散的像素點組成的,上面提到的這些算子將通過差分的方式來近似偏導數的值。其中,Canny算子是效果較好的一種圖像邊緣檢測算子。它分為兩個階段,首先對圖像進行高斯平滑,然後對平滑之後的圖像進行Roberts算子運算。以下圖(圖左為原圖,圖右為灰度圖)所示,給出Canny邊緣檢測算子的代碼。#coding=utf-8import cv2image = cv2.imread("lena.jpg")image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#Canny邊緣檢測canny = cv2.Canny(image, 30, 150)cv2.imwrite("Canny.jpg", canny)傅立葉特徵算子,又稱傅立葉形狀描述子,主要作用是通過對目標邊界的輪廓進行離散傅立葉變換得到目標邊界形狀的定量表達。離散傅立葉變換是圖像處理中常用的一種變換手段。通過離散傅立葉變換,我們可以將圖像的信號從時域轉換到頻域。當確定了圖像中的目標區域的起始點以及方向之後,我們就可以利用一系列的坐標對來描述邊界的信息了。假設邊界上有個邊界點,起始點為,按照順時針方向可以表示為一個坐標序列:一般來說,如果我們將目標邊界看成是從某一個點出發,則沿著該邊界順時針旋轉一周的周邊長可以用一個複函數來表示。換句話說就是,邊界上點的坐標可以用如下複數來表示:通過這種方式,可以成功地將坐標序列的二維表示轉換為一維表示。對於複數,可以用一個一維離散傅立葉變換係數表示:這裡的是圖像邊界的傅立葉描述子。同理,如果對進行傅立葉反變換,則可以得到最開始的坐標序列的表達式(僅選取前個傅立葉變換係數近似):低階係數表示的是邊界的大致形狀,高階係數表示的是邊界的細節特徵。傅立葉描述子在描述邊界時,對旋轉、平移、尺度變化等均不敏感。#coding=utf-8import cv2import numpy as np#直接讀為灰度圖像img = cv2.imread('fuliye.png', 0)f = np.fft.fft2(img)fshift = np.fft.fftshift(f)#先取絕對值,表示取模。再取對數,將數據範圍變小magnitude_spectrum = 20*np.log(np.abs(fshift))
cv2.imwrite("original.jpg", img)cv2.imwrite("center.jpg", magnitude_spectrum)形狀不變矩法的主要思想是將對變換不敏感的、基於區域的幾何矩特徵作為形狀特徵。之所以稱之為「不變矩」,是因為矩特徵在旋轉、平移、尺度縮放的環境下都不會發生改變。對於二維連續函數階矩的定義如下:上式中的和可以取所有的自然數,所以上式構建了一個矩的集合,且集合與函數具有唯一性。為了更方便地描述物體的形狀,我們假設函數是一個二值函數,即該函數在目標物體上的取值為1,在背景上的取值為0。不區分目標物體內部的灰度,參數稱為矩的階。特別地,當時,得到零階矩。零階矩的幾何意義是表示物體的面積,即:根據歸一化之後的中心矩,對旋轉、平移、尺度等都不敏感的七個不變矩。下面我們對同一幅圖像,分別進行尺度縮小為原始圖像的一半、逆時針旋轉5度操作以及垂直鏡像變換的操作,分別求出原始圖像及變換後的各個圖像的七階矩。可以得出,這七階矩的值對於尺度、旋轉及鏡像變換不敏感。程序代碼如下:import cv2from datetime import datetimeimport numpy as npnp.set_printoptions(suppress=True)
def my_humoments(img_gray): moments = cv2.moments(img_gray) humoments = cv2.HuMoments(moments) #取對數 humoments = np.log(np.abs(humoments)) print(humoments) if __name__ == '__main__': t1 = datetime.now() fp = 'lena.jpg' img = cv2.imread(fp) #縮放 h,w,_ = img.shape img = cv2.resize(img, (h/2, w/2), cv2.INTER_LINEAR) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imwrite("scale.jpg",img_gray) #旋轉 (h, w) = img.shape[:2] center = (w // 2, h // 2) M = cv2.getRotationMatrix2D(center, 5, 1.0) img = cv2.warpAffine(img, M, (w, h)) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imwrite("rotate.jpg", img_gray) #垂直鏡像 img = cv2.flip(img, 0, dst=None) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imwrite("flip.jpg",img_gray) my_humoments(img_gray)幾何參數法主要包括像素與鄰域、位置、方向、距離、區域周長和區域面積。一幅圖像中,位於坐標處的像素有4個相鄰的像素,分別位於其上下左右,坐標分別為,如下圖所示。有時我們不僅需要某個像素點周圍4個像素的值,而且需要其周圍8個像素的值,此時8個點的坐標分別為,如下圖所示。目標在圖片中的位置有兩種表達方式,一種叫質心即目標質量的中心,另一種叫形心即目標形狀的中心。對於一個大小的目標,假設其灰度值大小為,則質心公式如下:像圓形這樣的圖形,很難定義它的方向。一般地,我們在定義方向的時候,為了保證唯一性,事先假定物體的形狀是長方形,它的長邊即物體的方向。在圖像處理領域,常用的距離公式包括歐幾裡得距離、4鄰域距離以及8鄰域距離。假設兩個點的坐標分別為,則AB兩點之間的距離公式如下:區域的周長可以用區域邊界所佔的面積表示,可以認為是邊界的像素點數量。如果將像素看成是一個個單獨的點,那麼區域的周長就可以認為是區域的邊界8鏈碼的長度。如果將像素看成是圖像中一個個單位面積的小方格,那麼可認為區域和背景都是由方格組成的。區域的周長就可以定義為區域和背景的交界線的長度。對於二值圖來說,區域的面積可以簡單地定義為目標物所佔像素點的數量,即區域的邊界內包含的像素點的個數。區域面積的計算公式如下:基於幾何分布的特徵提取方法大致可以分為兩類,一類是二維直方圖投影法,另一類區域網格統計法。幾何分布特徵提取方法的代表之一就是二維直方圖投影法,也就是獲取水平以及豎直方向上各行、列黑色像素累計分布的結果,如下圖所示。由於圖片經過歸一化後,長寬相對固定,例如32×36像素的二值字符「3」如下圖左所示。一般二維直方圖投影法對圖像的掃描順序為從上到下、從左往右,所以得到的對應數字矩陣如下圖右所示。在水平方向和豎直方向分別對原圖進行投影,然後分別按照行列方向統計黑色像素的值且進行歸一化,最終得到特徵向量。以圖3-24a的二值字符「3」為例,可以得到68維的特徵向量值,如下表所示。區域網格統計法是另一種常見的基於幾何分布的特徵提取方法。其主要思想是先利用一個的網格將原圖進行分割,然後按從上至下、從左至右的順序依次統計每一個網格中「1」的個數,從而得到最終的特徵向量。以上面的二值字符「3」為例,我們用一個3×4的網格對其進行分割,得到的結果如下圖所示。本文摘編自劉樹春的《深度實踐OCR:基於深度學習的文字識別》,經出版方授權發布。作者劉樹春是阿里巴巴本地生活研究院算法專家,前復旦七牛雲聯合實驗室OCR算法負責人。本書系統地介紹了文字識別的各類方法,包括圖像預處理、數據生成與增強、文字檢測、文字識別以及後處理和結構化等內容,內容翔實,推薦閱讀!