'Get Laplacian pyramid using opencv
I'm trying to get a layer of the Laplacian pyramid using the opencv functions: pyrUp and pyrDown.
In the documentation and in more detail in this book, I found that the i-th Laplacian layer should be obtained by the following expression:
Li = Gi - pyrDown(Gi+1)
where Gi is the i-th layer of the Gaussian pyramid.
What I've tried is:
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)
But I get different sizes of the images involved in the substraction. I don't understand it because pyrUp is suppposed to invert the process of the Gaussian pyramid, i.e. pyrDown (with a lose of information of course but that should not affect the size, right?).
UPDATE
I refactored my code to:
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
As you can see, I force the destination image to be of the same size of the source with the parameter dstsize of the pyrUp function.
However, this code also gives me an error when when executing the pyrUp function. The message of the error is:
OpenCV Error: Assertion failed (std::abs(dsize.width - ssize.width*2) == dsize.width % 2 && std::abs(dsize.height - ssize.height*2) == dsize.height % 2) in pyrUp_,
In debug mode I checked the expression of the assertion with:
up.shape[1]-down.shape[1]*2 == up.shape[1] %2 and up.shape[0]-down.shape[0]*2 == up.shape[0] %2
and it is satisfied.
So, I don't have a clue of what is happening.
Solution 1:[1]
Here is an example of what I think is happening:
After the last iteration lets say gi_prev size is 11x11, so gi size is 5x5 (because it can't be 5.5x5.5). Then pyrup will be 10x10, not 11x11.
I would print out the sizes and check whether this is the case.
Solution 2:[2]
However, this code also gives me an error when when executing the pyrUp >function. The message of the error is:
OpenCV Error: Assertion failed (std::abs(dsize.width - ssize.width*2) == >dsize.width % 2 && std::abs(dsize.height - ssize.height*2) == dsize.height % >2) in pyrUp_,
Many years late to the party here, but here we go. When passing the upscaled image size using 'dstsize:
up = cv2.pyrUp(down, dstsize=currImg.shape)
the .shape method returns height x width. However, the pyrup function requires these dimensions as width x height. Therefore try the following code:
up = cv2.pyrUp(down, dstsize=(currImg.shape[1],currImg.shape[0])
Solution 3:[3]
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("c:/samples/lena.jpg")
layer = img.copy()
gp = [layer]
for i in range(6):
layer = cv2.pyrDown(layer)
gp.append(layer)
cv2.imshow(str(i),layer)
layer = gp[5]
cv2.imshow('upper',layer)
lp = [layer]
for i in range(5,0,-1):
guassian_extended = cv2.pyrUp(gp[i])
laplacian = cv2.subtract(gp[i-1],guassian_extended)
cv2.imshow(str(i),laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Bull |
| Solution 2 | Stevie Cuzz |
| Solution 3 | Majid |
