【问题标题】:OpenCV: Segment each digit from the given image. Digits are written in each cell of a row matrix. Each cell is bounded by marginsOpenCV:从给定图像中分割每个数字。数字写在行矩阵的每个单元格中。每个单元格都以边距为界
【发布时间】:2019-09-08 22:12:43
【问题描述】:

我一直在尝试从表单文档中识别手写字母(数字/字母)。众所周知,表单文档有 1d 行单元格,申请人必须在这些有界单元格中填写他们的信息。但是,我无法从边界框中分割数字(目前我的输入仅包含数字)。

我经历了以下步骤:

  1. 通过opencv2的“imread”方法读取图像(作为灰度图像)。初始图片尺寸:19 x 209(以像素为单位)。
pic = "crop/cropped000.jpg"
newImg = cv2.imread(pic, 0)
  1. 通过 opencv2 的“resize”方法将图像大小调整为原始大小的 200%。我使用了 INTER_AREA 插值。调整后的图片尺寸:38 x 418(以像素为单位)
h,w = newImg.shape
resizedImg = cv2.resize(newImg, (2*w,2*h), interpolation=cv2.INTER_AREA)
  1. 应用 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)
  1. 裁剪轮廓并将它们作为图像保存在“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 功能,如阈值、高斯模糊、扩张、侵蚀,但都是徒劳的。

【问题讨论】:

    标签: python-3.x opencv canny-operator handwriting-recognition


    【解决方案1】:

    # 我们还需要一个日期单元格宽度参数:因为这对于 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): # 因为日期只有 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。 我想这会对你有所帮助。

    【讨论】:

    • 没有。我希望系统通过轮廓、边缘检测等技术自行检测框。如果知道行宽和列宽,那么分割它们肯定很容易。不过,我已经找到了解决方案。
    • 能否请您告诉我您的解决方案我也需要那种解决方案。
    猜你喜欢
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2020-05-31
    • 2017-04-02
    • 1970-01-01
    • 2014-01-22
    相关资源
    最近更新 更多