I have this image.Rectangles with lines. I have to assign the number (1 to 4) below the image of the rectangle with respect to its length inside the rectangle. The shorter the line lower the number. I am using OpenCV and Jupyter Notebook. How can I accomplish this?
I tried using Hough line transform and contour detection using OpenCV. But Hough line transform detects way too many lines even in places where there are no lines. This is my first time experimenting with images and OpenCV.
Also, I would be grateful if you could also tell me how to make the rectangles straight along with the straight lines inside them. Although I haven't tried doing this myself yet, it will be helpful.
Edit Based on the suggestion by @fmw42, I ended up doing the followig.
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Load the image
image = cv2.imread('rects.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
# Find contours in the edge-detected image with hierarchical retrieval
contours, hierarchy = cv2.findContours(edges, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
# Create a copy of the original image to draw the contours on
contour_image = image.copy()
# Lists to store the lengths of inner contours (lines)
inner_contour_lengths = []
# Loop through the contours and hierarchy
for i, contour in enumerate(contours):
# Get the parent index from the hierarchy
parent_idx = hierarchy[0][i][3]
if parent_idx != -1:
# Inner contour, line
perimeter = cv2.arcLength(contour, True)
inner_contour_lengths.append((perimeter, i)) # Store length and index
# Sort the inner contour lengths in ascending order
inner_contour_lengths.sort()
# Assign numbers to the lines based on their lengths
line_numbers = {length_index[1]: i + 1 for i, length_index in enumerate(inner_contour_lengths)}
# Draw and label the lines for the four contours with lowest lengths
for length, index in inner_contour_lengths[:4]: # Only the first four contours
contour = contours[index]
cv2.drawContours(contour_image, [contour], -1, (0, 255, 0), 2) # Green color
number = line_numbers[index]
cv2.putText(contour_image, str(number), tuple(contour[0][0]), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) # Red color
plt.imshow(cv2.cvtColor(contour_image, cv2.COLOR_BGR2RGB))
plt.show()
The result is here.result image. If there is a better way to do it, please tell me.