『壹』 圖像的特徵提取都有哪些演算法
圖像的經典特徵提取方法:
1 HOG(histogram of Oriented Gradient,方向梯度直方圖)
2 SIFT(Scale-invariant features transform,尺度不變特徵變換)
3 SURF(Speeded Up Robust Features,加速穩健特徵,對sift的改進)
4 DOG(Difference of Gaussian,高斯函數差分)
5 LBP(Local Binary Pattern,局部二值模式)
6 HAAR(haar-like ,haar類特徵,注意haar是個人名,haar這個人提出了一個用作濾波器的小波,為這個濾波器命名為haar濾波器,後來有人把這個濾波器用到了圖像上,就是圖像的haar特徵)
圖像的一般提取特徵方法:
1 灰度直方圖,顏色直方圖
2 均值,方差
3 信號處理類的方法:灰度共生矩陣,Tamura紋理特徵,自回歸紋理特徵,小波變換。
4 傅里葉形狀描述符,小波描述符等,
『貳』 紋理特徵提取方法:LBP, 灰度共生矩陣
搬運自本人 CSDN 博客: 《紋理特徵提取方法:LBP, 灰度共生矩陣》
註:本文中大量行內 Latex 公式在中不支持,如果想要仔細參閱,請移步上面的 CSDN 博客鏈接。
在前面的博文 《圖像紋理特徵總體簡述》 中,筆者總結了圖像紋理特徵及其分類。在這里筆者對其中兩種演算法介紹並總結。
參考網址:
《紋理特徵提取》
《【紋理特徵】LBP 》
《灰度共生矩陣(GLCM)理解》
《灰度共生矩陣的理解》
《圖像的紋理特徵之灰度共生矩陣 》
參考論文:
《基於灰度共生矩陣提取紋理特徵圖像的研究》——馮建輝
《灰度共生矩陣紋理特徵提取的Matlab實現》——焦蓬蓬
LBP方法(Local binary patterns, 局部二值模式)是一種用來描述圖像局部紋理特徵的運算元;它的作用是進行特徵提取,提取圖像的局部紋理特徵。
LBP是一個計算機視覺中用於圖像特徵分類的一個方法,用於紋理特徵提取。後來LBP方法與HOG特徵分類器與其他機器學習演算法聯合使用。
LBP演算法的核心思想,是以某個像素點為中心,與其鄰域像素點共同計算。關於鄰域像素點的選擇方法,其實並不唯一:
這里選擇環形鄰域的方法進行說明:
窗口中心的像素點作為中心,該像素點的像素值作為閾值。然後將周圍8個像素點的灰度值與該閾值進行比較,若周圍某像素值大於中心像素值,則該像素點位置被標記為1;反之,該像素點標記為0。
如此這樣,該窗口的8個點可以產生8位的無符號數,這樣就得到了該窗口的LBP值,該值反應了該窗口的紋理信息。如下圖所示:
圖中,中心像素點的像素值作為閾值,其值v = 3;周圍鄰域8個像素值中,有3個比閾值小的像素點置0,5個比閾值大的像素點置1。
LBP演算法的計算公式如下:
$$ LBP_{P, R}(x_{c},y_{c}) = sum_{p=0}^{P-1}s(g_{p} - g_{c})2^p, s(x)=left{egin{matrix}1 : x geq 0 0 : x leq 0 end{matrix} ight. $$
LBP紋理特徵向量,一般以圖像分塊LBP直方圖表示。具體步驟如下:
得到了整幅圖像的LBP紋理特徵後,便可以利用SVM或者其他機器學習演算法進行分類了。
這兩天筆者將會對源碼進行測試封裝,以後會上傳到我的GitHub網站上。
灰度共生矩陣法(GLCM, Gray-level co-occurrence matrix),就是通過計算灰度圖像得到它的共生矩陣,然後透過計算該共生矩陣得到矩陣的部分特徵值,來分別代表圖像的某些紋理特徵(紋理的定義仍是難點)。灰度共生矩陣能反映圖像灰度關於<font color = red> 方向、相鄰間隔、變化幅度等 </font>綜合信息,它是分析圖像的局部模式和它們排列規則的基礎。
對於灰度共生矩陣的理解,需要明確幾個概念:方向,偏移量和灰度共生矩陣的階數。
計算紋理特徵第一步,就是將多通道的圖像(一般指RGB圖像)轉換為灰度圖像,分別提取出多個通道的灰度圖像。
紋理特徵是一種結構特徵,使用不同通道圖像得到的紋理特徵都是一樣的,所以可以任意選擇其一。
一般在一幅圖像中的灰度級有256級,從0--255。但在計算灰度共生矩陣時我們並不需要256個灰度級,且計算量實在太大,所以一般分為8個灰度級或16個灰度級。
而且當分成8個灰度級時,如果直接將像素點的灰度值除以32取整,會引起影像清晰度降低,所以進行灰度級壓縮時,首先我們會將圖片進行直方圖均衡化處理,增加灰度值的動態范圍,這樣就增加了影像的整體對比效果。
註:筆者後文中的例子中,為了簡要說明,所以灰度等級簡單設置為4。
計算特徵值前,先選擇計算過程中的一些參數:
下面分部且適當的使用一些例子說明計算過程:
為了達到簡單說明計算紋理特徵值的目的,筆者此處做簡要的假設:灰度被分為4階,灰度階從0--3;窗口大小為6 × 6;
窗口A的灰度矩陣A如下:
窗口B的灰度矩陣B如下:
此處以左上角元素為坐標原點,原點記為(1, 1);以此為基礎舉例,第四行第二列的點記為(4, 2);
情景1:d = 1,求0°方向矩陣A的共生矩陣:
則按照0°方向(即水平方向 從左向右,從右向左兩個方向 ),統計矩陣值(1, 2),則如下圖所示:
$$
P_{A}(d=1, heta =0^o)=egin{vmatrix}
0 & 8 & 0 & 7
8 & 0 & 8 & 0
0 & 8 & 0 & 7
7 & 0 & 7 & 0
end{vmatrix}
$$
情景2:d = 1,求45°方向矩陣A的共生矩陣:
按照情景1,同理可得此時的統計矩陣結果如下:
$$
P_{A}(d=1, heta =45^o)=egin{vmatrix}
12 & 0 & 0 & 0
0 & 14 & 0 & 0
0 & 0 & 12 & 0
0 & 0 & 0 & 12
end{vmatrix}
$$
情景3:d = 1,求0°與45°方向矩陣B的共生矩陣:
與前面同理,可以得到矩陣B的統計及矩陣結果如下:
$$
P_{B}(d=1, heta =0^o)=egin{vmatrix}
24 & 4 & 0 & 0
4 & 8 & 0 & 0
0 & 0 & 12 & 2
0 & 0 & 2 & 4
end{vmatrix}
$$
$$
P_{B}(d=1, heta =45^o)=egin{vmatrix}
18 & 3 & 3 & 0
3 & 6 & 1 & 1
3 & 1 & 6 & 1
0 & 1 & 1 & 2
end{vmatrix}
$$
矩陣A, B的其餘90°、135°矩陣與上面同理,所以筆者偷懶略去。
這樣,我們就已經計算得到了單個窗口的灰度共生矩陣的各個方向的矩陣,下面就要用剛才算出的矩陣計算灰度共生矩陣特徵值。
用P表示灰度共生矩陣的歸一化頻率矩陣,其中i, j表示按照某方向同時出現於兩個像素的某兩個級別的灰度值,所以P(i, j)表示滿足這種情況的兩個像素出現的概率。
以上述情景2中的矩陣為例:
原矩陣為:
$$
P(d=1, heta =45^o)=egin{vmatrix}
12 & 0 & 0 & 0
0 & 14 & 0 & 0
0 & 0 & 12 & 0
0 & 0 & 0 & 12
end{vmatrix}
$$
歸一化後,矩陣形式變為:
$$
P(d=1, heta =45^o)=egin{vmatrix}
12/50 & 0 & 0 & 0
0 & 14/50 & 0 & 0
0 & 0 & 12/50 & 0
0 & 0 & 0 & 12/50
end{vmatrix}
$$
灰度共生矩陣理論的前輩Haralick等人用灰度共生矩陣提出了14中特徵值,但由於灰度共生矩陣的計算量很大,所以為了簡便,我們一般採用四個最常用的特徵來提取圖像的紋理特徵:<font color=red> 能量、對比度、相關度、熵 </font>。
$ ASM = sum_{i} sum_{j}P(i, j)^2 $
能量是灰度共生矩陣各元素的平方和,又被稱角二階距。它是圖像紋理灰度變化均一的度量,反映了圖像灰度分布均勻程度和紋理粗細程度。
$ CON = sum_{i} sum_{j} (i-j)^2 P(i,j) $
對比度是灰度共生矩陣主對角線附近的慣性矩,它體現矩陣的值如何分布,反映了圖像的清晰度和紋理溝紋的深淺。
$ CORRLN = [sum_{i} sum_{j}((ij)P(i,j)) - mu_{x} mu_{y}]/ sigma_{x} sigma_{y} $
相關度體現了空間灰度共生矩陣元素在行或列方向上的相似程度,反映了圖像局部灰度相關性。
$ ENT = - sum_{i} sum_{j} P(i,j) log P(i,j) $
熵體現了圖像紋理的隨機性。若共生矩陣中所有值都相等,取得最大值;若共生矩陣中的值不均勻,則其值會變得很小。
求出該灰度共生矩陣各個方向的特徵值後,再對這些特徵值進行均值和方差的計算,這樣處理就消除了方向分量對紋理特徵的影響。
一個滑動窗口計算結束後,該窗口就可以移動一個像素點,形成另一個小窗口圖像,重復進行上一步的計算,生成新窗口圖像的共生矩陣和紋理特徵值;
以此類推,滑動窗口遍歷完所有的圖像像素點後,整個圖像就形成了一個由紋理特徵值構成的一個紋理特徵值矩陣。
之後,就可以將這個紋理特徵值矩陣轉換成紋理特徵圖像。
筆者已經對源碼進行測試了封裝,並上傳到了筆者的GitHub網站上。
GitHub: https://github.com/upcAutoLang/GLCM-OpenCV
『叄』 matlab 中有提取圖像特徵點的函數嗎
本人恰巧正在做角點的提取與匹配,特徵點有很多種,看是基於區域還是邊緣,先是要檢測特徵點,這個主要是利用微分,然後再提取,貌似沒有現成的函數,這個給你參考一下,效果還可以
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Harris提取演算法
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc,clear all;
filename='camera2.bmp';
X= imread(filename); % 讀取圖像
Info=imfinfo(filename); %這個要習慣用
% f=rgb2gray(X);
f=X;
ori_im=double(f)/255; %unit8轉化為64為雙精度double64
fx = [-2 -1 0 1 2]; % x方向梯度運算元(用於Harris角點提取演算法)
Ix = filter2(fx,ori_im); % x方向濾波 善於使用filter
% fy = [5 8 5;0 0 0;-5 -8 -5]; % 高斯函數一階微分,y方向(用於改進的Harris角點提取演算法)
fy = [-2;-1;0;1;2]; % y方向梯度運算元(用於Harris角點提取演算法)
Iy = filter2(fy,ori_im); % y方向濾波
Ix2 = Ix.^2;
Iy2 = Iy.^2;
Ixy = Ix.*Iy;
clear Ix;
clear Iy; %消除變數哈
h= fspecial('gaussian',[10 10 ],2); % 產生7*7的高斯窗函數,sigma=2
Ix2 = filter2(h,Ix2);
Iy2 = filter2(h,Iy2);
Ixy = filter2(h,Ixy); %分別進行高斯濾波
height = size(ori_im,1);
width = size(ori_im,2);
result = zeros(height,width); % 紀錄角點位置,角點處值為1 ,背景都是黑色的哈
R = zeros(height,width);
Rmax = 0; % 圖像中最大的R值 以便設置門限
for i = 1:height
for j = 1:width
M = [Ix2(i,j) Ixy(i,j);Ixy(i,j) Iy2(i,j)]; %2*2的矩陣
R(i,j) = det(M)-0.06*(trace(M))^2; % 計算R ,求得RMAX,看來是整體求得的,角點響應函數
if R(i,j) > Rmax
Rmax = R(i,j);
end;
end;
end;
cnt = 0; %記錄點數的
for i = 2:height-1
for j = 2:width-1 % 進行非極大抑制,窗口3*3
if R(i,j) > 0.01*Rmax && R(i,j) > R(i-1,j-1) && R(i,j) > R(i-1,j) && R(i,j) > R(i-1,j+1) && R(i,j) > R(i,j-1) && R(i,j) > R(i,j+1) && R(i,j) > R(i+1,j-1) && R(i,j) > R(i+1,j) && R(i,j) > R(i+1,j+1)
result(i,j) = 1;
cnt = cnt+1;
end;
end;
end;
%
% i=1;
% for j=1:height
% for k=1:width
% if result(j,k)==1;
% corners1(i,1)=j;
% corners1(i,2)=k;
% i=i+1;
% end;
% end;
% end;
[posc, posr] = find(result == 1);
cnt % 角點個數
imshow(ori_im*255) %和 X的效果是一樣的
hold on;
plot(posr,posc,'g+');
『肆』 圖像特徵提取方法
特點:
1、局部特徵
2、對旋轉,縮放,亮度變化保持不變性
3、高速性
缺點:
1、局部特徵
2、對邊緣光滑的圖像難以准確提取特徵點
原理:
1、在尺度空間(例如高斯金字塔)上搜尋keypoints興趣點(對於尺度和旋轉不變)
2、篩選上一步獲得的興趣點
(1)對空間中的極值點進行精確定位
(2)用Hessian矩陣消除邊緣效應3、在選定的尺度下,在興趣點附近構造梯度方向直方圖
4、對直方圖進行統計,以此來描述此keypoints
總結:
這個方法是通過尋找通過高斯模糊來構造不同尺度下的高斯尺度空間金字塔,通過遍歷所有點,找出尺度空間中的極值點(與26個點進行比較,分別是這一層的周圍8個點,以及上下兩層的9個點)。在初步探查之後,通過對尺度空間下的DoG函數進行擬合,來確定keypoints的精確位置。DoG運算元的缺點是有較強的邊緣效應,在消除邊緣效應之後,得到的就是篩選後的精確keypoints。最後就是對找到的keypoints統計梯度方向直方圖,並將其向量化。
簡單來說,這個方法由於其旋轉及尺度不變性,主要被應用於圖片匹配的應用中。
參考鏈接1
參考鏈接2
原理:
1、圖片預處理:灰度化,亮度空間標准化
2、計算圖中每個像素的梯度
3、將圖像劃分成一個個cell
4、統計每個cell內的梯度直方圖
5、將每幾個cell組成一個block,將該block內的所有cell的的梯度特徵串起來組成該block內的HoG特徵
6、將整張圖內的所有block的HoG向量串起來組成此圖的HoG特徵向量(可歸一化)
總結:
這個方法通過設定不同大小的cell以及block作為參數,統計出整張圖像的梯度特徵(梯度可以反應物體的形狀,邊緣等特徵),通過cell以及block的形式去統計局部特徵。該方法配合SVM曾是圖像分類任務中最為常用的。
參考鏈接1
參考鏈接2
步驟:
1、確定cell大小
2、遍歷cell中的像素,將其周圍的8個像素與其相比較,若大於中心像素,則對應像素標記為1,否則為0
3、統計cell中的二值直方圖,全部串起來組成圖像的特徵向量
總結:
這個方法通過二值降維的方式,提取出了圖像的紋理特徵,並且有效的減少了高頻雜訊的影響。
參考鏈接
步驟:
1、構建Hessian矩陣,生成所有的邊緣點
2、構建尺度空間金字塔
3、keypoints定位,對第一步生成的所有邊緣點進行尺度空間中的極值篩選
4、進行SIFT中的精確定位
5、特徵點主方向選擇,與SIFT不同的是,SURF採用的是Harr演算法中的扇形統計
6、統計4*4cell中的梯度值,並整合成特徵向量
總結:
這個方法是SIFT的優化演算法,通過在第一步構造Hessian矩陣選出邊緣點作為第一批keypoints,減少了SIFT中所有點在尺度空間中的極值對比。同時,通過該用Harr的扇形統計並沿主方向統計特徵,使得每一個cell中的向量維度由原來的128降到了64 。
參考鏈接
『伍』 求matlab彩色圖片的顏色特徵提取演算法的代碼,和紋理特徵提取的代碼。傳統方法即可。
其實學數字圖像處理,關鍵的不是源代碼(和一般編程還是有區別的,這個是經驗之談,其實一般博導未必會編程,但是你和他說說你的方法,他一般都能切中要害),而是你能理解基於概念及適用場所。
基於顏色、紋理、形狀都屬於低層特徵,這些你理解就夠了,關鍵是對你的課題適合哪種方法來映射到高層語義上面,例如:識別物體輪廓,那可能形狀就比較適合等。
我之所以寫上面那段話,主要是我感覺你索取代碼也不說明具體要求,也就是方向不明確。
如今顏色特徵提取演算法有很多,諸如顏色直方圖、顏色矩、顏色集、顏色聚合向量、顏色相關圖等,既然你沒說,我就給個IEEE CSVT 2001的一篇關於顏色直方圖法的論文(源碼版權歸作者所有):
function colorhist = colorhist(rgb)
% CBIR_colorhist() --- color histogram calculation
% input: MxNx3 image data, in RGB
% output: 1x256 colorhistogram == (HxSxV = 16x4x4)
% as the MPEG-7 generic color histogram descriptor
% [Ref] Manjunath, B.S.; Ohm, J.-R.; Vasudevan, V.V.; Yamada, A., "Color and texture descriptors"
% IEEE Trans. CSVT, Volume: 11 Issue: 6 , Page(s): 703 -715, June 2001 (section III.B)
% check input
if size(rgb,3)~=3
error('3 components is needed for histogram');
end
% globals
H_BITS = 4; S_BITS = 2; V_BITS = 2;
%rgb2hsv可用rgb2hsi代替,見你以前的提問。
hsv = uint8(255*rgb2hsv(rgb));
imgsize = size(hsv);
% get rid of irrelevant boundaries
i0=round(0.05*imgsize(1)); i1=round(0.95*imgsize(1));
j0=round(0.05*imgsize(2)); j1=round(0.95*imgsize(2));
hsv = hsv(i0:i1, j0:j1, :);
% histogram
for i = 1 : 2^H_BITS
for j = 1 : 2^S_BITS
for k = 1 : 2^V_BITS
colorhist(i,j,k) = sum(sum( ...
bitshift(hsv(:,:,1),-(8-H_BITS))==i-1 &...
bitshift(hsv(:,:,2),-(8-S_BITS))==j-1 &...
bitshift(hsv(:,:,3),-(8-V_BITS))==k-1 ));
end
end
end
colorhist = reshape(colorhist, 1, 2^(H_BITS+S_BITS+V_BITS));
% normalize
colorhist = colorhist/sum(colorhist);
%基於紋理特徵提取灰度共生矩陣用於紋理判斷
% Calculates cooccurrence matrix
% for a given direction and distance
%
% out = cooccurrence (input, dir, dist, symmetric);
%
% INPUT:
% input: input matrix of any size
%
% dir: direction of evaluation
% "dir" value Angle
% 0 0
% 1 -45
% 2 -90
% 3 -135
% 4 -180
% 5 +135
% 6 +90
% 7 +45
%
% dist: distance between pixels
%
% symmetric: 1 for symmetric version
% 0 for non-symmetric version
%
% eg: out = cooccurrence (input, 0, 1, 1);
% Author: Baran Aydogan (15.07.2006)
% RGI, Tampere University of Technology
% [email protected]
function out = cooccurrence (input, dir, dist, symmetric);
input = round(input);
[r c] = size(input);
min_intensity = min(min(input));
max_intensity = max(max(input));
out = zeros(max_intensity-min_intensity+1);
if (dir == 0)
dir_x = 0; dir_y = 1;
end
if (dir == 1)
dir_x = 1; dir_y = 1;
end
if (dir == 2)
dir_x = 1; dir_y = 0;
end
if (dir == 3)
dir_x = 1; dir_y = -1;
end
if (dir == 4)
dir_x = 0; dir_y = -1;
end
if (dir == 5)
dir_x = -1; dir_y = -1;
end
if (dir == 6)
dir_x = -1; dir_y = 0;
end
if (dir == 7)
dir_x = -1; dir_y = 1;
end
dir_x = dir_x*dist;
dir_y = dir_y*dist;
out_ind_x = 0;
out_ind_y = 0;
for intensity1 = min_intensity:max_intensity
out_ind_x = out_ind_x + 1;
out_ind_y = 0;
[ind_x1 ind_y1] = find (input == intensity1);
ind_x1 = ind_x1 + dir_x;
ind_y1 = ind_y1 + dir_y;
for intensity2 = min_intensity:max_intensity
out_ind_y = out_ind_y + 1;
[ind_x2 ind_y2] = find (input == intensity2);
count = 0;
for i = 1:size(ind_x1,1)
for j = 1:size(ind_x2,1)
if ( (ind_x1(i) == ind_x2(j)) && (ind_y1(i) == ind_y2(j)) )
count = count + 1;
end
end
end
out(out_ind_x, out_ind_y) = count;
end
end
if (symmetric)
if (dir < 4)
dir = dir + 4;
else
dir = mod(dir,4);
end
out = out + cooccurrence (input, dir, dist, 0);
end