[
This is the image I need to do contour detection on. I need to contour the characters inside and outside the rectangle, but not the rectangle itself. The Second image I attached is the desired output.
Now this is the approach I have tried so far:
import cv2
# Read the image
image = cv2.imread('fig1.jpg')
# Convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply histogram equalization to enhance contrast
equalized = cv2.equalizeHist(gray)
# Apply Gaussian blur to the equalized image
blurred = cv2.GaussianBlur(equalized, (5, 5), 0)
# Apply Laplacian operator to detect edges
edges = cv2.Laplacian(blurred, cv2.CV_64F)
# Apply thresholding to create a binary image
_, edges_binary = cv2.threshold(edges, 20, 255, cv2.THRESH_BINARY)
# Convert edges_binary to the appropriate data type (CV_8UC1)
edges_binary = edges_binary.astype(np.uint8)
# Find contours of the edges
contours, _ = cv2.findContours(edges_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw the sides of the rectangle (for visualization)
cv2.drawContours(image, contours, -1, (255, 255, 255), 2)
# Get the bounding box of the rectangle
x, y, w, h = cv2.boundingRect(contours[0])
# Omit the sides of the rectangle from the binary image
edges_binary[y:y+h, x:x+w] = 0
# Find contours in the modified binary image
contours, _ = cv2.findContours(edges_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw contours on the original image
cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
# Display the result
cv2.imshow('Contour Detection', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
I feel as though I am very close. I have tried several other approaches, but this one creates the closest to the desired result. I only learned OpenCV Last week, so can anyone tell me what else I can try?
You can use the contour area to avoid the large outer rectangle. Try the below code. Final result will have the bounding boxes of letters and symbols. Hope this helps.
import cv2
import numpy as np
#READ IMAGE AND APPLY THRESHOLD
image = cv2.imread("letters.jpg")
grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresholded_image = cv2.threshold(grayscale_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
#FIND THE CONTOURS IN IMAGE
contours, hierarchy = cv2.findContours(thresholded_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_image = np.zeros_like(thresholded_image)
#SELECT CONTOURS WHICH ARE SMALL, LESS AREA COMPARED TO LARGE RECTANGLE
selected_ctr =[]
selected_bounding_rect = []
for ctr in contours:
if cv2.contourArea(ctr) < 1000: #ADJUST THIS ACCORDING TO YOUR NEED.
selected_ctr.append(ctr) #SELECT CONTOUR
selected_bounding_rect.append(cv2.boundingRect(ctr)) #GET BOUNDING BOX
#DRAW CONTOURS OF THE FOUND LETTERS AND SYMBOLS
cv2.drawContours(contour_image, selected_ctr, -1, 255, thickness=1)
cv2.imwrite("letters_ctr.jpg",contour_image) # SAVE CONTOUR IMAGE
#DRAW THE SELECTED RECTANGLES
for rect in selected_bounding_rect:
image_rect = cv2.rectangle(image, rect, (0, 255, 0) , 1)
cv2.imwrite("letters_rect.jpg",image_rect) #SAVE RECTANGLE DRAWN IMAGE
Output: