Обнаружение кругов на фотографии с использованием HoughCircles
Здравствуйте! Делал прогу для распознавания количество круглых труб на фото, использовал cv2.HoughCircles, настраивал все параметры что бы отрегулировать распознание кругов:
circles = cv2.HoughCircles(
image,
cv2.HOUGH_GRADIENT,
dp=1.2,
minDist=20, # Минимальное расстояние между центрами кругов
param1=388, # Порог для градиентного детектора
param2=65, # Порог для акцепта круга
minRadius=5, # Минимальный радиус круга
maxRadius=95 # Максимальный радиус круга
)
Использовал эти же параметры для распознания труб на другой фотке, но там это работает совсем по другому, вот результат:
Помогите разобраться пожалуйста??
Исходный код:
import cv2
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
def load_data(annotation_file):
data = pd.read_csv(annotation_file)
image_paths = data['img_path'].tolist()
pipe_counts = data['pipe_count'].tolist()
return image_paths, pipe_counts
def preprocess_image(image_path):
"""
Предобработка изображения: преобразование в градации серого и размытие.
"""
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
blurred = cv2.GaussianBlur(image, (7, 7), 1) # Попробуйте разные размеры
return blurred
def detect_circles(image):
"""
Обнаружение кругов на изображении с использованием Hough Circle Transform.
"""
circles = cv2.HoughCircles(
image,
cv2.HOUGH_GRADIENT,
dp=1.2,
minDist=20, # Минимальное расстояние между центрами кругов
param1=388, # Порог для градиентного детектора
param2=65, # Порог для акцепта круга
minRadius=5, # Минимальный радиус круга
maxRadius=95 # Максимальный радиус круга
)
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
# Фильтрация кругов по радиусу
filtered_circles = [circle for circle in circles if 10 < circle[2] < 100]
# Опциональная дополнительная фильтрация для обеспечения полноты круга
valid_circles = []
for (x, y, r) in filtered_circles:
if is_complete_circle(image, x, y, r):
valid_circles.append((x, y, r))
return np.array(valid_circles)
return []
def is_complete_circle(image, x, y, r):
"""
Проверка, является ли обнаруженный круг полноценным, а не частичным.
"""
# Определение области изображения, содержащей круг
mask = np.zeros_like(image, dtype=np.uint8)
cv2.circle(mask, (x, y), r, 255, -1)
# Получение пикселей круга
circle_pixels = cv2.bitwise_and(image, mask)
# Проверка, что круг заполнен (более 50% пикселей круга должны быть белыми)
circle_area = np.sum(mask > 0)
filled_area = np.sum(circle_pixels > 0)
return filled_area / circle_area > 0.5
def split_data(image_paths, pipe_counts, test_size=0.2):
return train_test_split(image_paths, pipe_counts, test_size=test_size, random_state=42)
def extract_features(image_paths):
images = [preprocess_image(image_path) for image_path in image_paths]
features = [len(detect_circles(image)) for image in images]
return np.array(features).reshape(-1, 1)
def draw_circles(image_path, circles):
"""
Рисование обнаруженных кругов на изображении.
"""
image = cv2.imread(image_path)
for (x, y, r) in circles:
cv2.circle(image, (x, y), r, (0, 255, 0), 2) # Рисуем круги
cv2.rectangle(image, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1) # Рисуем центр
cv2.imshow('Detected Circles', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Ответы (1 шт):
Автор решения: MBo
→ Ссылка
Круги, наблюдаемые под углом - эллипсы, причём их эксцентриситет меняется по мере изменения угла зрения на торец трубы
Чтобы обнаружить эллипсы, попробуйте SimpleBlobDetector или выделить контуры и подогнать их эллипсами, фильтруя по нужным параметрам