image = cv2.imread(“0.0/00.pgm”)


%time
import numpy as np
import matplotlib.pyplot as plt
from math import atan2, degrees


def gaussian_filter(image: np.ndarray, sigma: float=1.5) -> np.ndarray:
“”“Returns image with gaussian filter.”“”
size = int(2 * np.ceil(3 * sigma) + 1)

kernel = np.fromfunction(
lambda x, y: (1 / (2 * np.pi * sigma**2)) * np.exp(
-((x - size//2)**2 + (y - size//2)2) / (2 * sigma2)), (size, size))

smoothed_image = np.zeros_like(image)

for i in range(image.shape[0]):
for j in range(image.shape[1]):
neighborhood = image[max(i-size//2, 0):min(i+size//2+1, image.shape[0]), max(j-size//2, 0):min(j+size//2+1, image.shape[1])]
smoothed_image[i, j] = np.sum(neighborhood * kernel[:neighborhood.shape[0], :neighborhood.shape[1]])

return smoothed_image


def sobel_operator(image):
kernel_x = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
kernel_y = np.array([[-1, -2, -1],
[0, 0, 0],
[1, 2, 1]])
gradient_x = np.zeros_like(image)
gradient_y = np.zeros_like(image)
for i in range(image.shape[0] - 2):
for j in range(image.shape[1] - 2):
neighborhood = image[i:i+3, j:j+3]
gradient_x[i+1, j+1] = np.sum(neighborhood * kernel_x)
gradient_y[i+1, j+1] = np.sum(neighborhood * kernel_y) 
edges = np.hypot(gradient_x, gradient_y)
return edges


def binary_threshold(image, threshold):
binary_image = np.zeros_like(image)
binary_image[image > threshold] = 1
return binary_image


def binary_closing(image, iterations=1):
closed_image = np.copy(image)
for i in range(iterations):
dilated_image = np.maximum(closed_image, np.maximum(np.roll(closed_image, 1, axis=0), np.roll(closed_image, -1, axis=0)))
dilated_image = np.maximum(dilated_image, np.maximum(np.roll(dilated_image, 1, axis=1), np.roll(dilated_image, -1, axis=1)))
closed_image = np.minimum(closed_image, dilated_image)
return closed_image


def binary_opening(image, iterations=1):
opened_image = np.copy(image)
for i in range(iterations):
eroded_image = np.minimum(opened_image, np.minimum(np.roll(opened_image, 1, axis=0), np.roll(opened_image, -1, axis=0)))
eroded_image = np.minimum(eroded_image, np.minimum(np.roll(eroded_image, 1, axis=1), np.roll(eroded_image, -1, axis=1)))
opened_image = np.maximum(opened_image, eroded_image)
return opened_image


def probabilistic_hough_line(image, threshold, line_length, line_gap):
lines = []
indices = np.argwhere(image > threshold)
x_coords, y_coords = indices[:, 1], indices[:, 0]
while len(indices) > 0:
x1, y1 = x_coords[0], y_coords[0]
distances = np.abs((x_coords - x1) + (y_coords - y1) * 1j)
line_indices = np.where(distances < line_length)[0]
line_x_coords = x_coords[line_indices]
line_y_coords = y_coords[line_indices]
x2, y2 = line_x_coords[-1], line_y_coords[-1]
lines.append([(x1, y1), (x2, y2)])
line_indices = np.where((x_coords >= x1-line_gap) & (x_coords <= x2+line_gap) &
(y_coords >= y1-line_gap) & (y_coords <= y2+line_gap))[0]
x_coords = np.delete(x_coords, line_indices)
y_coords = np.delete(y_coords, line_indices)
return np.array(lines)


def label(image):
labeled_image = np.zeros_like(image)
current_label = 1
for i in range(image.shape[0]):
for j in range(image.shape[1]):
if image[i, j] == 1 and labeled_image[i, j] == 0:
stack = [(i, j)]
while len(stack) > 0:
x, y = stack.pop()
labeled_image[x, y] = current_label
for m in range(max(x-1, 0), min(x+2, image.shape[0])):
for n in range(max(y-1, 0), min(y+2, image.shape[1])):
if image[m, n] == 1 and labeled_image[m, n] == 0:
stack.append((m, n))
current_label += 1
return labeled_image, current_label - 1


def detect_triangle_angles(image):
# Сглаживаем изображение для удаления шума
smoothed_image = gaussian_filter(image, sigma=1.5)

# Применяем оператор Собеля для выделения границ
edges = sobel_operator(smoothed_image)

# Применяем пороговую обработку для получения бинарного изображения
threshold_image = binary_threshold(edges, threshold=0.2)

# Замыкаем линии и объединяем границы треугольника
closed_image = binary_closing(threshold_image, iterations=3)

# Разделяем связанные границы треугольника
opened_image = binary_opening(closed_image, iterations=2)

# Используем алгоритм Хафа для поиска линий
lines = probabilistic_hough_line(opened_image, threshold=10, line_length=10, line_gap=3)

# Применяем фильтр к найденным линиям для удаления ненужных сегментов
labeled_image, num_labels = label(opened_image)
for i in range(1, num_labels + 1):
indices = np.argwhere(labeled_image == i)
if len(indices) < 50: # Фильтр сегментов по длине
opened_image[tuple(indices.T)] = 0

# Используем найденные границы для определения углов треугольника
angles = []
for line in lines:
x1, y1 = line[0]
x2, y2 = line[1]
angles.append(degrees(atan2(y2 - y1, x2 - x1)))

return angles

# Пример использования
# image_path = “example.jpg’ # Путь к изображению
# image = load_image(image_path)
# angles = detect_triangle_angles(image)
# print(‘Углы треугольника:’, angles)
angles = detect_triangle_angles(image)
print(f"Corners of 3angle: {angles}”)



Получаю на этот код ошибку:
21 for j in range(image.shape[1]):
22 neighborhood = image[max(i-size//2, 0):min(i+size//2+1, image.shape[0]), max(j-size//2, 0):min(j+size//2+1, image.shape[1])]
—> 23 smoothed_image[i, j] = np.sum(neighborhood * kernel[:neighborhood.shape[0], :neighborhood.shape[1]])
24 
25 return smoothed_image

ValueError: operands could not be broadcast together with shapes (6,6,3) (6,6