【问题标题】:how do i extract numbers from an image, row by row?如何从图像中逐行提取数字?
【发布时间】:2021-01-12 12:50:53
【问题描述】:

在使用 opencv 预处理数独板的图像(来自网络)后,我设法得到以下图片:

遍历轮廓并使用 pytesseract 和 psm 10(单个字符)提取每个值会导致垃圾值。

因此我想将图像分割成行并尝试使用 config psm 6 提取值,希望它可以工作。

我采用的方法是简单地对行进行 numpy 切片并尝试提取值,尽管它不起作用,在第一次迭代后给我SystemError: tile cannot extend outside image 尽管我确定切片发生在图像内部

y = 1
for x in range(1, 9):
     cropped_row = mask[y*33-33:y*33-1][x*33-33:x*33-1]
     text = tess.image_to_string(np.array(cropped_row), config='--psm 6')
     y += 1
     print(text)

我想要一些关于从图像中 OCRing 行的正确方法的指导

【问题讨论】:

  • 我很惊讶你没有用psm=10 做得更好。您是否包含边框并合理设置 dpi?
  • 如果掩码是 numpy 应该是 mask[y*33-33:y*33-1, x*33-33:x*33-1],你也可以遍历 x 和 y同时对于 x,y in zip(range(1,9),range(1,9))

标签: python python-imaging-library python-tesseract opencv-python


【解决方案1】:

最后我采取了一种稍微不同的方法,正如 natancy 在this 回答中所解释的那样。

我专注于网格线,并删除了所有值,以便findcontours() 将定位所有网格单元格。

然后,我遍历所有轮廓并检查它们是单元格(按大小)还是其他轮廓。 如果它是一个单元格,则掩码仅使当前单元格可见(以及使用时的值 bitwise_and(original_image, mask) 这样我就可以得到一个只有一个数字的空白图像,然后我通过 tesseract 运行该图像。 稍后清除一些文本,我得到了我想要的输出。

提取数字:

list_of_clues = []
    for contour in contours:
        extracted_value = ''

        # create black mask
        mask = np.zeros(processed.shape, dtype=np.uint8)

        # check if contour is a cell
        area = cv2.contourArea(contour)
        if 700 <= area <= 1000:  # contour is a cell
            cv2.drawContours(mask, [contour], -1, WHITE, -1)  # color everything in mask, but the contour- white
            isolated_cell = cv2.bitwise_and(processed, mask)
            isolated_cell[mask == 0] = 255  # invert isolated_cell's mask to WHITE (for tess)

            # extract text from isolated_cell
            text = tess.image_to_string(isolated_cell, config='--psm 10')

            # clean non-numbers:
            for ch in text:
                if ch.isdigit():
                    extracted_value = ch

            # calculate cell coordinates only if extracted_value exist
            if extracted_value:
            # relevant for my proj, extract grid coordinates of extracted value
                [x_pos, y_pos, wid, hei] = cv2.boundingRect(contour)    # get contour's sizes
                x_coord = int(x_pos // (grid_size_pixels / 9))          # get x row-coordinate
                y_coord = int(y_pos // (grid_size_pixels / 9))          # get y col-coordinate
                list_of_clues.append(((x_coord, y_coord), int(extracted_value)))
        else:   # contour isn't a cell
            continue

【讨论】:

    【解决方案2】:

    我试过这个:

    custom_oem_psm_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist="0123456789"'# -c preserve_interword_spaces=0'
    text= pytesseract.pytesseract.image_to_string(otsu, config=custom_oem_psm_config)
    print(text)
    

    输出:

    2 91
    4 67 13
    2 976
    4 9
    9816 2754
    3 1
    653 7
    24 85 1
    46 2
    

    如果你想得到数字的准确位置,试试numpy切片,从左到右,从上到下排序,然后将每个数字传递给tesseract

    【讨论】:

      猜你喜欢
      • 2017-01-18
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多