Spaces:
Sleeping
Sleeping
File size: 5,037 Bytes
990270d 291ef85 990270d 291ef85 990270d 291ef85 990270d 564b428 990270d 291ef85 990270d 564b428 990270d 564b428 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import gradio as gr
import cv2
import numpy as np
import os
from typing import Tuple, List
def detect_bends_and_angles(
image,
blur_kernel_size: int = 7,
canny_threshold1: int = 30,
canny_threshold2: int = 150,
dilation_kernel_size: int = 2,
hough_threshold: int = 50,
min_line_length: int = 10,
max_line_gap: int = 60,
bend_threshold: int = 15,
debug: bool = True
) -> Tuple[List[Tuple[int, int]], List[Tuple[Tuple[int, int], float]]]:
"""
Detect bends and calculate angles relative to horizontal with configurable parameters.
"""
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
if blur_kernel_size is None:
blur_kernel_size = 3
blur_kernel_size = max(3, blur_kernel_size | 1) # Ensure it's odd
blurred = cv2.GaussianBlur(gray, (blur_kernel_size, blur_kernel_size), 0)
edges = cv2.Canny(blurred, canny_threshold1, canny_threshold2)
kernel = np.ones((dilation_kernel_size, dilation_kernel_size), np.uint8)
dilated = cv2.dilate(edges, kernel, iterations=1)
height, width = dilated.shape
lines = cv2.HoughLinesP(
dilated, rho=1, theta=np.pi/180, threshold=hough_threshold,
minLineLength=min_line_length, maxLineGap=max_line_gap
)
bend_points = []
if lines is not None:
segments = []
for line in lines:
x1, y1, x2, y2 = line[0]
if x1 > x2:
x1, x2 = x2, x1
y1, y2 = y2, y1
segments.append((x1, y1, x2, y2))
segments.sort(key=lambda seg: seg[0], reverse=True)
for i in range(len(segments) - 1):
x1, y1, x2, y2 = segments[i]
x1_next, y1_next, x2_next, y2_next = segments[i + 1]
if abs(x1 - x1_next) < bend_threshold and abs(y1 - y1_next) < bend_threshold:
bend_points.append((x1, y1))
angles = []
for i in range(len(bend_points) - 1):
x1, y1 = bend_points[i]
x2, y2 = bend_points[i + 1]
dx, dy = x2 - x1, y2 - y1
angle = np.arctan2(dy, dx) * 180 / np.pi
angle = angle if angle >= 0 else angle + 180
angles.append((bend_points[i], angle))
return bend_points, angles
def process_image(
image,
blur_kernel_size: int,
canny_threshold1: int,
canny_threshold2: int,
dilation_kernel_size: int,
hough_threshold: int,
min_line_length: int,
max_line_gap: int,
bend_threshold: int
) -> Tuple[np.ndarray, str]:
"""
Process the image and return the visualization and angle measurements.
"""
if image is None:
return None, "Please upload an image."
if isinstance(image, dict):
image = image['image']
if isinstance(image, str):
image = cv2.imread(image)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
bend_points, angles = detect_bends_and_angles(
image, blur_kernel_size, canny_threshold1, canny_threshold2, dilation_kernel_size,
hough_threshold, min_line_length, max_line_gap, bend_threshold
)
result_img = image.copy()
for i, (x, y) in enumerate(bend_points):
cv2.circle(result_img, (x, y), 5, (0, 0, 255), -1)
cv2.putText(
result_img, f"Bend {chr(65 + i)}", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1
)
for (x, y), angle in angles:
cv2.putText(
result_img, f"{angle:.1f}°", (x, y + 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1
)
measurements = "Angle Measurements:\n"
for i, ((x, y), angle) in enumerate(angles):
measurements += f"Bend {chr(65 + i)} at ({x}, {y}): {angle:.1f}°\n"
return result_img, measurements
def create_gradio_interface():
interface = gr.Interface(
fn=process_image,
inputs=[
gr.Image(label="Input Image", type="numpy"),
gr.Slider(minimum=3, maximum=15, step=2, value=7, label="Blur Kernel Size"),
gr.Slider(minimum=0, maximum=100, step=10, value=30, label="Canny Threshold 1"),
gr.Slider(minimum=100, maximum=300, step=10, value=150, label="Canny Threshold 2"),
gr.Slider(minimum=1, maximum=5, step=1, value=2, label="Dilation Kernel Size"),
gr.Slider(minimum=10, maximum=100, step=10, value=50, label="Hough Threshold"),
gr.Slider(minimum=5, maximum=50, step=5, value=10, label="Minimum Line Length"),
gr.Slider(minimum=10, maximum=100, step=10, value=60, label="Maximum Line Gap"),
gr.Slider(minimum=5, maximum=30, step=5, value=15, label="Bend Threshold")
],
outputs=[
gr.Image(label="Result"),
gr.Textbox(label="Measurements", lines=10)
],
title="Angle Detection App",
description="Upload an image to detect bends and measure angles. Adjust parameters as needed."
)
return interface
if __name__ == "__main__":
interface = create_gradio_interface()
interface.launch(share=True) |