Я пытался воспроизвести оптическую иллюзию, которую вы найдете здесь (изображение), но у меня возникли проблемы с добавлением горизонтальных линий внутри кругов: Моя попытка до сих пор:
-Обнаружение определенных цветов кругов
-Обнаружение контуров и извлечение центральных точек круга и радиуса
-Тогда попробуйте нарисовать горизонтальные линии (что у меня не получилось)
Вот мой код:
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, большое спасибо! Я добавлю это как ответ. Не могли бы вы проверить мой код в ответах? В настоящее время это решает мою проблему, но я просто хотел убедиться, что сделал то, что вы имели в виду. Спасибо за ваше время.
Код выглядит нормально для того, что вы получаете, но я не думаю, что это то, что вы хотели, если вы хотели того же, что и в примере изображения, которое вы использовали в своей ссылке, где зеленые линии были над определенными кругами, красные над другими и синие над другие с полными полосами r, g, b позади них.
Да, я сейчас работаю над этим, я просто добавил круги и линии отдельно для каждого канала, я думаю, что я близок к тому, что хотел. Еще раз спасибо, @fmw42, большое спасибо за то, что поделились своими мыслями.
Хорошая работа. Держись! Не сдавайся.
Как отметил @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)
Ваши линии красные, зеленые и синие. Так что их можно разделить по каналам. Поэтому создайте маску для кругов для каждого канала и используйте маску, чтобы определить, какие цвета являются передними, а какие — задними, из масок. Таким образом, вы не рисуете линии внутри кругов, а только полные линии на изображении.