[Это теперь решено. Я разместил свой обновленный код внизу моего вопроса для справки].
Я пытаюсь создать программу на Python для автоматического наложения небольшого изображения на большое изображение для списка координат. Я могу заставить его работать для одного примера одного маленького изображения на большом изображении, но не тогда, когда я пытаюсь повторить это несколько раз. Я был бы признателен, если бы кто-нибудь указал на ошибку в моем коде (надеюсь, это довольно просто, я не уверен в Python).
Цель кода — найти самые яркие точки на изображении (в данном случае изображение звездного поля), использовать порог, эрозию, процесс расширения для выделения самых ярких/самых больших звезд. Затем используется функция findContours, и вокруг каждого контура рисуется прямоугольник. Центральные координаты каждого прямоугольника рассматриваются как пиксельные координаты этой звезды. Затем я пытаюсь использовать эти координаты для наложения меньшего изображения на базовое изображение в каждой позиции, где обнаружена яркая звезда. По какой-то причине это не работает, и я был бы очень признателен за некоторую помощь, спасибо.
Поиск в Google и поиск в стеке, которые я пробовал, не привели к коду, который я мог бы сымитировать, к сожалению, и я не смог успешно закодировать его самостоятельно.
Это код, который я использовал для наложения одного изображения на базовое изображение, и он работает правильно:
import cv2
import numpy as np
fg_img = cv2.imread("image_small.png")
bg_img = cv2.imread("image_big.png")
cv2.imshow('small',fg_img)
cv2.imshow('big',bg_img)
h1, w1 = fg_img.shape[:2]
print (h1, w1)
pip_h = 10
pip_w = 10
bg_img[pip_h:pip_h+h1,pip_w:pip_w+w1] = fg_img
cv2.imshow('overlaid', bg_img)
cv2.waitKey(0)
И это код, который я пытаюсь заставить работать:
import imutils
import cv2
fg_img = cv2.imread("image_small.png")
bg_img = cv2.imread("image_big.png")
graybg = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY)
h1, w1 = fg_img.shape[:2]
##print(h1, w1)
thresh = cv2.threshold(graybg, 225, 255, cv2.THRESH_BINARY)[1]
mask = thresh.copy()
mask = cv2.erode(mask, None, iterations=1)
mask2 = mask.copy()
mask2 = cv2.dilate(mask2, None, iterations = 2)
h2, w2 = mask2.shape[:2]
print(h2, w2)
cnts = cv2.findContours(mask2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
output = mask2.copy()
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
print(x,y)
pip_h = y
pip_w = x
mask2[pip_h:pip_h+h1,pip_w:pip_w+w1] = fg_img
cv2.imshow("Contours", output)
cv2.waitKey(0)
Сообщение об ошибке, которое я получаю при запуске второй воспроизведенной выше программы, гласит: «ValueError: не удалось передать входной массив из формы (82,70,3) в форму (11,70)». Для справки, разрешение меньшего изображения было 82x70, разрешение большого изображения на самом деле было 1920x1080...
Еще раз спасибо за чтение, я надеюсь, что ошибка легко разрешима. Спасибо
ИСПРАВЛЕННЫЙ КОД:
import imutils
import cv2
fg_img = cv2.imread("image_small.png")
bg_img = cv2.imread("image_big.png")
graybg = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY)
h1, w1 = fg_img.shape[:2]
print(h1, w1)
thresh = cv2.threshold(graybg, 225, 255, cv2.THRESH_BINARY)[1]
mask = thresh.copy()
mask = cv2.erode(mask, None, iterations=1)
mask2 = mask.copy()
mask2 = cv2.dilate(mask2, None, iterations = 2)
h2, w2 = mask2.shape[:2]
print(h2, w2)
cnts = cv2.findContours(mask2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
pip_h = y
pip_w = x
print(pip_h, pip_w)
if h2 - pip_h > h1 + 1 and w2 - pip_w > w1 + 1:
bg_img[pip_h:pip_h+h1,pip_w:pip_w+w1] = fg_img
cv2.imshow("Contours", bg_img)
cv2.waitKey(0)