python-3.x - OpenCV:从给定图像中分割每个数字。数字写在行矩阵的每个单元格中。每个单元格都以边距为界
问题描述
我一直在尝试从表单文档中识别手写字母(数字/字母)。众所周知,表单文档有 1d 行单元格,申请人必须在这些有界单元格中填写他们的信息。但是,我无法从边界框中分割数字(目前我的输入仅包含数字)。
我经历了以下步骤:
- 通过 opencv2 的“imread”方法读取图像(作为灰度图像)。初始图像尺寸:19 x 209(以像素为单位)。
pic = "crop/cropped000.jpg"
newImg = cv2.imread(pic, 0)
- 通过 opencv2 的“resize”方法将图像大小调整为原始大小的 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 ://imgur.com/a/GStIcdj
我不得不将图像尺寸加倍,因为 Canny 边缘检测正在为一个对象产生双边缘(但是,它仍然如此)。我也玩过其他 openCV 功能,如阈值、高斯模糊、扩张、侵蚀,但都是徒劳的。
解决方案
# 我们还需要一个日期单元格宽度参数:因为这对于 diff bank 可能有所不同 def crop_image_data_from_date_field(图像,new_start_h,new_end_h,new_start_w,new_end_w,cell_width): #for date 每个单元格具有相同的高度和宽度:此处宽度:25 px,因此线将根据宽度进行更改 裁剪图像列表 = [] 起始宽度 = new_start_w for i in range(1,9): # as date 只有 8 个字段:DD/MM/YYYY
cropped_img = 图像[new_start_h:new_end_h, new_start_w + 1 :new_start_w+22] new_start_w = 起始宽度 + (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。我想这会对你有所帮助。
推荐阅读
- javascript - 错误:“对象”类型的“[对象对象]”。NgFor 仅支持绑定到 Iterables,例如 Arrays。- 离子项目
- google-app-engine - Google App Engine 上的传出 HTTP 请求位置
- c# - 图像 WPF 视图上的 2D 动态硬件位置
- javascript - 编码新手并尝试将两个 div 加在一起,其中一个 div 是加 6,另一个是 1
- docker - Docker 容器大小和性能
- python - 拟合模型时的训练精度未反映在混淆矩阵中
- functional-programming - 编写 OCaml 函数时出现“语法错误”?
- java - Spring Security,注销:将参数从 /logout 传递到 /login
- flutter - 更改全屏关闭按钮的颜色
- angular - 访问“http://....”源“http://localhost:4200”的 XMLHttpRequest 已被 CORS 策略阻止