【问题标题】:Text line segmentation using OpenCV Python使用 OpenCV Python 进行文本行分割
【发布时间】:2022-07-06 19:18:43
【问题描述】:

我正在尝试从下图中提取文本行,并尝试了以下代码,但我只得到一个没有任何数据的图像。在屏蔽图像时,所有线条都被完美地屏蔽了。下面我附上了蒙版图像、最终输出图像和所需的输出图像。

img = cv.imread('Handwritten_data/Ostu_images/H_1.jpg')

lower = (0, 0, 0)
upper = (0, 120, 150)

# threshold on border color
mask = cv.inRange(img, lower, upper)

# dilate threshold
kernel = cv.getStructuringElement(cv.MORPH_RECT, (250,10))
mask = cv.morphologyEx(mask, cv.MORPH_DILATE, kernel)

# recolor border to white
img[mask==255] = (255,255,255)


# Inverting the mask by
# performing bitwise-not operation
mask_black = cv.bitwise_not(mask)
Mask = cv.bitwise_and(img, img, mask = mask_black)

gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# otsu threshold
thresh = cv.threshold(gray, 0, 255, cv.THRESH_OTSU )[1] 

# apply morphology open
kernel = cv.getStructuringElement(cv.MORPH_RECT, (250,10)) 
morph = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel)


# creating a folder
try: 
    # creating a folder named data
    if not os.path.exists('Image_0'):
        os.makedirs('Image_0')
  
# if not created then raise error
except OSError:
    print ('Error: Creating directory of data')

# find contours and bounding boxes
bboxes = []
bboxes_img = img.copy()
contours = cv.findContours(morph, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
    x,y,w,h = cv.boundingRect(cntr)
    cv.rectangle(bboxes_img, (x, y), (x+w, y+h), (0,0,255), 1)
    bboxes.append((x,y,w,h))

for j in range(len(bboxes)):
    (x,y,w,h) = bboxes[j]
    crop = img[y-10:y+h+10, x-10:x+w+10]
    cv.imwrite(f'Image_0/S_{j}.jpg', crop)

任何解决此问题的建议或帮助。

下面是遮罩图

最终图像输出

想要的图像输出是这样的

提前致谢

【问题讨论】:

  • 也许首先使用print() 来查看变量中的内容以及执行了哪部分代码。它被称为"print debuging",它有助于查看代码在做什么。也许您创建的列表只有一项,或者犯了其他错误。
  • 你可以使用os.makedirs('Image_0', exist_ok=True)而不检查if not os.path.exists('Image_0'):
  • 也许您应该在每次操作后显示图像以查看图像上的内容。看来您使用 img[mask==255] = (255,255,255) 从图像中删除了所有文本
  • 似乎所有线条都被识别为单一轮廓,而不是单独的元素。
  • 您遇到的一个问题是大多数蒙版线连接起来,因此当您提取轮廓边界框时,您不会得到分离的线。您需要修改您的形态,以便您的蒙面区域不接触。让你的形态内核只有 1 或 2 像素高,而不是 10。

标签: python opencv


【解决方案1】:

你提出的文本行分割的想法是正确的。但这种方法需要一些调整。

注意:

当您想要遮盖图像的一部分时,请确保遮盖区域为白色。因为在寻找轮廓时,算法会寻找白色区域。由于您正在寻找黑色的轮廓,因此算法错过了它。

以下根据上述思路进行修改。

解决方案:

img = cv2.imread(image_file)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh2 = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY_INV)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (150,2))
mask = cv2.morphologyEx(thresh2, cv2.MORPH_DILATE, kernel)

下面是蒙版图片:

bboxes = []
bboxes_img = img.copy()
contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
    x,y,w,h = cv2.boundingRect(cntr)
    cv2.rectangle(bboxes_img, (x, y), (x+w, y+h), (0,0,255), 1)
    bboxes.append((x,y,w,h))

以下是带边界框的最终结果:

您现在可以添加您的部分代码,以将每个区域保存为单独的图像文件。您可以尝试修改内核参数并探索不同的形态学操作以获得更好的掩码区域。

希望这能让你走上正轨!

【讨论】:

  • 感谢您抽出宝贵时间提出改进代码的建议
猜你喜欢
  • 2017-12-15
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 2019-05-02
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
相关资源
最近更新 更多