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

У меня есть 20 небольших изображений (которые я хочу поместить в целевую область фонового изображения (13x12). Я уже отметил свою целевую область кружком, у меня есть координаты круга в двух массивах пикселей. Теперь я хочу чтобы узнать, как я могу случайным образом добавить свои 20 маленьких изображений в случайную область в мои массивы пикселей, которые в основном являются целевой областью (нарисованный круг).

В моем коде я пытался использовать только одно изображение, если оно сработает, я передам папку с моими 20 маленькими изображениями.

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

# Depencies importation
import cv2
import numpy as np

# Saving directory
saving_dir = "../Saved_Images/"

# Read the background image
bgimg = cv2.imread("../Images/background.jpg")

# Resizing the bacground image
bgimg_resized = cv2.resize(bgimg, (2050,2050))

# Read the image that will be put in the background image (exemple of 1)
# I'm just trying with one, if it works, I'll pass the folder of the 20
small_img = cv2.imread("../Images/small.jpg")

# Convert the resized background image to gray
bgimg_gray = cv2.cvtColor(bgimg, cv2.COLOR_BGR2GRAY) 
# Convert the grayscale image to a binary image
ret, thresh = cv2.threshold(bgimg_gray,127,255,0)
# Determine the moments of the binary image
M = cv2.moments(thresh)
# calculate x,y coordinate of center
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])

# Drawing the circle in the background image
circle = cv2.circle(bgimg, (cX, cY), 930, (0,0,255), 9)

print(circle) # This returns None

# Getting the coordinates of the circle
combined = bgimg[:,:,0] + bgimg[:,:,1] + bgimg[:,:,2]
rows, cols = np.where(combined >= 0)

# I have those pixels in rows and cols, but I don't know
# How to randomly put my small image in those pixel

# Saving the new image
cv2.imwrite(saving_dir+"bgimg"+".jpg", bgimg)

cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.resizeWindow("Test", 1000, 1200)
# Showing the images
cv2.imshow("image", bgimg)
# Waiting for any key to stop the program execution
cv2.waitKey(0)

В ожидаемых результатах маленькие изображения должны располагаться на фоновом изображении случайным образом.

Почему в 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
0
160
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Если у вас есть центр и радиус вашего круга, вы можете легко сгенерировать случайные координаты, случайно выбрав угол theta из [0, 2*pi], вычислив соответствующие значения x и y с помощью cos(theta) и sin(theta) и масштабируя их с помощью некоторых случайно выбранных коэффициентов масштабирования из [0, radius]. Я подготовил для вас код, см. ниже.

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

import cv2
import numpy as np

# (Artificial) Background image (instead of reading an actual image...)
bgimg = 128 * np.ones((401, 401, 3), np.uint8)

# Circle parameters (obtained somehow...)
center = (200, 200)
radius = 100

# Draw circle in background image
cv2.circle(bgimg, center, radius, (0, 0, 255), 3)

# Shape of small image (known before-hand...?)
(w, h) = (13, 12)

for k in range(200):

    # (Artificial) Small image (instead of reading an actual image...)
    smallimg = np.uint8(np.add(128 * np.random.rand(w, h, 3), (127, 127, 127)))

    # Select random angle theta from [0, 2*pi]
    theta = 2 * np.pi * np.random.rand()

    # Select random distance factors from center
    factX = (radius - w/2) * np.random.rand()
    factY = (radius - h/2) * np.random.rand()

    # Calculate random coordinates for small image from angle and distance factors
    (x, y) = np.uint16(np.add((np.cos(theta) * factX - w/2, np.sin(theta) * factY - h/2), center))

    # Replace (rather than "add") determined area in background image with small image
    bgimg[x:x+smallimg.shape[0], y:y+smallimg.shape[1]] = smallimg

cv2.imshow("bgimg", bgimg)
cv2.waitKey(0)

Примерный вывод:

Output

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


Обновлено: Я отредактировал приведенный выше код. Чтобы учесть комментарий ниже, я сдвигаю маленькое изображение на (width/2, height/2) и соответственно ограничиваю масштабный коэффициент радиуса, чтобы граница круга не нарушалась ни сверху/слева, ни снизу/справа.

Ранее возможно нарушение границы в нижней/правой части (n = 200):

Violation

После редактирования это должно быть предотвращено (n = 20000):

No violation

Касание красной линии на изображении связано с толщиной линии. Из соображений безопасности можно было бы добавить еще расстояние в 1 пиксель.

Ваш код хорош, но маленькие изображения не должны выходить за границу круга. Вот почему я хотел использовать координаты круга, поэтому я пытаюсь адаптировать ваш код, чтобы он соответствовал моим потребностям. Я хочу найти способ сказать своим маленьким изображениям, что они должны оставаться внутри круга. У меня есть координата круга со следующим: # Getting the coordinates of the circle combined = bgimg[:,:,0] + bgimg[:,:,1] + bgimg[:,:,2] rows, cols = np.where(combined >= 0) Но я пока не нашел, как это сделать. Когда я печатаю строки, столбцы представляют собой массивы пикселей. Спасибо @HansHirse

EE2017 10.04.2019 14:36

@EE2017 Если бы вы ответили на мой вопрос о фигурах, вписывающихся в круг stackoverflow.com/q/55576760/2836621, а не проигнорировали меня и снова задали почти тот же вопрос, вы бы не тратили впустую время Ганса, которое он так щедро отдает...

Mark Setchell 10.04.2019 15:09

@MarkSetchell, я тебе ответил. Когда я ответил, я уже решил первый вопрос. Я просто искал способ преобразовать мои координаты круга, которые у меня есть, как массив пикселей. Мне очень жаль, если вы так себя чувствовали; но я не игнорировал тебя. Пожалуйста, примите во внимание мои извинения. Это сообщество слишком велико, чтобы кому-то было грустно. Еще раз прошу прощения. Позвольте мне взглянуть на ответ #HansHirse сейчас...

EE2017 10.04.2019 15:19

@HansHirse Большое спасибо, ваш ответ / код решил мою проблему. Я не думал об использовании угла. К сожалению, у меня недостаточно репутации, чтобы проверить ваш ответ, надеюсь, кто-то, кто может, сделает это. Еще раз спасибо гений.

EE2017 10.04.2019 15:25

@ EE2017 Я вижу, вы не можете голосовать в данный момент, но вы должны иметь возможность пометить мой ответ как принятый, или я ошибаюсь?

HansHirse 10.04.2019 17:01

@HansHirse, я думал, что для меня это тоже деактивировано, так как я еще не могу голосовать. Теперь все готово, еще раз спасибо. Правда в том, что я полирую ваш код, чтобы заставить его делать что-то гораздо более сложное (например, получение входных изображений из разных папок, использование вложенного цикла...). Но основа ваша. Спасибо еще раз,

EE2017 10.04.2019 17:09

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