Python cv2图像金字塔

时间:2016-04-26 14:57:56

标签: python-2.7 opencv numpy image-processing

尝试实现着名的橙色/ Apple金字塔混合(cv2 Image Pyramids)。

注意:两个图像的形状都是307x307。

但是,由于cv2.subtractcv2.add中的裁剪值导致结果图像模糊(如cv2 vs numpy Matrix Arithmetics中所述),我使用numpy算术代替了建议在StackOverflow: Reconstructed Image after Laplacian Pyramid Not the same as original image

我通过在一个图像上执行金字塔来测试这个,并且使用金字塔构造的结果图像具有相同的Max,Min,Average像素值,而不是使用cv2算术。

但是,在金字塔等级7上,结果图像会产生“噪音”。一个红点和9级结果图像得到很多绿色像素噪声。 Images of levels 6, 7, 9 - Imgur Album

任何想法为什么会发生这种情况?我想说的金字塔等级9绿色噪音是因为图像低于1x1的形状。但7级金字塔上的红点呢?

  • 编辑:已添加代码

    numberOfPyramids = 9
    
    # generate Gaussian pyramids for A and B Images
    GA = A.copy()
    GB = B.copy()
    gpA = [GA]
    gpB = [GB]
    
    for i in xrange(numberOfPyramids):
        GA = cv2.pyrDown(GA)
        GB = cv2.pyrDown(GB)
        gpA.append(GA)
        gpB.append(GB)
    
    # generate Laplacian Pyramids for A and B Images
    lpA = [gpA[numberOfPyramids - 1]]
    lpB = [gpB[numberOfPyramids - 1]]
    
    for i in xrange(numberOfPyramids - 1, 0, -1):
        geA = cv2.pyrUp(gpA[i], dstsize = np.shape(gpA[i-1])[:2]) 
        geB = cv2.pyrUp(gpB[i], dstsize = np.shape(gpB[i-1])[:2])
    
        laplacianA = gpA[i - 1] - geA if i != 1 else cv2.subtract(gpA[i-1], geA)
        laplacianB = gpB[i - 1] - geB if i != 1 else cv2.subtract(gpB[i-1], geB)
    
        lpA.append(laplacianA)
        lpB.append(laplacianB)
    
    # Now add left and right halves of images in each level
    LS = []
    for la, lb in zip(lpA, lpB):
        _, cols, _ = la.shape
        ls = np.hstack((la[:, : cols / 2], lb[:, cols / 2 :]))
        LS.append(ls)
    
    # now reconstruct
    ls_ = LS[0]
    for i in xrange(1, numberOfPyramids):
        ls_ = cv2.pyrUp(ls_, dstsize = np.shape(LS[i])[:2])
        ls_ = ls_ + LS[i] if i != numberOfPyramids - 1 else cv2.add(ls_, LS[i])
    
    cv2.imshow(namedWindowName, ls_)
    cv2.waitKey()
    

1 个答案:

答案 0 :(得分:1)

在阅读了关于拉普拉斯金字塔的原始article之后,我发现我误解了这种方法,我们可以完全重建原始图像而不会模糊,因为我们使用了额外的像素信息。而裁剪值确实会导致模糊。那么现在我们又回到了开头:)

所以你发布的代码仍然是剪切值,我建议你使用int16来保存laplacian金字塔,而不是使用cv2.subtract。希望它有效。