I am writing a code to find number of bends in a image.
import cv2
import numpy as np
import matplotlib.pyplot as plt
# reading and converting img to grayscale
image_rgb = cv2.imread('cir_cab2_upscaled.jpeg')
img = cv2.imread('cir_cab2_upscaled.jpeg', cv2.IMREAD_GRAYSCALE)
# Setting a threshold limit to convert all pixel below threshold to black and above to white
gray2 = np.zeros(img.shape)
gray2 [img < 210] = 255
gray2 [img > 130] = 0
plt.imshow(gray2, cmap = 'gray')
# output_img = output[:,pos[0]:pos[1]-1]
# for i in range(len(img_arr)):
edges = cv2.Canny(img, 100, 200)
dx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3, borderType=cv2.BORDER_REPLICATE)
dy = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3, borderType=cv2.BORDER_REPLICATE)
angle = np.zeros_like(img, dtype=np.float64)
y, x = np.where(edges > 0)
angle[y, x] = np.arctan2(dy[y, x], dx[y, x])
angle_degrees = np.degrees(angle)
plt.imshow(dy)
# Normalize angles to range [0, 1]
normalized_angles = (angle_degrees - angle_degrees.min()) / (angle_degrees.max() - angle_degrees.min())
# Scale to range [0, 255]
angle_visualization = (normalized_angles * 255).astype(np.uint8)
plt.imshow(angle_visualization, cmap='gray')
# User-defined threshold value
user_threshold_value = 120
# Binary thresholding
angle_visualization_inverted = cv2.bitwise_not(angle_visualization)
_, binary_thresholded = cv2.threshold(angle_visualization_inverted, user_threshold_value, 255, cv2.THRESH_BINARY)
# Otsu's thresholding
_, otsu_thresholded = cv2.threshold(angle_visualization_inverted, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Plotting
plt.figure(figsize=(20, 3))
# Original visualization
plt.subplot(1, 3, 1)
plt.imshow(angle_visualization_inverted, cmap='gray')
plt.title('Original Visualization')
plt.axis('off')
# Binary thresholded image
plt.subplot(1, 3, 2)
plt.imshow(binary_thresholded, cmap='gray')
plt.title('Binary Thresholded (User-defined)')
plt.axis('off')
# Otsu's thresholded image
plt.subplot(1, 3, 3)
plt.imshow(otsu_thresholded, cmap='gray')
plt.title("Otsu's Thresholded")
plt.axis('off')
# img_arr = [binary_thresholded]
img_arr = (otsu_thresholded)
# Find contours
bends = []
for j in range(len(img_arr)):
if j!=3:
continue
kernel = np.ones((5, 5), np.uint8)
img_dilation = cv2.dilate(img_arr[j], kernel, iterations=1)
contours, _ = cv2.findContours(img_dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Convert contours to a list so we can modify it
contours = list(contours)
# Iterate through contours in reverse order so we can safely remove contours from the list
for i in reversed(range(len(contours))):
# Calculate area of contour
area = cv2.contourArea(contours[i])
# If area is less than 5, remove the contour from the list
if area < 20:
contours.pop(i)
# Draw remaining contours on the RGB image in red
img_arr_rgb = cv2.cvtColor(img_arr[j], cv2.COLOR_GRAY2RGB)
contour_image = img_arr_rgb.copy()
cv2.drawContours(contour_image, contours, -1, (255, 0,0), -1)
bends.append(len(contours))
# for contour in contours:
# convexHull = cv2.convexHull(contour)
# cv2.drawContours(contour_image, [convexHull], -1, (0, 255, 0), 1)
contour_image
bends
enter image description here
enter image description here
Apparently I’ve taken the reference of a code that applies the same approach but is done on an image that has multiple shapes in it stored i a column, I need to find bends on one image at a time. But unfortunately upon modifying i am getting 0 bends as output. I guess maybe the lines formed between the image might be causing the issue .Code must run on both images
Please rectify and provide corrected code if possible