Python cv2图像金字塔

4

尝试实现著名的橙子/苹果金字塔混合(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

我通过对一张图片执行金字塔操作并使用金字塔构建回结果图像进行测试,发现与使用cv2算术运算相比,最大、最小和平均像素值都相同。

然而,在金字塔的第7层,结果图像会出现一个红点的“噪点”,在第9层,结果图像会出现很多绿色像素的噪点。Levels 6、7、9的图片-Imgur相册。有任何想法为什么会发生这种情况?我会说,第9层金字塔的绿色噪声是因为图像变成了小于1x1的形状。但是第7层金字塔上的红点呢?
  • EDIT : Code Added

    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()
    

你正在使用的数组的数据类型是什么?(如果img是numpy数组,请检查img.dtype。) - Warren Weckesser
@WarrenWeckesser 两种图像类型都是 numpy.ndarray,数据类型为 uint8 - Elia
1
检查您的数组中8位值是否溢出。但是,如果没有看到实际代码(请参见http://stackoverflow.com/help/mcve),我认为我们无法提供更多帮助。 - Warren Weckesser
@WarrenWeckesser 添加了能够重现结果的代码。 - Elia
1个回答

1
在阅读了关于拉普拉斯金字塔的原始文章后,我发现我误解了这种方法,我们可以使用额外的像素信息完全重建原始图像,而不会出现模糊,因为裁剪值确实会导致模糊。现在我们回到了起点:)
所以,您发布的代码仍然是裁剪值,我建议您使用int16保存拉普拉斯金字塔,而不是使用cv2.subtract。希望它有效。

你能否提供给我其中一篇文章呢?我找不到任何包含那种信息的文章... - Elia
如果你有足够的耐心,可以阅读原文:链接。这篇文章讨论了低分辨率图像重建的主题,你可以在谷歌学术中搜索“超分辨率”。 - very hit
在阅读完这篇文章后,我发现拉普拉斯金字塔有负值。而且我们可以使用拉普拉斯金字塔完全重建图像,因此我更新了我的答案。@Elia - very hit
尝试使用uint16、int16和float32进行工作,最后在显示图像时将其更改为uint8,仍然得到相同的结果。@very hit - Elia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接