El código MATLAB implementa la extracción de características del histograma de gradiente direccional HOG

El primer paso: preprocesamiento de la imagen original: imagen en escala de grises, corrección de gamma

 Después de importar la imagen, conviértala en una imagen en escala de grises, filtre y corrija la imagen. Los métodos y parámetros utilizados para el filtrado y la corrección se seleccionan según la situación de la imagen.

Paso 2: Calcule el gradiente total y la dirección del gradiente de cada píxel

Utilice [-1,0,1] como operador en la dirección x; [-1;0;1] como operador en la dirección y ; el gradiente en la dirección x se almacena en f1(i,j); el El gradiente en la dirección y se almacena en f2(i,j). Calcule el gradiente total y la dirección del gradiente.

Gradiente total: rho(i,j)=((f1(i,j))^2+(f2(i,j)^2))^0.5

Dirección de elevación: theta(i,j)=(atan(f2(i,j)/f1(i,j)))*180/3.14

La imagen de Matlab es positiva de izquierda a derecha y de arriba a abajo. Después de calcular la dirección del gradiente, debe convertirse en un ángulo en el sistema de coordenadas plano rectangular. La dirección positiva del eje y es 0°. Cuando Al girar en el sentido de las agujas del reloj, el ángulo cambia de 0° a 360°. Es conveniente para estadísticas posteriores de histogramas de gradiente direccional.

Las coordenadas y los ángulos de la imagen en matlab se muestran en la siguiente figura:

Para facilitar las estadísticas posteriores de diferentes intervalos de ángulos, los ángulos en la figura anterior se pueden convertir en las coordenadas en la figura siguiente. En este ejemplo, 360 ° se divide en 6 intervalos con un intervalo de 60 °, y la dirección Se cuentan los histogramas de gradiente de los 6 intervalos (el método de división de ángulos y el intervalo de división se pueden seleccionar de forma diferente según las necesidades): 

Paso 3: establezca una celda como el área de imagen de cellx × celly. En este ejemplo, se toman 10 × 10 píxeles y se cuentan las características del histograma de 10 × 10 = 100 píxeles en 6 direcciones.

