我一直在尝试从表单文档中识别手写字母(数字/字母)。众所周知,表单文档具有 1d 行单元格,申请人必须在这些限定单元格中填写其信息。但是,我无法从边界框中分割数字(目前我的输入仅包含数字)。
我经历了以下步骤:
- 通过opencv2的"imread"方法读取图像(作为灰度图像)。初始图像尺寸:19 x 209(像素)。
pic = "crop/cropped000.jpg"
newImg = cv2.imread(pic, 0)
- 通过opencv2的"调整大小"方法将图像大小调整为原始大小的200%。我使用了INTER_AREA插值。调整大小的图像大小:38 x 418(像素)
h,w = newImg.shape
resizedImg = cv2.resize(newImg, (2*w,2*h), interpolation=cv2.INTER_AREA)
- 应用了Canny边缘检测。
v = np.median(resizedImg)
sigma = 0.33
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edgedImg = cv2.Canny(resizedImg, lower, upper)
- 裁剪轮廓
- 并将它们保存为"BB"目录中的图像。
im2, contours, hierarchy = cv2.findContours(edgedImg.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
num = 0
for c in contours:
x, y, w, h = cv2.boundingRect(c)
num += 1
new_img = resizedImg[y:y+h, x:x+w]
cv2.imwrite('BB/'+str(num).zfill(3) + '.jpg', new_img)
完整代码摘要:
pic = "crop/cropped000.jpg"
newImg = cv2.imread(pic, 0)
h,w = newImg.shape
print(newImg.shape)
resizedImg = cv2.resize(newImg, (2*w,2*h), interpolation=cv2.INTER_AREA)
print(resizedImg.shape)
v = np.median(resizedImg)
sigma = 0.33
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edgedImg = cv2.Canny(resizedImg, lower, upper)
im2, contours, hierarchy = cv2.findContours(edgedImg.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
num = 0
for c in contours:
x, y, w, h = cv2.boundingRect(c)
num += 1
new_img = resizedImg[y:y+h, x:x+w]
cv2.imwrite('BB/'+str(num).zfill(3) + '.jpg', new_img)
制作的图片发布在这里: https://i.stack.imgur.com/9To5D.jpg
我不得不将图像大小加倍,因为Canny边缘检测正在为对象生成双边(但是,它仍然如此)。我还玩过其他openCV功能,如阈值,高斯模糊,扩张,侵蚀,但都是徒劳的。
# 我们需要为日期单元格宽度再添加一个参数:因为这对于差异库可能有所不同 def crop_image_data_from_date_field(Image, new_start_h, new_end_h, new_start_w, new_end_w, cell_width): #for 日期每个单元格具有相同的高度和宽度:此处宽度:25 px,因此电源线将根据宽度进行更改 cropped_image_list = [] starting_width = new_start_w 对于范围 (1,9) 中的 i:# 作为日期只有 8 个字段:日/月/年 cropped_img
= 图像[new_start_h:new_end_h,new_start_w + 1 :new_start_w+22] new_start_w = starting_width + (i*cell_width)cropped_img = cv2.resize(cropped_img, (28, 28)) image_name = 'cropped_date/cropped_'+ str(i) + '.png' cv2.imwrite(image_name, cropped_img) cropped_image_list.append(image_name) # print('cropped_image_list : ',cropped_image_list,len(cropped_image_list)) # rec_value = handwritten_digit_recog.recog_digits(cropped_image_list) recvd_value = custom_predict.predict_digit(cropped_image_list) # print('recvd val : ',recvd_value) return recvd_value
您需要指定每个单元格宽度,它是x,y,w,h。 我认为这会对你有所帮助。