简体   繁体   English

使用 Python 中的 open.cv 从手写文本中分离行

[英]Separate lines from handwritten text using open.cv in Python

I am using the below script to try and separate handwritten text from the lines which the text was written on.我正在使用下面的脚本尝试将手写文本与文本所在的行分开。 Currently I am trying to select the lines.目前我正在尝试 select 的线路。

This seems to work well when the line are solid but when the lines are a string of dots it becomes tricky.当线条是实线时,这似乎效果很好,但是当线条是一串点时,它变得很棘手。 To try and get around this I have tried using dilate to make the dots into solid lines, but dilate is also making the text solid which then gets pick up as horizontal lines.为了解决这个问题,我尝试使用 dilate 将点变成实线,但 dilate 也会使文本变成实线,然后将其作为水平线拾取。 I can tweak the kernel for each image but that is not a workable solution when dealing with thousandths of images.我可以为每个图像调整kernel ,但在处理千分之一图像时,这不是一个可行的解决方案。

Can someone suggest how I might make this work please.有人可以建议我如何完成这项工作。 Is this the best approach or is there a better approach for selecting these lines?这是最好的方法还是有更好的方法来选择这些线?

Sample images示例图像在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

import cv2
file_path = r'image.jpg'
image = cv2.imread(file_path)

# resize image if image is bigger then screen size
print('before Dimensions : ', image.shape)
if image.shape[0] > 1200:
    image = cv2.resize(image, None, fx=0.2, fy=0.2)
print('after Dimensions : ', image.shape)

result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Applying dilation to make lines solid
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilation = cv2.dilate(thresh, kernel, iterations = 1)

# Detect horizontal lines
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,1))
detect_horizontal = cv2.morphologyEx(dilation, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(result, [c], -1, (36,255,12), 2)

cv2.imshow('1- gray', gray)
cv2.imshow("2- thresh", thresh)
cv2.imshow("3- detect_horizontal", detect_horizontal)
cv2.imshow("4- result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

By finding contours, we can eliminate smaller ones by their area using cv2.contourArea .通过寻找轮廓,我们可以使用cv2.contourArea按面积消除较小的轮廓。 This will work under the assumption that the image contains dotted lines.这将在图像包含虚线的假设下起作用。

Code:代码:

# read image, convert to grayscale and apply Otsu threshold
img = cv2.imread('text.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
th = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# create black background of same image shape
black = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)

# find contours from threshold image
contours = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]

# draw contours whose area is above certain value
area_threshold = 7
for c in contours:
    area = cv2.contourArea(c)
    if area > area_threshold:
        black = cv2.drawContours(black,[c],0,(255,255,255),2)

black : black

在此处输入图像描述

To refine this for more images, you can filter contours using some statistical measures (like mean, median, etc.)要针对更多图像进行优化,您可以使用一些统计度量(如均值、中值等)过滤轮廓

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM