Filtering image in opencv with histogram projection - Mask problem

Viewed 323

I am making an algorithm to detect license plates, specifically at character segmentation part. For this I use a histogram projection.

My idea is to use this histogram projection to

  1. Clean edges
  2. Segment the characters

The problem is when I want to apply histogram projection twice, when applying a filter, it does not show well (see last image)

Example with clean edges, with this binary image:

enter image description here

I have this algorithm that cleans the edges of a binary image:

from matplotlib import pyplot as plt
import pylab
import numpy as np

img = binary_image # input image
(rows,cols)=img.shape

h_projection = np.array([ x/rows for x in img.sum(axis=0)])
threshold = 255 - 60
print("we will use threshold {} for horizontal".format(threshold))
# select the black areas
black_areas = np.where(h_projection > threshold)
fig = plt.figure(figsize=(16,8))
fig.add_subplot(121)
for j in black_areas:
    img[:, j] = 0
    plt.plot((j, j), (0, 1), 'g-')
plt.plot(range(cols), h_projection.T)

v_projection = np.array([ x/cols for x in img.sum(axis=1)])
threshold = 255 - 60
print("we will use threshold {} for vertical".format(threshold))
black_areas = np.where(v_projection > threshold)
fig.add_subplot(122)
for j in black_areas:
    img[j, :] = 0
    plt.plot((0,1), (j,j), 'g-')
plt.plot(v_projection, range(rows))
plt.show()

# obscurate areas on the image
plt.figure(figsize=(16,12))
plt.subplot(211)
plt.title("Image with the projection mask")
plt.imshow(img)

And the output:

enter image description here enter image description here

It do it very well (It could be more specific with the threshold, but I can't because different images were loaded for a neural network).

Now if I want to apply another histogram projection for character segmentation:

from matplotlib import pyplot as plt
import pylab
import numpy as np

#input image will be the same img variable.

(rows,cols)=img.shape

h_projection = np.array([ x/rows for x in img.sum(axis=0)])
print(np.min(h_projection))
print(np.max(h_projection))
threshold = (np.max(h_projection) - np.min(h_projection)) / 4
print("we will use threshold {} for horizontal".format(threshold))
# select the black areas
black_areas = np.where(h_projection < threshold)
fig = plt.figure(figsize=(16,8))
fig.add_subplot(121)
for j in black_areas:
    img[:, j] = 1
    plt.plot((j, j), (0, 1), 'g-')
plt.plot(range(cols), h_projection.T)

v_projection = np.array([ x/cols for x in img.sum(axis=1)])
threshold = (np.max(v_projection) - np.min(v_projection)) / 4
print("we will use threshold {} for vertical".format(threshold))
black_areas = np.where(v_projection < threshold)
fig.add_subplot(122)
for j in black_areas:
    img[j, :] = 0
    plt.plot((0,1), (j,j), 'g-')
plt.plot(v_projection, range(rows))
plt.show()

# obscurate areas on the image
plt.figure(figsize=(16,12))
plt.subplot(211)
plt.title("Image with the projection mask")
plt.imshow(img)

# erode the features
import scipy
plt.subplot(212)
plt.title("Image after erosion (suggestion)")
eroded_img = scipy.ndimage.morphology.binary_erosion(img,  structure=np.ones((1,1))).astype(img.dtype)
plt.imshow(eroded_img)
plt.show()

It will show something like this:

enter image description here

enter image description here

As you can see the last image, when erosion it's applied, it seems that don't take the black of the previous the mask. Am I marking some areas wrong?

0 Answers
Related