Detecting line inside a rectangle using OpenCV and Python

129 Views Asked by At

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.

0

There are 0 best solutions below