
哈尔(Haar)特征是什么?
哈尔特征是一种反应图像灰度变化的一种特征。它分为四类:边缘特征、线性特征、中心特征和对角特征。
哈尔特征值的表示
用黑和白两种矩形框组合成特征模板,在特征模板内用权重乘以黑色框内的像素和,减去用权重乘以白色框内的像素和。这个差值就表示为这个区域内图像的哈尔特征值。
不同的哈尔特征模板
哈尔特征使用不同的模板来提取特征:边缘特征、线性特征、对角特征和中心特征。通过改变特征模板的大小和位置,可以在图像窗口中穷举出大量的特征。
计算哈尔特征值时。如果白色区域大于黑色区域,黑色区域乘上更大的权重。
哈尔特征提取的具体步骤
步骤:用一个矩阵扫描图像,缩放矩阵大小再次扫描图像,使用不同的矩阵来扫描图像。将得到的所有哈尔特征值连成特征向量。
用一个矩阵扫描图像
先用一个矩阵从左上角开始,从左向右,,自上到下,经过特征值的计算得到该图像在该哈尔特征下的特征向量。扫描过程中需要设定步长和矩阵大小。该过程类似于池化核池化。
假设图像大小为100*100,矩阵大小为10*10,步长为10,那么在该特征矩阵下的哈尔特征向量为1*100。
缩放矩阵大小再次扫描图像
为了保证图像的大小不变性(当图像尺寸大小变化时特征仍能被正常提取)在提取哈尔特征时,都需要将其进行缩放,如果原大小为10*10的矩阵进行10次缩放,每次放大都得重新扫描一次图像,一共可以得到是个特征向量。
使用不同的矩阵来扫描图像
我们通常进行特征提取的过程中,往往图像包含的不止只有一种哈尔特征,所以需要用更多的特征矩阵来完成对图像的扫描。通常需要更得的哈尔特征矩阵来分别提取图像的特征。如边缘特征,线性特征、对角特征、对角特征
将得到的所有哈尔特征值连成特征向量
在得到各类型和大小扫描后得到的特征向量后,我们需要将这些特征向量连接在一起,交给算法模型使计算机能够识别该图像。便于接来算法模型的学习训练。
流程示意图(来源于华为人才在线)

哈尔特征的特点
什么是图像不变性
图像不变性是指图像经过移动,缩放,改变亮度,都能被特征提取方法识别为同一形状,这一特点就是图像不变性。当然特征提取算法同样需要具有图像不变性。
优点
计算量相对来讲小,只有加减运算,提取特征速度很快。
具有移动不变性。
使用不同大小的特征矩阵进行扫描使哈尔特征具有一定的尺寸不变性。
使用不同角度的特征矩阵进行扫描使哈尔特征具有一定的旋转不变性。
缺点(局限性)
当矩阵大小变大后计算量也会增加
不具有光照不变性(当局部光照增大时,黑白框两侧的权重乘以像素和的差值绝对值会减小,使得特征提取出现问题)
改进哈尔特征的方法
积分图
在计算哈尔特征时,当特征矩阵很大很大时,计算量就会变得很大很大。为了减少计算量,P.Viola,M.Jones等人提出了积分图的概念。
啥是积分图呢,理解起来也很简单,就是将各像素的灰度值累积起来将其放入一个新的积分图里。积分图的长和宽与原图像一致,积分图某一点(x,y)的值等于这个点(x,y)在原图像包含的所有的像素灰度值的累积加和。当使用特征矩阵进行计算是可以直接使用积分图进行计算,不需要重新累加向量和,从而加快了计算。
积分图示例
积分图的计算

图像归一化
当图像的亮度发生变化时,使用哈尔特征会出现丢失特征的问题,这是因为哈尔特征算法不具有光照不变性。当光照发生变化时,像素的权重乘像素和的差值绝对值会发生变化,导致特征丢失。为了解决该问题,我们可以将原图像进行归一化处理,即将像素灰度的值域从[0~255]映射到[0~1]以减缓亮度对权重乘像素和的差值绝对值的影响。
哈尔特征的代码实现(含积分图)
计算积分图:
def integral(img):
integ_graph = np.zeros((img.shape[0],img.shape[1]),dtype = np.int32)
#创建尺寸大小与原图相同的零矩阵,便于将计算完的积分放入积分图
for x in range(img.shape[0]):
#先遍历行
sum_clo = 0
#上一列积分累加值
for y in range(img.shape[1]):
sum_clo = sum_clo + img[x][y]
integ_graph[x][y] = integ_graph[x-1][y] + sum_clo;
return integ_graph
获取积分图坐标(便于计算特征向量值)
def getHaarFeaturesArea(width,height):
widthLimit = width-1
heightLimit = height/2-1
#定义哈尔特征大小限制
features = []
#初始化坐标
for w in range(1,int(widthLimit)):
#先一个特征矩阵对原图进行扫描
for h in range(1,int(heightLimit)):
wMoveLimit = width - w
hMoveLimit = height - 2*h
for x in range(0, wMoveLimit):
for y in range(0, hMoveLimit):
#哈尔矩阵的运动(开始扫描)
features.append([x, y, w, h])
#合并坐标
return features
哈尔特征值的计算
def calHaarFeatures(integral_graph,features_graph,minmum):
haarFeatures = []
for num in range(len(features_graph)):
#计算左面的矩形区局的像素和
haar1 = integral_graph[features_graph[num][0]][features_graph[num][1]]-\
integral_graph[features_graph[num][0]+features_graph[num][2]][features_graph[num][1]] -\
integral_graph[features_graph[num][0]][features_graph[num][1]+features_graph[num][3]] +\
integral_graph[features_graph[num][0]+features_graph[num][2]][features_graph[num][1]+features_graph[num][3]]
#计算右面的矩形区域的像素和
haar2 = integral_graph[features_graph[num][0]][features_graph[num][1]+features_graph[num][3]]-\
integral_graph[features_graph[num][0]+features_graph[num][2]][features_graph[num][1]+features_graph[num][3]] -\
integral_graph[features_graph[num][0]][features_graph[num][1]+2*features_graph[num][3]] +\
integral_graph[features_graph[num][0]+features_graph[num][2]][features_graph[num][1]+2*features_graph[num][3]]
#右面的像素和减去左面的像素和(设置阈值进行筛选)
if haar2-haar1>minmum:
haarFeatures.append(haar2-haar1)
return haarFeatures
感谢阅读:)
如有偏差请指正
1158

被折叠的 条评论
为什么被折叠?



