Обнаружение определенного цвета в круглой области и добавление горизонтальных линий внутри круга

Я пытался воспроизвести оптическую иллюзию, которую вы найдете здесь (изображение), но у меня возникли проблемы с добавлением горизонтальных линий внутри кругов: Моя попытка до сих пор:

-Обнаружение определенных цветов кругов

-Обнаружение контуров и извлечение центральных точек круга и радиуса

-Тогда попробуйте нарисовать горизонтальные линии (что у меня не получилось)

Вот мой код:

import numpy as np
import cv2

img = 255*np.ones((800, 800, 3), np.uint8)
height, width,_ = img.shape

#filling the image with lines
for i in range(0, height, 15):
    cv2.line(img, (0, i+3), (width, i+3), (255, 0, 0), 4)
    cv2.line(img, (0, i+8), (width, i+8), (0, 255, 0), 4)
    cv2.line(img, (0, i+13), (width, i+13), (0, 0, 255), 4)

#adding 5 gray circles
for i in range(0, height, int(height/5)):
        cv2.circle(img, (i+50, i+50), 75, (128, 128, 128), -1) 
#finding rannge of gray circles
lower=np.array([127,127,127])
upper=np.array([129,129,129])
mask = cv2.inRange(img, lower, upper)

#contours
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    #draw circles around the contours
    coordinates = cv2.minEnclosingCircle(cnt)
     #coordinates and radius:
    center = (int(coordinates[0][0]), int(coordinates[0][1]))
    radius = int(coordinates[1])
    #I wanted to do a sanity check before the for loop (I added a line the longest line should be 2*radius)
    cv2.line(img, (center[0]-radius, center[1]), (center[0]+radius, center[1]), (0, 0, 0), 4)
    
    for i in range(0, radius, int(radius/5)):
        cv2.line(img, (center[0]-radius+i, center[1]+i), (center[0]+radius-i, center[1]+i), (0, 0, 0), 4)
        cv2.line(img, (center[0]-radius+i, center[1]-i), (center[0]+radius-i, center[1]-i), (0, 0, 0), 4)
        

cv2.imwrite('munker.png',img)

И вот результат:

Как видите, значения в цикле for не пропорциональны границам круга, поэтому строки короткие (кроме самой длинной). Что мне здесь не хватает?

Я попробовал преобразование Хафа, но у меня была похожая проблема.

Для большей ясности я пишу код, чтобы показать, что я хотел:

 for i in range(0, 360, 15):
        x = int(center[0] + radius * np.cos(np.deg2rad(i)))
        y = int(center[1] + radius * np.sin(np.deg2rad(i)))
        cv2.line(img, (x,y), (x, y), (0, 255, 255), 10)

Я хочу объединить желтые точки с горизонтальными линиями. Но моя математика закончена прямо здесь. Извините, это длинно, я просто пытался прояснить ситуацию. Спасибо за ваше время.

Ваши линии красные, зеленые и синие. Так что их можно разделить по каналам. Поэтому создайте маску для кругов для каждого канала и используйте маску, чтобы определить, какие цвета являются передними, а какие — задними, из масок. Таким образом, вы не рисуете линии внутри кругов, а только полные линии на изображении.

fmw42 19.11.2022 18:10

Какое отличное решение, ты герой @fmw42, большое спасибо! Я добавлю это как ответ. Не могли бы вы проверить мой код в ответах? В настоящее время это решает мою проблему, но я просто хотел убедиться, что сделал то, что вы имели в виду. Спасибо за ваше время.

AltunE 19.11.2022 19:18

Код выглядит нормально для того, что вы получаете, но я не думаю, что это то, что вы хотели, если вы хотели того же, что и в примере изображения, которое вы использовали в своей ссылке, где зеленые линии были над определенными кругами, красные над другими и синие над другие с полными полосами r, g, b позади них.

fmw42 19.11.2022 19:59

Да, я сейчас работаю над этим, я просто добавил круги и линии отдельно для каждого канала, я думаю, что я близок к тому, что хотел. Еще раз спасибо, @fmw42, большое спасибо за то, что поделились своими мыслями.

AltunE 19.11.2022 20:47

Хорошая работа. Держись! Не сдавайся.

fmw42 19.11.2022 22:46
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как отметил @fmw42 в комментарии, разделение каналов RGB и применение маски очень эффективно для заполнения внутренней части кругов горизонтальными линиями.

import numpy as np
import cv2

img = 255*np.ones((800, 800, 3), np.uint8)
height, width,_ = img.shape
for i in range(0, height, 15):
    cv2.line(img, (0, i+3), (width, i+3), (255, 0, 0), 4)
    cv2.line(img, (0, i+8), (width, i+8), (0, 255, 0), 4)
    cv2.line(img, (0, i+13), (width, i+13), (0, 0, 255), 4)
b, g, r = cv2.split(img)
mask_b = np.zeros((height, width), np.uint8)
mask_g = np.zeros((height, width), np.uint8)
mask_r = np.zeros((height, width), np.uint8)
for i in range(0, height, int(height/5)):
    cv2.circle(mask_b, (i, i), 75, 255, -1)
    cv2.circle(mask_g, (i, i), 75, 255, -1)
    cv2.circle(mask_r, (i, i), 75, 255, -1)

#apply the mask to the channels
b = cv2.bitwise_and(b, b, mask=mask_b)
g = cv2.bitwise_and(g, g, mask=mask_g)
r = cv2.bitwise_and(r, r, mask=mask_r)
#merge the channels
img = cv2.merge((b, g, r))

cv2.imshow('image', img)
cv2.waitKey(0)

Другие вопросы по теме