El tamaño de la imagen en este ejemplo es 300×400 píxeles, por lo que es necesario contar (300/10)×(400/10)=30×40=1200 celdas. Cada celda contiene 100 píxeles y cada punto contiene el gradiente total. ., información de la dirección del gradiente, divida estos 100 píxeles en 6 grupos de acuerdo con la dirección del gradiente y cuente el valor del gradiente acumulado total de cada grupo (después de contar, use un método apropiado para calcular el valor del gradiente total en las 6 direcciones de cada celda (. El valor de acumulación de gradiente se normaliza para obtener el valor característico de una celda. O no se realiza una acumulación simple durante las estadísticas y se utiliza el método de interpolación para acumular en cada dirección para obtener el valor característico de una celda).

(El tamaño de la celda se puede seleccionar según las necesidades reales).

Paso 4: Establezca 1 bloque en n × n celdas. En este ejemplo, 1 bloque tiene 3 × 3 celdas. Dado que cada celda contiene características de histograma en 6 direcciones, cada bloque contiene 9 × 6 = 54 características.

Los bloques se toman fila por fila y columna por columna, y cada celda ingresará bloques diferentes varias veces para realizar estadísticas. En este ejemplo, un bloque consta de 3 × 3 celdas. Se puede obtener un total de (30-2) × (40-2) = 1064 bloques. Cada celda contiene 6 valores de características, por lo que un bloque contiene 9 × 6=54 valores propios, produciendo en última instancia 1064 × 54 = 57456 valores propios. (Los 54 valores propios de cada bloque se pueden normalizar utilizando los métodos adecuados).

El programa de implementación de Matlab es el siguiente:

F=imread('D:\Desktop\matlab\13.png');

%第一步:原始图像预处理:灰度图、伽马矫正。
F=rgb2gray(F);
subplot(2,3,1),imshow(F);title('灰度图');

f=double(F);
[row,col]=size(f);
for i=1:row
    for j=1:col
         f(i,j)=(f(i,j))^0.5;                     %伽马矫正Gamma=1/2,
    end
end
subplot(2,3,2),imshow(f,[]);title('伽马矫正');

%第二步:计算各像素的总梯度、梯度方向
f1=zeros(row,col);           %f1用于存x方向梯度
f2=zeros(row,col);           %f2用于存y方向梯度
rho=zeros(row,col);          %rho用于存总方向梯度
theta=zeros(row,col);        %theta用于存梯度方向
gx=[-1,0,1];                 %计算x方向的算子,matlab图像左向右为正
gy=[-1;0;1];                 %计算x方向的算子,matlab图像上向下为正
for i=2:row-1
    for j=2:col-1
        fx=[f(i,j-1),f(i,j),f(i,j+1)];
        fy=[f(i-1,j);f(i,j);f(i+1,j)];
        Gx=gx.*fx;
        Gy=gy.*fy;
        f1(i,j)=sum(Gx,"all");                    %计算x方向梯度
        f2(i,j)=sum(Gy,"all");                    %计算y方向梯度
        rho(i,j)=((f1(i,j))^2+(f1(i,j)^2))^0.5;    %计算总梯度
        %下面计算梯度方向,matlab图像左向右为正,上向下为正,使用f2(i,j)/f1(i,j)计算方向后需要将其转换为平面直角坐标系中的角度
        %以y轴正方向为0°,顺时针旋转,角度由0°变化至360°。便于统计方向梯度直方图
        if f1(i,j)>0 && f2(i,j)<0                                          
             theta(i,j)=(atan(f2(i,j)/f1(i,j)))*180/3.14+90;                  %x方向梯度>0,y方向梯度<0,平面直角坐标系中的第一象限,转换为0°~90°范围
        end
        if f1(i,j)>0 && f2(i,j)>0 
             theta(i,j)=(atan(f2(i,j)/f1(i,j)))*180/3.14+90;                  %x方向梯度>0,y方向梯度>0,平面直角坐标系中的第四象限,转换为90°~180°范围
        end
        if f1(i,j)<0 && f2(i,j)>0 
             theta(i,j)=(atan(f2(i,j)/f1(i,j)))*180/3.14+270;                 %x方向梯度<0,y方向梯度>0,平面直角坐标系中的第三象限,转换为180°~270°范围
        end
        if f1(i,j)<0 && f2(i,j)<0 
             theta(i,j)=(atan(f2(i,j)/f1(i,j)))*180/3.14+270;                 %x方向梯度<0,y方向梯度<0,平面直角坐标系中的第二象限,转换为270°~360°范围
        end
        if f1(i,j)==0 && f2(i,j)<0 
             theta(i,j)=0.00001;                                              %x方向梯度=0,y方向梯度<0,平面直角坐标系中的y轴正方向,转换为0°,为了和无梯度方向(f2(i,j)、f1(i,j)均为0的情况)区别开,设该方向为极小的正值
        end
        if f1(i,j)>0 && f2(i,j)==0 
             theta(i,j)=90;                                                   %x方向梯度>0,y方向梯度=0,平面直角坐标系中的x轴正方向,转换为90°
        end
        if f1(i,j)==0 && f2(i,j)>0 
             theta(i,j)=180;                                                  %x方向梯度=0,y方向梯度>0,平面直角坐标系中的y轴负方向,转换为180°
        end
        if f1(i,j)<0 && f2(i,j)==0 
             theta(i,j)=270;                                                  %x方向梯度<0,y方向梯度=0,平面直角坐标系中的x轴负方向,转换为270°
        end
        if f1(i,j)==0 && f2(i,j)==0 
             theta(i,j)=0;                                                    %f2(i,j)、f1(i,j)均为0,无梯度方向
        end
     end
end
subplot(2,3,3),imshow(f1,[]);title('x方向梯度');
subplot(2,3,4),imshow(f2,[]);title('y方向梯度');
subplot(2,3,5),imshow(rho,[]);title('总梯度');
subplot(2,3,6),imshow(theta,[]);title('梯度方向');

%第三步:设置1个cell为cellx×celly的图片区域,该例中取10×10个像素,统计10×10=100个像素6个方向上的直方图特征.
       % 需要统计(300/10)×(400/10)=30×40=1200个cell
theta_num=6;                    %设置统计6个方向的直方图特征(也可设置为统计9个或其他n个方向)
cellx=10;                       %设置1个cell有几行像素               
celly=10;                       %设置1个cell有几列像素
theta_size=360/theta_num;       %统计6个方向上的直方图,每个方向60°

cell_rho=zeros(cellx,celly);    %创建cell_rho矩阵,用来放1个cell中各像素的总梯度
cell_theta=zeros(cellx,celly);  %创建cell_theta矩阵,用来放1个cell中各像素的梯度方向
histogram=zeros(1,theta_num);   %创建histogram数组,用来放1个cell中的6个统计直方图特征
Cell=cell(row/cellx,col/celly); %定义元胞数组大小,用于存放所有cell中的6个直方图特征

for x=1:row/cellx                                                          %需要确定图片尺寸的行数可被整除,即可得到图片可分为几行cell
    for y=1:col/celly                                                      %需要确定图片尺寸的列数可被整除,即可得到图片可分为几列cell
         cell_rho=rho(10*x-9:10*x,10*y-9:10*y);                            
         cell_theta=theta(10*x-9:10*x,10*y-9:10*y);                        %把每个cell中的总梯度、梯度方向放入矩阵cell_rho、cell_theta中,便于后面统计
                          
             for i=1:cellx
                  for j=1:celly
                      if cell_theta(i,j)>0
                      histogram(ceil(cell_theta(i,j)/theta_size))=histogram(ceil(cell_theta(i,j)/theta_size))+cell_rho(i,j); %统计10×10像素中各6个方向的直方图特征,放入histogram这个1×6的数组中
                      end
                  end
             end
             s=sum(histogram,"all");
             for h=1:theta_num
                 histogram(h)=histogram(h)/s;     %归一化
             end
             figure(2),plot(histogram);
             Cell{x,y}=histogram;                 %将归一化后的histogram(1×6)放入元胞数组中
             for h=1:theta_num
                 histogram(h)=0;                  %将histogram各元素置0,为下一个cell统计做好准备
             end
             
             histogram=zeros(1,6);
    end
end

%第四步:设置1个block为n×n个cell,该例中取1个block为3×3个cell,因每个cell中包含6个方向的直方图特征,则每个block包含9×6=54个特征.
       % 逐行、逐列取block,一共可取得(30-2)×(40-2)=1064个block,最终产生1064×6=6384个特征值
n=3;
[v,w]=size(Cell);
feature=cell(1,(v-(n-1))*(w-(n-1)));

for xx=1:v-2
    for yy=1:w-2
        feature{(xx-1)*(w-2)+yy}=[Cell{xx:xx+(n-1),yy:yy+(n-1)}];          %将3×3个cell的特征向量合并放入1个block中,作为1个block的特征
    end
end
%feature包含整图1064个block中所有的特征值

l=length(feature);
fmesh=[];
for i=1:l
    fmesh=[fmesh;feature{i}(:)'];            %用于画图
end
figure(3);
mesh(fmesh);

La siguiente imagen muestra los resultados de completar el primer y segundo paso:

La siguiente figura muestra los valores propios de 1 celda en 6 direcciones después de completar el tercer paso:

La siguiente figura muestra los resultados de visualización de cada valor de característica de bloque, es decir, el valor de característica HOG extraído de esta imagen:

Si necesita poder identificar imágenes como automóviles, necesita otros métodos de entrenamiento y métodos de detección. Este ejemplo solo presenta brevemente el proceso de extracción de valores de características de HOG. Hay muchos lugares donde necesita seleccionar parámetros y métodos en función de la situación real. situación.

Este ejemplo hace referencia a lo siguiente:

Principio de extracción de características de HOG_blog de Shen Ziheng-blog CSDN

Histograma de gradiente direccional de MATLAB HOG: un vaso de sake invita a la luna brillante - Blog Garden (cnblogs.com)

[Reconocimiento facial] Extraiga el reconocimiento facial basado en las características de matlab HOG [incluido el código fuente de Matlab 641]_matlab extrae características de hog_Blog de Poseidon Light-Blog CSDN

Supongo que te gusta

Origin blog.csdn.net/weixin_56832351/article/details/129439271
Recomendado
Clasificación