基于python-opencv的HOG特征提取和使用cv2.HOGDescriptor()
本次模式识别课程要求实现路标检测,训练集只给了5个样本,测试集有50个样本,听说HOG特征+特征匹配就能达到很好的效果,因此采用了这种方法。
在python-opencv里,有定义了一个类cv2.HOGDescriptor,使用这个类就可以直接提取图片的HOG特征。图片没有要求,3通道和单通道的我试一下结果一样。
网上关于这个类的介绍很少,翻了好多内容才找到了一部分。首先来看一下如何直接使用构造函数来定义一个hog对象,下面就是定义的方法,里面的参数稍微看一下(常用的就前面几个,后面的默认就行,在opencv教材里全部用的默认参数)
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins,derivAperture,winSigma,histogramNormType,L2HysThreshold,gammaCorrection,nlevels)
常用的是winSize, blockSize, blockStride, cellSize, nbins这四个,分别是窗口大小(单位:像素)、block大小(单位:像素)、block步长(单位:像素)、cell大小(单位:像素)、bin的取值
这些的概念建议找一个HOG教程自己看一下就行,我们用的时候就自己规定这几个参数就差不多了(用默认的也可以,但是效果可能不好,毕竟这个特征描述子很看参数设置的,可以更换几组参数多试试)
贴一下我自己用的时候的过程:
import numpy as np
import cv2img = cv2.imread(test)#在这里设置参数
winSize = (128,128)
blockSize = (64,64)
blockStride = (8,8)
cellSize = (16,16)
nbins = 9#定义对象hog,同时输入定义的参数,剩下的默认即可
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins)
定义完HOG描述子对象hog之后,就能拿来计算图像的HOG特征了,它封装的太好以至于用着非常简单无脑,直接用这个类中的成员函数compute就能求得一个图片的HOG特征描述子,它的返回值一个拼接好的n*1维的特征向量(应该就是把许多个特征向量横向拼接起来了,具体的n要看你设置的参数和窗口、block的步长),数据结构是Numpy-nparray类型,利用numpy也非常方便处理,使用过程如下
compute常用的参数有3个,第一个是必须的参数,就是图片(用opencv读取的numpy-nparray,经测试3通道BGR或者单通道灰度图都可以,而且结果也一样)数据结构。第二个是winStride,是窗口滑动步长(影响最终n的大小)。第三个是padding,填充,就是在外面填充点来处理边界。
然后就开始使用compute来计算HOG特征描述子
winStride = (8,8)
padding = (8,8)
test_hog = hog.compute(img, winStride, padding).reshape((-1,))
这里我就得到了HOG描述子,一个n*1的矩阵(numpy-nparray),这样HOG描述子就提取出来了,剩下就随心所欲了,这就是用python-opencv来实现提取HOG描述子
对于上述的路标问题我就是提取每个图片的HOG描述子,然后相互求内积,内积大的就说明两者最相近。
下面是我自己用python实现的HOG特征提取,主要是思路和梯度计算部分需要想明白,别的都很简单。
提取流程
梯度计算
归一化
提取单通道、三通道HOG特征,完成路标识别代码如下:
import numpy as np
import cv2
import os
import math
from sklearn.preprocessing import normalizeeps = 0.000001#灰度图提取HOG
def getHOG_1dims(pic_name):img = cv2.imread(pic_name,cv2.IMREAD_GRAYSCALE)img = img/255img = cv2.resize(img,(207,194))g_img = np.zeros((img.shape[0],img.shape[1],2))for i in range(1,img.shape[0]-1):for j in range(1,img.shape[1]-1):gx = img[i+1,j] - img[i-1,j]gy = img[i,j+1] - img[i,j-1]g = (gx**2 + gy**2)**0.5if gx == 0 and gy == 0:dg = 0elif gx == 0 and gy != 0:dg = math.pi/2else:dg = math.atan(gy/gx) if dg < 0:dg = dg + math.piif dg == math.pi:dg = 0g_img[i,j,0] = gg_img[i,j,1] = dg cell_n = np.zeros((9))#cell hh = img.shape[0]//16#cell ww = img.shape[1]//16#cell size per hh_size = 16#cell size per ww_size = 16cell = np.zeros((h,w,9)) for m in range(h):for n in range(w):for i in range(h_size*m,h_size*(m+1)):for j in range(w_size*n,w_size*(n+1)):cell_n[int(g_img[i,j,1]//(math.pi/9))] += g_img[i,j,0]cell[m,n] = cell_nblock = np.zeros((h//2,w//2,9))for p in range(h//2):for q in range(w//2):for i in range(2*p,2*p+2):for j in range(2*q,2*q+2):block[p,q] += cell[i,j]block_norm = np.zeros((h//2,w//2,9))for i in range(h//2):for j in range(w//2):length = (np.linalg.norm(block[i,j])**2 + 0.000001)**0.5block_norm[i,j] = block[i,j]/lengthblock_norm = block_norm.reshape(block_norm.shape[0]*block_norm.shape[1],9)return block_norm #RGB提取HOG
def getHOG_3dims(pic_name):img = cv2.imread(pic_name)img = cv2.resize(img,(192,192))#img = cv2.imread('xxx.jpg')#cv2.imshow('result',img)#key = cv2.waitKey()#print(img.shape[0])#if key & 0xff == ord('q'):# cv2.destroyAllWindows()#gamma归一化 gamma取1img = img/255#用1阶微分算子计算图像梯度g_img = np.zeros((img.shape[0],img.shape[1],3,2))for i in range(1,img.shape[0]-1):for j in range(1,img.shape[1]-1):gx_b = img[i+1,j,0] - img[i-1,j,0]gy_b = img[i,j+1,0] - img[i,j-1,0]gx_g = img[i+1,j,1] - img[i-1,j,1]gy_g = img[i,j+1,1] - img[i,j-1,1]gx_r = img[i+1,j,2] - img[i-1,j,2]gy_r = img[i,j+1,2] - img[i,j-1,2]gb = (gx_b**2 + gy_b**2)**0.5gg = (gx_g**2 + gy_g**2)**0.5gr = (gx_r**2 + gy_r**2)**0.5if gx_b == 0 and gy_b == 0:dgb = 0elif gx_b == 0 and gy_b != 0:dgb = math.pi/2else:dgb = math.atan(gy_b/gx_b) if dgb < 0:dgb = dgb + math.piif gx_g == 0 and gy_g == 0:dgg = 0elif gx_g == 0 and gy_g != 0:dgg = math.pi/2else:dgg = math.atan(gy_g/gx_g) if dgg < 0:dgg = dgg + math.piif gx_r == 0 and gy_r == 0:dgr = 0elif gx_r == 0 and gy_r != 0:dgr = math.pi/2else:dgr = math.atan(gy_r/gx_r)if dgr < 0:dgr = dgr + math.pig_img[i,j,0,0] = gbg_img[i,j,1,0] = ggg_img[i,j,2,0] = grg_img[i,j,0,1] = dgbg_img[i,j,1,1] = dggg_img[i,j,2,1] = dgr #计算cell的梯度直方图向量,其中每个cell包含8*8个像素,每个block包含16*16个像素,即2*2个cellcell_n = np.zeros((3,9))#cell hh = 24#cell ww = 24#cell size per hh_size = img.shape[0]//24#cell size per ww_size = img.shape[1]//24cell = np.zeros((h,w,27))for m in range(h):for n in range(w):for i in range(h_size*m,h_size*(m+1)):for j in range(w_size*n,w_size*(n+1)):for k in range(3):cell_n[k,int(g_img[i,j,k,1]//(math.pi/9))] += g_img[i,j,k,0]cell[m,n] = cell_n.reshape(27)block = np.zeros((h//2,w//2,27))for p in range(h//2):for q in range(w//2):for i in range(2*p,2*p+2):for j in range(2*q,2*q+2):block[p,q] += cell[i,j]block_norm = np.zeros((h//2,w//2,27))for i in range(h//2):for j in range(w//2):length = (np.linalg.norm(block[i,j])**2 + 0.000001)**0.5block_norm[i,j] = block[i,j]/lengthblock_norm = block_norm.reshape(block_norm.shape[0]*block_norm.shape[1],27)return block_normdef judge(test):global traintest_hog = getHOG_1dims(test)temp = 0result = 0for i in range(5):matrix = np.dot(test_hog,train[i].T)num_sum = 0for j in range(36):
# for k in range(16):num_sum += matrix[j,j]if num_sum > temp:temp = num_sumresult = i+1return resultif __name__ == '__main__':train_1 = getHOG_1dims('xxx/1.jpg')train_2 = getHOG_1dims('/xxx/2.jpg')train_3 = getHOG_1dims('/xxx/3.jpg')train_4 = getHOG_1dims('/xxx/4.jpg')train_5 = getHOG_1dims('/xxx/5.jpg')train = [train_1,train_2,train_3,train_4,train_5]path = '/xxx/test/'path_list = os.listdir(path)path_list.sort(key=lambda x: int(x[:-4]))count = 0for filename in path_list:result_1 = judge(path + filename)print(result_1)if (int(filename[:-4])-1)//10 + 1 == result_1:count += 1print("accquracy is :" + str(count/50))
基于python-opencv的HOG特征提取和使用cv2.HOGDescriptor()相关推荐
- 基于python+OpenCV的车牌号码识别
基于python+OpenCV的车牌号码识别 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分: ...
- 基于python opencv人脸识别的签到系统
基于python opencv人脸识别的签到系统 前言 先看下效果 实现的功能 开始准备 页面的构建 功能实现 代码部分 总结 前言 一个基于opencv人脸识别和TensorFlow进行模型训练的人 ...
- 基于Python+OpenCV车道线检测(直道和弯道)
基于Python+OpenCV车道线检测(直道和弯道) 基于Python+OpenCV车道线检测(直道和弯道)
- 【开源分享】基于Python+OpenCV+PyQt5车牌识别(GUI界面)
亲测无错:基于Python+OpenCV+PyQt5车牌识别(GUI界面)绝对可以用的!!!!! 基于Python+OpenCV+PyQt5车牌识别(GUI界面) 参考文档
- 基于python+opencv的图像目标区域自动提取
向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程 公众号:datayx 一.提取纸张中的内容 一张照片中的感兴趣区域总是沿着x,y,z三个轴都有一定倾斜(如下图),要 ...
- 基于Python+OpenCV的图像搜索引擎(CBIR+深度学习+机器视觉)含全部工程源码及图片数据库下载资源
目录 前言 总体设计 系统整体结构图 系统流程图 运行环境 模块实现 1. 数据预处理 2. 定义图像描述符 3. 索引化数据集 4. 设计搜索引擎内核 5. 执行搜索 系统测试 1. 处理数据集 2 ...
- 基于python+openCV的中值滤波
先直接来一个3×3的吧 def median(src_img, filter_size, channels):# 首先,定义一个大小为9的0数组# list = [[0, 0, 0, 0, 0, 0, ...
- 机器学习水果识别——python+opencv实现物体特征提取
文章目录 一.用python+opencv实现物体特征值提取 1.读取图像.转为灰度图像并降噪 2.获取水果轮廓 将最大轮廓画入最开始的img图像并显示 将小于某一规模的轮廓删除 3.提取水果的面积周 ...
- 基于python+opencv+pyautogui的图像识别点击
第一次发文没啥经验 很多都是借鉴若有侵权请告知 必更改 开源代码只供学习交流请勿用作其他用途!!! get_img()#这个函数是获取rgb格式屏幕截图,可用于截图一次识别多个元素 imgclick( ...
最新文章
- 麻省理工牛人解说数学体系
- Android中取消系统标题栏的几种方式
- 2020年前端招聘技术概览
- JEECG开源社区招收学生说明
- Windows vpn 远程桌面 使用快捷键
- Unity中UI界面颤抖解决方法
- 怎么checkout一个gerrit提交,完事之后再push
- ThinkPHP中使用聚合查询去重求和
- 香草 jboss 工具_使用Tensorflow创建香草神经网络
- 抓包——HTTP分析
- WEB安全 asp+access注入
- 光棍.com市场推广策划书(爆笑)
- 转:高级软件工程师成长秘诀(文末有笔者自己的小评论)
- 新媒体内容运营的7个核心环节
- 2023软件测试面试全方位话术,你想要的全都有
- 重新思考 视频超分辨 Transformers 中的对齐
- 3D全景图,全景视频,陀螺仪
- NetApp运维使用手册
- 富文本编辑器处理过的字符串部分字符正则捕获不到,含有不可见字符\u200B
- python机器学习相关的操作 numpy,GridSearchCV(网格搜索)等