Sourav
Sourav

Reputation: 866

Find Alphabet and Color it to Red with OpenCV Python

I have a large image with some alphabets in it and cut out of one alphabet ("A"). I need to find each A in the larger image and color it to red.

Large Image: large image

Alphabet A: Letter A

To solve the problem, I have used the following codes-

import cv2, numpy as np

# read the image and convert into binary
a = cv2.imread('search.png', 0) 
ret,binary_image = cv2.threshold(a,230,255,cv2.THRESH_BINARY_INV)

# create the Structuring element
letter_a = cv2.imread('A.png', 0)
ret,se = cv2.threshold(letter_a,230,255,cv2.THRESH_BINARY_INV)

#erosion and dilation for finding A
erosion = cv2.erode(binary_image , se) 
new_se = cv2.flip(se,0)
dilation = cv2.dilate(erosion, new_se) 
cv2.imwrite('dilation.jpg', dilation )

In this point, I get the following image dilation image

As you can see, I am clearly identifying all the A. However, I need to color those A to red and most importantly, write on the first large image with black letter and white background. Is there any way to do that? Maybe using numpy array write on the first image?

Upvotes: 1

Views: 1120

Answers (2)

Sourav
Sourav

Reputation: 866

I used the following codes to solve the problem-

import cv2, numpy as np
# read the image and convert into binary
color_image = cv2.imread(r'search.png', 1) 
gray_image = cv2.imread(r'search.png', 0) 
ret,binary_image = cv2.threshold(gray_image,230,255,cv2.THRESH_BINARY_INV)

# create the Structuring element
letter_a = cv2.imread('A.png', 0)
ret,se = cv2.threshold(letter_a,230,255,cv2.THRESH_BINARY_INV)

#erosion and dilation for finding A
erosion = cv2.erode(binary_image, se) 
new_se = cv2.flip(se,0)
dilation = cv2.dilate(erosion, new_se) 

for i in zip(*np.where(dilation == 255)):
    color_image[i[0], i[1], 0] = 0
    color_image[i[0], i[1], 1] = 0
    color_image[i[0], i[1], 2] = 255

# show and save image
cv2.imwrite('all_a.jpg', color_image)
cv2.imshow('All A',color_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result

Upvotes: 0

J.D.
J.D.

Reputation: 4561

You can solve this as follows.
First off, to color the letters red in the main image, it is best to load it in color. A grayscale copy is created to perform the threshold.
Then a black image with the dimensions of the main image is create and the color of this image is set to red. The image with the A's is used as a mask to get an image of red A's. These red A's are then added to the main image.*

Result:

enter image description here

Code:

import cv2, numpy as np

# load the image in color
a = cv2.imread('search.png') 
# create grayscale
a_gray = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)
ret,binary_image = cv2.threshold(a_gray,230,255,cv2.THRESH_BINARY_INV)

# create the Structuring element
letter_a = cv2.imread('A.png', 0)
ret,se = cv2.threshold(letter_a,230,255,cv2.THRESH_BINARY_INV)

#erosion and dilation for finding A
erosion = cv2.erode(binary_image , se) 
new_se = cv2.flip(se,0)
dilation = cv2.dilate(erosion, new_se) 

# create a red background image
red = np.zeros((a.shape[:3]),dtype=a.dtype)
red[:] = (0,0,255)
# apply the mask with A's to get red A's
red_a = cv2.bitwise_and(red,red,mask=dilation)

# Add the A's to the main image
result = cv2.add(a,red_a)

cv2.imshow('Result', result )
cv2.waitKey(0)
cv2.destroyAllWindows()

*If the letters are not black an extra step is needed, read this tutorial. But for your image this is not necessary.

Upvotes: 3

Related Questions