【问题标题】:Why does my code not segment the characters of the input image?为什么我的代码不分割输入图像的字符?
【发布时间】:2021-09-07 18:44:34
【问题描述】:

我正在尝试从图像中进行字符分割,但输出没有被分割。

这是我的 new_input 图片:

new input image

这是我分割字符的代码:

word = cv2.imread('../input/word-image/word.PNG',0)

fig, ax1 = plt.subplots(1)
ax1.imshow(word, cmap="gray")
# the next two lines is based on the assumptions that the width of
# a license plate should be between 5% and 15% of the license plate,
# and height should be between 35% and 60%
# this will eliminate some
character_dimensions = (0.35*word.shape[0], 0.60*word.shape[0], 0.05*word.shape[1], 0.15*word.shape[1])
min_height, max_height, min_width, max_width = character_dimensions

characters = []
counter=0
column_list = []
for regions in regionprops(word):
    y0, x0, y1, x1 = regions.bbox
    region_height = y1 - y0
    region_width = x1 - x0

    if region_height > min_height and region_height < max_height and region_width > min_width and region_width < max_width:
        roi = word[y0:y1, x0:x1]

        # draw a red bordered rectangle over the character.
        rect_border = patches.Rectangle((x0, y0), x1 - x0, y1 - y0, edgecolor="red",
                                       linewidth=2, fill=False)
        ax1.add_patch(rect_border)

        # resize the characters to 20X20 and then append each character into the characters list
        resized_char = resize(roi, (20, 20))
        characters.append(resized_char)

        # this is just to keep track of the arrangement of the characters
        column_list.append(x0)
# print(characters)
plt.show()

这是当前的输出:

这可能是什么问题?

【问题讨论】:

    标签: python image-processing deep-learning ocr image-segmentation


    【解决方案1】:

    来自skimage.measure.regionprops上的文档:

    测量标记图像区域的属性。

    您没有提供正确标记的图像,但您的输入被解释为一个,因为由于混叠,您有多个灰度值。在您的循环中调试regions,您会看到检测到很多区域。由于您对宽度和高度的假设,它们都被忽略了。

    因此,第一步是生成适当的标记图像,例如使用cv2.connectedComponents。因此,您需要事先(反向)对输入图像进行二值化。拥有labels 图像,您可以直接进行循环。不过,我会在这里忽略所有关于宽度和高度的假设。

    那是修改后的代码:

    import cv2
    import matplotlib.pyplot as plt
    from matplotlib import patches
    from skimage.measure import regionprops
    from skimage.transform import resize
    
    # Read image as grayscale
    word = cv2.imread('pFLpN.png', cv2.IMREAD_GRAYSCALE)
    
    # Inverse binarize image, and find connected components
    thr = cv2.threshold(word, 254, 255, cv2.THRESH_BINARY_INV)[1]
    labels = cv2.connectedComponents(thr)[1]
    
    # Maybe leave out any assumptions on the width and height...
    
    # Prepare outputs
    plt.figure(figsize=(18, 9))
    plt.subplot(2, 2, 1), plt.imshow(word, cmap='gray'), plt.title('Original image')
    plt.subplot(2, 2, 2), plt.imshow(thr, cmap='gray'), plt.title('Binarized image')
    plt.subplot(2, 2, 3), plt.imshow(labels), plt.title('Connected components')
    ax = plt.subplot(2, 2, 4), plt.imshow(word, cmap='gray')
    
    # Iterate found connected components as before
    # (Without checking width and height...)
    characters = []
    counter = 0
    column_list = []
    for regions in regionprops(labels):
        y0, x0, y1, x1 = regions.bbox
        region_height = y1 - y0
        region_width = x1 - x0
        roi = word[y0:y1, x0:x1]
        rect_border = patches.Rectangle((x0, y0), x1 - x0, y1 - y0, edgecolor='red',
                                        linewidth=2, fill=False)
        ax[0].add_patch(rect_border)
    
        resized_char = resize(roi, (20, 20))
        characters.append(resized_char)
    
        column_list.append(x0)
    
    plt.title('Segmented characters')
    plt.tight_layout(), plt.show()
    

    而且,这就是输出:

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:      Windows-10-10.0.19041-SP0
    Python:        3.9.1
    PyCharm:       2021.1.2
    Matplotlib:    3.4.2
    OpenCV:        4.5.2
    scikit-image:  0.18.1
    ----------------------------------------
    

    【讨论】:

    • 这很有帮助!!我怎样才能打印出单个字符的图像呢?
    • “打印”是什么意思?您已经拥有roi = word[y0:y1, x0:x1],它是来自word 的裁剪字符。例如,将roi 保存到某个图像。如果你想显示单个字符,或者做一些额外的plt.imshow(roi)
    • 嘿!当我尝试输入不同的图像时,它不会被分割。请看一下我输入的新图像。我在发布的问题中进行了编辑。可能是什么原因?!
    • 因为您的初始图像具有完美的白色背景,而您的新图像具有一些白色/灰色背景。对于每一个图像处理任务,都需要在输入变化时调整预处理。如果您需要更通用的解决方案,请在开头提供更多输入示例!对于该新图像,您可以尝试thr = cv2.threshold(word, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)[1],它也适用于初始图像。但不能保证您接下来的 6 或 7 张图片都可以使用...
    • 此代码在连接字符上绘制边界框。但是,在我的语言中,并非所有字符都有连接的组件!在那种情况下我该怎么办???
    猜你喜欢
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 2018-02-05
    • 2011-06-25
    相关资源
    最近更新 更多