我正在尝试使用opencv函数获取一层拉普拉斯金字塔:pyrUp
和pyrDown
。
在documentation以及此book中的更详细信息中,我发现 i-th 拉普拉斯图层应通过以下表达式获取:
Li = Gi - pyrDown(Gi + 1)
其中Gi是高斯金字塔的第i层。
我尝试的是:
def get_laplacian_pyramid_layer(img, n):
gi = img
for i in range(n):
gi_prev = gi
gi = cv2.pyrDown(gi_prev)
pyrup = cv2.pyrUp(gi)
return cv2.addWeighted(gi_prev, 1.5, pyrup, -0.5, 0)
但是我得到了减法中涉及的不同尺寸的图像。我不理解它,因为pyrUp
被用来反转高斯金字塔的过程,即pyrDown(当然丢失信息但不应该影响大小,对吧?)。
更新
我将我的代码重构为:
def get_laplacian_pyramid_layer(img, n):
'''Returns the n-th layer of the laplacian pyramid'''
currImg, i = img, 0
while i < n: # and currImg.size > max_level (83)
down, up = new_empty_img(img.shape), new_empty_img(img.shape)
down = cv2.pyrDown(img)
up = cv2.pyrUp(down, dstsize=currImg.shape)
lap = currImg - up
currImg = down
i += 1
return lap
如您所见,我使用dstsize
函数的参数pyrUp
强制目标图像与源的大小相同。
但是,在执行pyrUp
函数时,此代码也会出错。错误消息是:
OpenCV错误:断言失败(std :: abs(dsize.width - ssize.width * 2)== dsize.width%2&amp;&amp; std :: abs(dsize.height - ssize.height * 2) == dsize.height%2)在pyrUp _,
中
在调试模式下,我用以下方法检查了断言的表达式:
up.shape[1]-down.shape[1]*2 == up.shape[1] %2 and up.shape[0]-down.shape[0]*2 == up.shape[0] %2
并且满意。
所以,我不知道发生了什么。
答案 0 :(得分:1)
以下是我认为正在发生的事情的一个例子:
在最后一次迭代后,假设gi_prev大小为11x11,因此gi大小为5x5(因为它不能是5.5x5.5)。然后pyrup将是10x10,而不是11x11。
我会打印尺寸并检查是否是这种情况。
答案 1 :(得分:1)
据我所知,您在每次迭代中都在输入图像 img 上使用pyrDown
down = cv2.pyrDown(img)
我建议你将该行更改为
down = cv2.pyrDown(currImg)
所以你实际上计算下一个金字塔图层。
出错的原因是你的下图。与输入图像
相比,它的形状宽度/ 2 x高度/ 2down = cv2.pyrDown(img)
但是你尝试将它的pyrUp结果(宽度*高度)存储在一个小得多的图像中,其形状因为
而变小(宽度/ 2 x高度/ 2)up = cv2.pyrUp(down, dstsize=currImg.shape)
...
currImg = down
即使我的答案为时已晚,也许它会帮助其他人
答案 2 :(得分:0)
但是,执行pyrUp&gt;函数时,此代码也会出错。错误消息是:
OpenCV错误:断言失败(std :: abs(dsize.width - ssize.width * 2)==&gt; dsize.width%2&amp;&amp; std :: abs(dsize.height - ssize.height * 2)== dsize.height%&gt; 2)在pyrUp _,
这里聚会很晚很多年,但是我们走了。使用&#39; dstsize:
传递放大的图像大小时up = cv2.pyrUp(down, dstsize=currImg.shape)
.shape方法返回height x width。然而,pyrup函数需要这些尺寸作为宽度x高度。因此,请尝试以下代码:
up = cv2.pyrUp(down, dstsize=(currImg.shape[1],currImg.shape[0])