2

I am trying to remove rules and a background smiley face from multiple notebook pages before performing text detection and recognition on the handwritten text.

enter image description here

An earlier thread offers helpful hints, but my problem is different in several respects.

  1. The text to keep is written over the background items to be removed.
  2. The items to be removed have distinct colors from that of the text, which may be the key to their removal.
  3. The lines to be removed are not very straight, and the smiley face even less so.

I'm thinking of using OpenCV for this task, but I'm open to using ImageMagick or command-line GIMP so long as I can process the entire batch at once. Since I have never used any of these tools before, any advice would be welcome. Thank you.

nathancy
  • 42,661
  • 14
  • 115
  • 137
bongbang
  • 1,610
  • 4
  • 18
  • 34
  • Possible duplicate of [Using ImageMagick to remove all color except black in an image?](https://stackoverflow.com/questions/15426968/using-imagemagick-to-remove-all-color-except-black-in-an-image) – wuerfelfreak Aug 14 '19 at 06:01
  • You could try thresholding on blue hue from HSV so that blue becomes white and all other colors are black. What have you tried? – fmw42 Aug 14 '19 at 06:02
  • do you have uncompressed images? jpeg is not ideal for high resolution stuff based on colour as most of the compressing is done on the colour information – Piglet Aug 14 '19 at 07:46
  • Assuming that the text is blue, you can use color thresholding to obtain a mask of the text outline then perform smoothing operations to isolate the characters. This way, you can concurrently remove the smiley face and the lines – nathancy Aug 15 '19 at 01:11

1 Answers1

2

Here's a simple approach with the assumption that the text is blue


We begin by converting the image to HSV format and create a mask to isolate the characters

image = cv2.imread('1.png')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([21,0,0])
upper = np.array([179, 255, 209])
mask = cv2.inRange(image, lower, upper)

enter image description here

Now we perform morphological transformations to remove small noise

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=1)

enter image description here

We have the desired text outlines so we can isolate characters by masking with the original image

result[close==0] = (255,255,255)

enter image description here

Finally to prepare the image for OCR/Tesseract, we change the characters to black

retouch_mask = (result <= [250.,250.,250.]).all(axis=2)
result[retouch_mask] = [0,0,0]

enter image description here

Full code

import numpy as np
import cv2

image = cv2.imread('1.png')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([21,0,0])
upper = np.array([179, 255, 209])
mask = cv2.inRange(image, lower, upper)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=1)

result[close==0] = (255,255,255)

cv2.imshow('cleaned', result)

retouch_mask = (result <= [250.,250.,250.]).all(axis=2)
result[retouch_mask] = [0,0,0]

cv2.imshow('mask', mask)
cv2.imshow('close', close)
cv2.imshow('result', result)
cv2.waitKey()
nathancy
  • 42,661
  • 14
  • 115
  • 137
  • Thank you, but I don't think filling the mask with black will work very well, because (1) the training data is [gray-scale](https://coding.tools/blog/casia-handwritten-chinese-character-recognition-using-convolutional-neural-network-and-similarity-ranking) and (2) the mask has a low fidelity to the original characters (e.g. it turns four horizon strokes in the bottom left-hand character into a solid triangle). There should be a way to use the mask to apply effects only to the characters so that they resemble the linked training examples, right? – bongbang Aug 19 '19 at 02:36
  • I don't understand why filling the mask with black won't work. You can convert the image to grayscale with `cv2.cvtColor()` then use the training data. The characters may look merged since the smoothing filter is large, you can adjust this filter to "unmerge" but you will have more noise – nathancy Aug 26 '19 at 20:22