Home > Enterprise >  Text line segmentation
Text line segmentation

Time:04-06

I am trying to extract the text lines from the below figure and I tried the below code but I am getting only a single image without any data. While masking the images all the lines are masked perfectly. Below i attached the masked image, final output image and desired output image.

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)

Any suggestions or help to solve this problem.enter image description here

Below is the masking image enter image description here

final image ouput enter image description here

desired image output be like enter image description here

Thanks in advance

CodePudding user response:

The idea you presented for text line segmentation is correct. But the approach needs some tweaking.

Note:

Whenever you want to mask a portion of the image, make sure the masked region is in white. Because when finding contours the algorithm looks for white regions. Since you were looking for contours that were in black the algorithm missed it.

The following is modified with the above idea.

Solution:

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)

Below is the mask image:

enter image description here

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))

The following is the final result with bounding boxes:

enter image description here

You can now add your portion of the code to save each region as a separate image file. You can try modifying the kernel parameters and exploring different morphological operations to get a better mask region.

Hope this puts you on the right track!

  • Related