【发布时间】:2019-05-28 14:11:58
【问题描述】:
我正在尝试从文档中读取信息,其中数据字段的类型是您只能在框中输入一个字母/数字。我设法为各个数据字段分割盒子数组,但是在分割这些盒子数组中的单个盒子时遇到问题。
我曾尝试使用cv2.approxPolyDP 和cv2.HoughLines 函数,但是两者都给出了不可接受的结果。 sudoku 问题在某一时刻使用了垂直/水平线的长度比单个数字大得多的事实。就我而言,数字有时会从盒子里溢出,而且几乎总是会碰到盒子。
这个函数不能单独检测小盒子:
def detect_boxes(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sharp_img = cv2.filter2D(np.asarray(gray), -1, kernel)
ret,thresh = cv2.threshold(sharp_img,180,255,1)
edges = cv2.Canny(sharp_img,50,150,apertureSize = 3)
_,contours,h = cv2.findContours(thresh,1,2)
boxes = []
for cnt in contours:
approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
temp = img
if len(approx)==4:
boxes.append(cnt)
print(cnt.shape)
print(max(cnt[0])-min(cnt[0]),max(cnt[1])-min(cnt[1]))
cv2.drawContours(temp,[cnt],0,(0,0,255),-1)
cv2_imshow(temp)
return boxes
approxPolyDP 结果是:
另一个函数是:
def det_box(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sharp_img = cv2.filter2D(np.asarray(gray), -1, kernel)
ret,thresh = cv2.threshold(sharp_img,180,255,1)
edges = cv2.Canny(gray,50,150,apertureSize = 3)
cv2_imshow(edges)
lines = cv2.HoughLines(edges,1,np.pi/180,200)
temp = img
for rho,theta in lines[0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(temp,(x1,y1),(x2,y2),(0,0,255),2)
cv2_imshow(temp)
return lines
HoughLines 结果是:
我试图按顺序获取每个小盒子的盒子点/轮廓。任何帮助将不胜感激。即使删除框中的水平线和垂直线也会有所帮助。
【问题讨论】:
-
如果您事先知道带有未填写框的文件,您可以例如使用 matchTemplate 或 sift/surf 将空文档作为模板,只需硬编码每个框相对于模板的位置,或从文档中减去模板以仅获得手绘部分
-
@HugoRune 我认为这是最后的手段。但是,我设法找到了没有它的解决方案。
标签: python opencv image-processing computer-vision