梯度直方图(HOG)用于图像多分类和图像推荐(下)

简介: 梯度直方图(HOG)用于图像多分类和图像推荐
  1. Normalize :以避免亮度、对比度或其他照明效果造成的影响。
  2. Filtering:考虑几个相邻像素,而不是单一像素值作为像素的真实值。高斯滤波对中心像素权重最大,对相邻像素权重按w、r、t递减,即根据窗口大小确定与中心像素的距离。

最后对滤波后的图像进行如下计算:

640.png

将整个图像分成若干块(b)。一个典型的块是上面提到的红框。此外,其他块可以看作是黑盒中提到的单元格(c)的集合。上图中,b的尺寸是8x8, c的尺寸是4x4

接下来,对于每个单元格,计算单元格中每个点的梯度大小和方向(为了简单起见,梯度大小可以简单地假设为Sobel导数或任意两个连续的x和y像素值之间的差)。然后形成大小为n的直方图,将梯度量级值从w.r.t梯度方向进行处理。最后根据规则对直方图进行归一化,形成一个n维向量。

对于一个单元格,我们得到一个n维向量。接下来的操作是通过向右移动50%重叠的图像块和向下移50%重叠的图像块来覆盖整个图像。

最后,将所有这些直方图串联起来,形成一个一维向量,称为HOG特征描述符。

HOG可以通过下面的代码段进行实现。

##HOGDescriptor#Returnsa1Dvectorforanimageppcr=8ppcc=8hog_images= []
hog_features= []
forimageintqdm(train_images):
blur=cv.GaussianBlur(image,(5,5),0) #GaussianFilteringfd,hog_image=hog(blur, orientations=8, pixels_per_cell=(ppcr,ppcc),cells_per_block=(2,2),block_norm=‘L2’,visualize=True)
hog_images.append(hog_image)
hog_features.append(fd)
hog_features=np.array(hog_features)
hog_features.shape

参数

对这个问题:-块大小为16x16

-单元格大小为8x8

这使得pixel_per_cell = (8x8)并且cells_per_block = (2x2)

-orientations(=8)是每个单元格的直方图容器的数量。在这8个容器中将放置16个梯度值,并将它们添加到每个容器中以表示该方向容器的梯度大小。当两个连续箱子之间的梯度分配发生冲突时,通常通过梯度插值来对梯度值进行投票。

-block_norm =“L1”。其他参数有L1归一化或L2-Hys(Hysteresis)。L2-Hys在某些情况下可以减少噪音。它使用l2 -范数来完成,然后将最大值限制为0.2,并使用l2 -范数来重新归一化。

#normalization by 'L2-Hys'

out=block/np.sqrt(np.sum(block**2) +eps**2)        
out=np.minimum(out, 0.2)        
out=out/np.sqrt(np.sum(out**2) +eps**2)

当实际图像形状为60x80,块大小为16x16时,总共将创建6x9 = 54个块(考虑到x,y中任意一步50%的重叠),而在每个块中我们将有4个单元格,每个单元格有8个直方图。因此,特征向量的长度为54x4x8 = 1728

下面是一些HOG图像的可视化表示:

640.png

在建模中使用梯度方向的想法是因为这种方法人类神经系统的工作方式相似。当人类看到某一物体时,大脑皮层会引起人们的注意,或者人类为了看得更清楚而改变观察的角度

由于是多分类问题,而且类内分布也不均匀,建议采用分层抽样。

X_train, X_test, y_train, y_test=train_test_split(hog_features,df_labels['class'],test_size=0.2,stratify=df_labels['class'])print('Training data and target sizes: \n{}, {}'.format(X_train.shape,y_train.shape))print('Test data and target sizes: \n{}, {}'.format(X_test.shape,y_test.shape))
=============================================Trainingdataandtargetsizes:
(15998, 1728), (15998,)
Testdataandtargetsizes:
(4000, 1728), (4000,)

最后,将数据使用分类器处理。针对该问题,分别采用了支持向量机、随机森林和KNN算法。在所有最近邻查找算法(ball_tree、kd_tree和brute force)中,KNN的表现都优于其他分类器。最后,使用“贪婪”搜索,因为它的计算速度比ball_tree和kd_tree快得多。

KNN分类器的代码片段

test_accuracy= []
scaler=StandardScaler()
X_scaled=scaler.fit_transform(X_train)classifier=KNeighborsClassifier(n_neighbors=3,algorithm='brute')
classifier.fit(X_scaled, y_train)
test_accuracy=classifier.score(scaler.transform(X_test), y_test)
print(test_accuracy)

在masterCategory中,主要包括以下五个类别:[“服饰”、“配饰”、“鞋履”、“个人护理”、“免费物品”]。所有属于其他类别的记录被命名为“其他”。

通过更改Jupyter笔记本中的列名,可以对任何列类型进行分类。

下面是一些有助于评估模型性能的数字。

640.png

list_of_categories=categories+['Others']print("Classification Report: \n Target: %s \n Labels: %s \n Classifier: %s:\n%s\n"% (target,list_of_categories,classifier, metrics.classification_report(y_test, y_pred)))df_report=pd.DataFrame(metrics.confusion_matrix(y_test, y_pred),columns=list_of_categories )
df_report.index= [list_of_categories]
df_report

640.png

最后,让我们对测试图像进行推断

#testimagewithidtest_data_location=root+'/test/'img=cv.imread(test_data_location+'1570.jpg',cv.IMREAD_GRAYSCALE) #loadatgrayscaleimage=cv.resize(img, (60, 80),interpolation=cv.INTER_LINEAR)ppcr=8ppcc=8hog_images_test= []
hog_features_test= []blur=cv.GaussianBlur(image,(5,5),0)
fd_test,hog_img=hog(blur, orientations=8, pixels_per_cell=(ppcr,ppcc),cells_per_block=(2,2),block_norm='L2',visualize=True)
hog_images_test.append(hog_img)
hog_features_test.append(fd)hog_features_test=np.array(hog_features_test)
y_pred_user=classifier.predict(scaler.transform(hog_features_test))
#print(plt.imshow(hog_images_test))
print(y_pred_user)
print("Predicted MaterCategory: ", mapper[mapper['class']==int(y_pred_user)]['masterCategory'])

一些建议!

scaler_global=MinMaxScaler()
final_features_scaled=scaler_global.fit_transform(hog_features)
neighbors=NearestNeighbors(n_neighbors=20, algorithm='brute')
neighbors.fit(final_features_scaled)distance,potential=neighbors.kneighbors(scaler_global.transform(hog_features_test))
print("Potential Neighbors Found!")
neighbors= []
foriinpotential[0]:
neighbors.append(i)recommendation_list=list(df_labels.iloc[neighbors]['id'])
recommendation_list

使用Flask分类值和推荐图像构建了一个简单的webservice (UI的开发不在本文讨论范围之内)。webservice看起来如下所示:

640.png

结论

本文首先说明了HOG背后的原理是什么,以及我们如何使用它来描述图像的特征。接下来,计算HOG特征并将其用于KNN分类器中,然后寻找K个最近邻点。这两个案例都在不使用任何深度学习方法的情况下达到了较高的准确率。在一些情况下,图像被错误地标记,或者图像有多个对象但被标记在一个类中,这会影响我们的模型。下一步是确定错误分类的根本原因,并制作一个更好的分类和推荐引擎。

目录
相关文章
|
5月前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
530 0
|
5月前
|
编解码 计算机视觉
图像金字塔
【6月更文挑战第4天】图像金字塔。
29 1
|
6月前
|
机器学习/深度学习 编解码 算法
SwinFIR:用快速傅里叶卷积重建SwinIR和改进的图像超分辨率训练
SwinFIR:用快速傅里叶卷积重建SwinIR和改进的图像超分辨率训练
204 1
|
6月前
|
编解码 Android开发 计算机视觉
多分辨率找图sift和直方图
牙叔教程 简单易懂
251 0
|
机器学习/深度学习 传感器 编解码
【图像重建】基于小波变换图像分解重建(PSNR对比)附matlab代码
【图像重建】基于小波变换图像分解重建(PSNR对比)附matlab代码
|
机器学习/深度学习 传感器 算法
【图像分割】基于局部空间信息直方图模糊聚类FGFCM 实现图像图像分割附matlab代码
【图像分割】基于局部空间信息直方图模糊聚类FGFCM 实现图像图像分割附matlab代码
|
机器学习/深度学习 传感器 算法
【图像重建】基于离散余弦变换DCT图像重建含MSE、PSNR、压缩比附matlab代码
【图像重建】基于离散余弦变换DCT图像重建含MSE、PSNR、压缩比附matlab代码
|
资源调度 算法 机器人
图像特征提取与描述_角点特征02:SIFT算法+SURF算法
前面两节我们介绍了Harris和Shi-Tomasi角点检测算法,这两种算法具有旋转不变性,但不具有尺度不变性,以下图为例,在左侧小图中可以检测到角点,但是图像被放大后,在使用同样的窗口,就检测不到角点了。
209 0
|
API 计算机视觉
opencv之直方图比较图像相似度
对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间 然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度进 而比较图像本身的相似程度。
451 0
opencv之直方图比较图像相似度