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.
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:
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:
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!