Как на изображение найти полукруг и получить его координаты?

В продолжение темы

Подскажите как адаптировать код под определение полукруга?

введите сюда описание изображения

import numpy as np
import cv2

 
def detect_semilar_circle(image_file_name):
    # print(image_file_name)
    # создаём шаблон нашего круга, который будем искать
    r = 10  # радиус
    # image_template = np.zeros((r * 2 + 1, r * 2 + 1), np.uint8)
    # cv2.circle(image_template, (r, r), r, 255, -1)

    image_template = np.zeros((r * 2 + 1, r * 2 + 1), np.uint8)
    cv2.ellipse(image_template, (r, r), (r, r), 0, 0, 180, 255)


    # входная картинка
    image = cv2.imread(image_file_name)
    # добавим немного пикселей с каждой стороны
    # чтобы компенсировать возможно обрезанный круг
    image = cv2.copyMakeBorder(image, *[r // 2] * 4, cv2.BORDER_REPLICATE)
    image_output = image.copy()

    # конвертация в grayscale
    image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # найдём максимальную яркость
    # будем использовать её как границу между чёрным и белым
    pixels = dict(zip(*np.unique(image_gray, return_counts=True)))
    max_pixel = sorted(pixels.keys())[-1]
    # конвертация в чёрно-белое
    # image_bw = cv2.threshold(image_gray, max_pixel - 1, 255, cv2.THRESH_BINARY)[1]
    image_bw = cv2.threshold(image_gray, max_pixel - 70, 255, cv2.THRESH_BINARY)[1]

    # подсчитаем количество чёрных и белых пикселей
    pixels = dict(zip(*np.unique(image_bw, return_counts=True)))
    if pixels[0] < pixels[255]:
        # похоже, что мы имеем тёмные элементы на светлом фоне
        # так что делаем из нашего шаблона круга негатив
        image_template = cv2.bitwise_not(image_template)

    x, y = cv2.minMaxLoc(cv2.matchTemplate(image_bw, image_template, cv2.TM_CCOEFF_NORMED))[-1]

    # всякая демонстрационная фигня
    print(f"Center: {x},{y}   Radius: {r}")

    # обведём найденный круг
    cv2.circle(image_output, (x + r, y + r), r, (0, 255, 0), 1)
    # cv2.ellipse(image_output, (x + r, y + r), (r, r), 115, 0, 180, (0, 255, 0))
    # и ткнём точку в центр
    cv2.circle(image_output, (x + r, y + r), 2, (255, 0, 255), -1)

    cv2.imshow("The result", np.hstack(
        [image, cv2.cvtColor(image_gray, cv2.COLOR_GRAY2BGR), cv2.cvtColor(image_bw, cv2.COLOR_GRAY2BGR),
         image_output]))
    cv2.waitKey(0)
    # конец всякой демонстрационной фигни

    return x, y

print(detect_semilar_circle(img_path))

введите сюда описание изображения

не находит


Ответы (0 шт):