本文讲的是垂直投影和水平投影在图像处理中的应用。
垂直投影指将所有像素沿垂直方向投射到一个点(进行平均值、求和等操作),水平投影则是沿水平方向。
比如下图显示了一张做了二值化处理的图片的水平投影和垂直投影的直方图(这里清除了两边为零的数据)。
我们可以用OpenCV的reduce来实现垂直投影和水平投影。
C++和Java中的reduce操作需要5个参数,依次为原图矩阵、输出矩阵、维数、操作类型rtype、数据类型dtype。
Dim h,v as mat
h.initialize
v.initialize
cv2.reduce(thresh,h,1,0,cv2.cvType("CV_32S")) '水平投影
cv2.reduce(thresh,v,0,0,cv2.cvType("CV_32S")) '垂直投影
维数的取值:
- 1,投射到一列
- 0,投射到一行
- -1,根据输出矩阵的大小自动选择
操作类型:
- CV_REDUCE_SUM,求和
- CV_REDUCE_AVG,求均值
- CV_REDUCE_MAX,求最大值
- CV_REDUCE_MIN,求最小值
数据类型需要根据最终得到的值进行设置,像求和的话就不能取太小,否则会报错。
接下来讲一个具体的例子,用于检测两个文字区域间是不是被黑线分隔。
比如下面两张图,分别是左右和上下方向存在分隔:
我们先对图像做二值化处理,并且反转颜色。之后做轮廓检测,对每个轮廓做reduce求和操作。如果轮廓是起到分隔作用的,那它是连接两端的连续的一段,坐标上每个点的值都要大于0。
下面是Python实现代码:
import cv2
import numpy as np
def infer(direction):
index=0
if direction==1: #horizontal
end=height
else: # vertical
end=width
for cnt in contours:
mask = np.zeros_like(img)
cv2.drawContours(mask, [cnt], -1, (255,255,255), 1)
sum = cv2.reduce(mask, direction, cv2.REDUCE_SUM, dtype=cv2.CV_32S)
blocked=True
for j in range(end):
if direction==1:
value=sum[j][0]
else:
value=sum[0,j]
print("j:"+str(j))
print("value:"+str(value))
if value==0:
blocked=False
break
if blocked==True:
cv2.imwrite(str(index)+'MyPic.jpg', mask)
cv2.imwrite('y.jpg', sum)
print(sum)
print("blocked")
return True
index=index+1
return False
img = cv2.imread('balloon.png', cv2.IMREAD_GRAYSCALE)
height, width = img.shape[:2]
ret, thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
infer(0)
第一张图检测到的分割轮廓:
reduce后的结果:
[[510]
[510]
[510]
[510]
[510]
[510]
[510]
[510]
[510]
[255]
[510]
[510]
[510]
[510]
[255]
[510]
[510]
[510]
[510]
[510]
[510]
[510]]
第二张图检测到的分割轮廓:
reduce后的结果:
[[10710 3315 3060 765 510 1020 510 510 765 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 510 510 510 510 510
510 510 510 510 510 510 510 1020 8670]]
参考资料: