python - 如何在某些坐标上将多个图像叠加到基础图像上?
问题描述
【现在解决了。我已经在我的问题底部发布了我的更新代码以供参考]。
我正在尝试在 Python 中创建一个程序,以自动将小图像叠加到大图像上以获得坐标列表。我可以让它为一个小图像的单个示例工作到一个更大的图像,但当我尝试多次重复此操作时却不行。如果有人能指出我的代码中的错误,我将不胜感激(我希望这可能是非常基本的,我对 Python 没有信心)。
代码的目的是找到图像中最亮的点(在本例中为星场图像),使用阈值、腐蚀、膨胀过程来隔离最亮/最大的星星。然后使用 findContours 函数,并在每个轮廓周围绘制一个矩形。每个矩形的中心坐标被视为该星的像素坐标。然后,我尝试使用这些坐标将较小的图像叠加到检测到亮星的每个位置的基本图像上。由于某种原因它不起作用,我将非常感谢您的帮助,谢谢。
不幸的是,我尝试过的谷歌搜索和堆栈搜索都没有找到一些我可以模仿的代码,而且我自己也无法成功编写代码。
这是我用来将单个图像叠加到基本图像上的代码,它可以正常工作:
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)
解决方案
您的代码的问题在于,在 for 循环中:
x,y,w,h = cv2.boundingRect(c)
如果pip_h=y
接近原始图像的高度h2
,则进行切片操作
mask2[pip_h:pip_h+h1]
只会给你h2 - pip_h
行。作为一个极端,想想当 时会发生什么pip_h=h2
。
简而言之,克隆操作
mask2[pip_h:pip_h+h1,pip_w:pip_w+w1] = fg_img
失败时h2 - pip_h < h1
或w2 - pip_w < w1
由于上述原因。
推荐阅读
- php - 如何将数据从数据库 Laravel 传递到父布局
- node.js - 贝宝订阅和计费协议之间的区别?
- amazon-web-services - Lambda 未触发 SNS
- r - 在 as.POSIXct 中更改时区
- c++ - Maybe 和 Either 单子、短路和性能
- python - AttributeError:“int”对象没有属性“to_dict”
- arkit - generateCollisionShapes() 似乎不起作用
- c++ - 无论我运行同一个应用程序多少次,应用程序(.exe)中的函数都应该只调用一次
- linux - 将字符串添加到 awk 命令的末尾
- c++ - 函数返回错误的结果。查找 n 阶乘的最后一个非零数字