OpenCV 中得矩阵和向量思维
比如下面去除背景算法,源码用c++写的,我用python重写了一遍,
参考1
用opencv 从实现如下,核心代码如下
def reduce_background(img):
win_size = 50
nh = int(img.shape[0]/win_size)+1
nw = int(img.shape[1]/win_size)+1
for i in range(nh):
for j in range(nw):
# print (i,j)
rstart = j*win_size
cstart = i*win_size
if rstart+win_size>img.shape[0]-1:
rend = img.shape[0]-1
else:
rend = rstart+win_size
if cstart+win_size>img.shape[1]-1:
cend = img.shape[1]-1
else:
cend = cstart+win_size
summ = float(win_size*win_size)
# sub = img[rstart:rend,cstart:cend]
# cv2.imshow("original"+str(i)+str(j),sub)
ar = 0
ag = 0
ab = 0
for r in range(rstart,rend):
for c in range(cstart,cend):
ar += img[r,c][0]/summ
ag += img[r,c][1]/summ
ab += img[r,c][2]/summ
# print(ar,ag,ab)
agray = 0.3*ar+0.59*ag+0.11*ab
# print(agray)
if agray<0.1:
bright = 1.0
else:
bright = 250.0/agray
contr = 1.3
for r in range(rstart,rend):
for c in range(cstart,cend):
vv = (ar +(img[r,c][0]-ar)*contr)*bright
img[r,c][0] = clamp(vv)
vv = (ag +(img[r,c][1]-ag)*contr)*bright
img[r,c][1] = clamp(vv)
vv = (ab +(img[r,c][2]-ab)*contr)*bright
img[r,c][2] = clamp(vv)
发现大量的时间用在for循环里,参考了网上的建议,把代码改写如下
def reduce_background(img):
"""
reduce background of any image by (size*size) square method
version 2:use numpy MAT accelate much faster than python approch
"""
win_size = 50
print (img.shape)
nh = int(img.shape[0]/win_size)+1
nw = int(img.shape[1]/win_size)+1
for i in range(nw):
for j in range(nh):
# print (i,j)
rstart = j*win_size
cstart = i*win_size
if rstart + win_size>img.shape[0]-1:
rend = img.shape[0]-1
else:
rend = rstart + win_size
if cstart + win_size>img.shape[1]-1:
cend = img.shape[1]-1
else:
cend = cstart + win_size
summ = float(win_size*win_size)
sub = img[rstart:rend,cstart:cend]
ar = 0 # average color of red
ag = 0 # average color of green
ab = 0 # average color of blue
rr = sub[:,:,0]
gg = sub[:,:,1]
bb = sub[:,:,2]
ar = cv2.mean(rr)
ag = cv2.mean(gg)
ab = cv2.mean(bb)
agray = 0.3*ar[0]+0.59*ag[0]+0.11*ab[0] #average color of grey
maxv = np.max(sub)
minv = np.min(sub)
s = 1 - minv/maxv
v = maxv/agray
if v>0.3:
bright = 2
else:
bright = 250.0/agray
contr = 1.3
# enhanse image
rr = np.clip((ar[0]+(rr-ar[0])*contr)*bright,0,255)
gg = np.clip((ag[0]+(gg-ag[0])*contr)*bright,0,255)
bb = np.clip((ab[0]+(bb-ab[0])*contr)*bright,0,255)
# update src image
img[rstart:rend,cstart:cend][:,:,0]=rr
img[rstart:rend,cstart:cend][:,:,1]=gg
img[rstart:rend,cstart:cend][:,:,2]=bb
return img
矩阵计算
用numpy矩阵函数执行效率大幅提升
for— 用向量运算 numpy ±*()等直接向量矩阵运算
rr = np.clip((ar[0]+(rr-ar[0])*contr)*bright,0,255)
子矩阵
sub = img[rstart:rend,cstart:cend] #子矩阵 或子图像
rr = sub[:,:,0] #”取出图像的红色分量
img[rstart:rend,cstart:cend][:,:,0]=rr # 填回数据
#
最大最小值
直接用np.max() 或 np.min() 我一开始用错成 minMaxLoc 函数走了很多弯路
当然还有 np.clip()等函数 不一一详述
总结
用numpy中的内置函数效率能提高,维护更方便