关于积分图和haar特征的相关概念请参考知乎:机器学习随笔 OpenCV AdaBoost + Haar目标检测技术内幕(上)
https://zhuanlan.zhihu.com/p/31427728
但是我是要用python代码实现,使出洪荒之力搜出HaarA的实现代码
链接如下:openCV之HAAR特征(代码实现)https://blog.csdn.net/weixin_37720172/article/details/77926585
基于小姐姐的代码,把其他三个基本的Haar特征代码实现。
Harr基本特征一共有四个,分别是边缘特征,中心特征,对角线特征。也就是下图对应的A,B,C,D
以下为分别使用HaarA,HaarB,HaarC,HaarD特征之后的图像效果。
HaarC的代码实现如下
def intergralMat(input = [],weight = 0 ,height = 0):
output = []
output.clear()
columnSum = [0 for i in range(weight)]
for i in range(height):
output.append([0 for x in range(weight)])
for j in range(weight):
if j == 0:
columnSum[j] = int(input[i][j])
else:
columnSum[j] = columnSum[j-1] + int(input[i][j])
if i == 0:
output[i][j] = columnSum[j]
else:
output[i][j] = output[i-1][j] + columnSum[j]
return output
def showimage(Haar_b,tmp):
dst = []
for x in range(len(Haar_b)):
dst.append([])
for y in range(len(Haar_b[0])):
if Haar_b[x][y] > 0:
dst[x].append(255)
else:
dst[x].append(0)
for x in range(len(dst)):
for y in range(len(dst[0])):
f = dst[x][y]
tmp[x, y] = [f, f, f]
return(tmp)
def myHaarC(interM = [],weigth = 0,height = 0,size = 1,deep = 3):
dst = []
for i in range(height - deep + 1):
dst.append([0 for x in range(weigth - size)])
for j in range(weigth - 3*size +1):
whithe,black = (0,0)
if j == 0 and i==0:
whithe = int(interM[i+deep-1][j+size-1])+int(interM[i+deep-1][j+3*size-1]) - int(interM[i+2][j+3*size-2])
elif i!=0 and j==0:
whithe = int(interM[i + deep - 1][j + size - 1]) - int(interM[i - 1][j+size -1])+ int(interM[i+deep-1][j+3*size-1]) + int(interM[i-1][j+3*size-2]) - int(interM[i+2][j+3*size-2]) - int(interM[i -1][j+ 3*size -1])
elif i == 0 and j != 0:
whithe = int(interM[i+deep-1][j+size-1]) - int(interM[i+deep-1][j-1])+int(interM[i+deep-1][j+3*size-1]) - int(interM[i+2][j+3*size-2])
else:
whithe = int(interM[i+deep-1][j+size-1]) + int(interM[i-1][j-1]) - int(interM[i+2][j-1]) - int(interM[i -1][j+ size -1])+ int(interM[i+deep-1][j+3*size-1]) + int(interM[i-1][j+3*size-2]) - int(interM[i+2][j+3*size-2]) - int(interM[i -1][j+ 3*size -1])
_i = i
_j = j + size
if _i==0:
black = int(interM[_i + deep - 1][_j + size - 1]) - int(interM[_i +deep-1][_j - 1])
else:
black = int(interM[_i+deep-1][_j+size-1]) + int(interM[_i-1][_j-1]) - int(interM[_i+2][_j-1]) - int(interM[_i - 1][_j+ size -1])
dst[i][j] = whithe-2*black
return dst
def showimage(Haar_b,tmp):#将进行Haar函数运算后的图片显示
dst = []
for x in range(len(Haar_b)):
dst.append([])
for y in range(len(Haar_b[0])):
if Haar_b[x][y] > 0:
dst[x].append(255)
else:
dst[x].append(0)
for x in range(len(dst)):
for y in range(len(dst[0])):
f = dst[x][y]
tmp[x, y] = [f, f, f]
return(tmp)
def main():
src = cv.imread('z1.jpg')#图片路径
tmp = src.copy()
# 分裂出三通道。这里只取b通道来进行分析,实际应该是分析三个通道,再合并
b, g, r = cv.split(src)
# 用于得到图像的宽高
_w = len(b[0])
_h = len(b)
in_b = intergralMat(b, _w, _h)#计算积分图
Haar = myHaarC(in_b,_w,_h)
out = showimage(Haar, tmp)
cv.imshow('src', src)#展示测试原图
cv.imshow('test ', out)
cv.imwrite('test haarC .jpg',out)
cv.waitKey()
因为“haar值的白色像素和减去黑色像素和”是基于权重来进行加减,所以对于HaarC=(白+黑)*1-3*黑,也就是HaarC=白-2*黑。
效果如下:
我在网上找了一个很小的积分图,形成数组,方便测试。每次def Haar函数之后,进行测试。测试代码如下:
积分图是基于下图:
interM=[[8,14,14,14,18,26,32,34,34],
[17,27,28,34,46,59,73,84,86],
[26,39,41,49,63,81,96,116,124],
[33,51,62,73,91,115,130,151,163],
[34,54,72,88,109,133,157,184,196],
[41,66,90,114,135,167,193,228,241],
[48,78,111,142,170,202,237,278,294]]#积分图
weight=7
height=9
dis=[]
dis=myHaarC(interM,9,7)
dis1=myHaarC(output,180,180)#output是我一个图像的积分图,可以注释掉
print(dis)
#输出结果:[[37, -14, -34, -36, 0, 0, 0], [9, -18, -19, -13, 0, 0, 0], [-16, -1, 3, -13, 0, 0, 0], [-35, -1, 11, -22, 0, 0, 0], [-49, -6, 26, -22, 0, 0, 0]]