I want to identify the squares in the image and extract the letters written in them, but I can’t get the whole letter. I only get fragments like in the images shown below.
img = cv2.imread(img_path)
img_path = "img.png"
gray = cv2.cvtColor(img , cv2.COLOR_BGR2GRAY)
# Smooth the edges to facilitate sharpening
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen_kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharpen = cv2.filter2D(blur, -1, sharpen_kernel)
# Apply adaptive thresholding to create a binary image and close gaps
thresh = cv2.adaptiveThreshold(sharpen, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV, 11, 2)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
# Detect contours and filter based on area size
contours = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)
contours = contours[0] if len(contours) == 2 else contours[1]
min_area = 350
max_area = 6200
image_number = 0
lower_blue = np.array([90, 50, 20])
upper_blue = np.array([150, 255, 255])
# Avoid the small/big random contours that are detected
contours = filter(lambda contour: min_area < cv2.contourArea(contour) < max_area, contours)
# Sort the contours to get them as a 'line'
sorted_contours = sorted(contours, key=lambda contour: cv2.boundingRect(contour)[0])
selected_rects = []
for c in sorted_contours:
x, y, w, h = cv2.boundingRect(c)
# Make sure that the rectangles do not overleap with the already selected ones
if not any(x > rect[0] and y > rect[1] and x + w < rect[0] + rect[2] and y + h < rect[1] + rect[3] for rect in selected_rects):
ROI = image[y:y + h, x:x + w]
ROI = cv2.GaussianBlur(ROI, (3, 3), 0)
hsv = cv2.cvtColor(ROI, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower_blue, upper_blue)
blue_pixels = cv2.countNonZero(mask)
# Make sure that the rectangle has blue within it to avoid random rectangles
if blue_pixels > 100:
binary_image = cv2.resize(mask, (28, 28))
cv2.imwrite(f'./resources/ROI_{image_number}.png', binary_image)
image_number += 1
selected_rects.append((x, y, w, h))
Initial Image
Some of the extracted ROIs
Masks that are incomplete
I tried to remove the gray border and then transform all the pixels that were not white into bright blue. However, I couldn’t remove all of the border in every case, and sometimes there were random yellowish spots because the image was scanned.
Farcasut is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.