【问题标题】:Removing borders from an image in Python在 Python 中从图像中删除边框
【发布时间】:2013-10-09 12:13:43
【问题描述】:

某些视频的帧带有边框等黑色条纹。我必须将它们从框架中移除。我想出了一个粗略的解决方案:

import sys, cv2, numpy
import Image, scipy

filename = "snap.jpeg"

img = cv2.imread(filename)

def checkEqual(lst):
    return len(set(lst)) <= 1 ## <-- This is the maximum length of the set

def removeColumns(image):
    for col in range(image.shape[1]):
        for ch in range(3):
            try:
                checkEqual(image[:, col, ch].tolist())
            except IndexError:
                continue
            else:
                if checkEqual(image[:, col, ch].tolist()):
                    try:
                        image = numpy.delete(image, col, 1)
                    except IndexError:
                        continue
                    else:
                        pass
    return image

img2 = removeColumns(img)

print img.shape, img2.shape ## (480, 856, 3) (480, 705, 3)

在这里,我找到了具有相同元素的列,并且我拥有的所有视频都有黑色边框。但即使我将函数checkEqual() 中的最大长度从1 增加到20 或40,也不会删除整个黑条。

这是原图:

这是运行程序后的图像:

任何人都可以提出更好的解决这个问题的建议吗? 谢谢!

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    这个问题已经在this answer解决了。

    from PIL import Image, ImageChops
    
    im = Image.open('iI3ZE.jpg')
    
    def trim(im):
        bg = Image.new(im.mode, im.size, im.getpixel((0,0)))
        diff = ImageChops.difference(im, bg)
        diff = ImageChops.add(diff, diff, 2.0, -100)
        bbox = diff.getbbox()
        if bbox:
            return im.crop(bbox)
    
    
    trim(im).show()
    

    我用 Pillow 代替了 PIL:

    pip install pillow
    

    结果:

    【讨论】:

      【解决方案2】:

      我认为,如果您从图像的另一侧工作,您会发现问题消失了,因为您正在检查第一列 (col[0] - 它是黑色的,因此您将其删除,黑色的 col[1 ] 变成 col[0] 然后你检查 col[1] - 跳过新的 col[0]....

      如果你从最大值开始,它会起作用,或者如果你在删除它后留在任何给定的列上。或者,您可以列出要删除的列表,将其反转,然后进行删除。

      【讨论】:

        【解决方案3】:

        在您的尝试中使用 opencv 和 numpy 怎么样:

        im = cv2.imread(filename)
        h,w,d = im.shape
        #left limit
        for i in range(w):
            if np.sum(im[:,i,:]) > 0:
                break
        #right limit
        for j in xrange(w-1,0,-1):
            if np.sum(im[:,j,:]) > 0:
                break
        
        cropped = im[:,i:j+1,:].copy() # deep copy to get byte-aligned array needed for opencv 
        

        【讨论】:

        • 对我来说,这个解决方案在去除黑色边框时效果最好,因此像素值不一定完全为零 - 通过将 np.sum 替换为 np.mean 和 > 3。需要一些小技巧,但效果非常好(与其他解决方案不同)。谢谢!!!
        【解决方案4】:

        为什么不计算帧并使用PIL

        from PIL import Image
        
        img = Image.open('myImage.jpeg')
        box = (50, 50, 100, 100)
        area = img.crop(box)
        

        【讨论】:

        • 然后呢?存档在哪里?
        猜你喜欢
        • 1970-01-01
        • 2020-03-07
        • 2013-09-05
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 2015-06-10
        • 1970-01-01
        • 2021-12-18
        相关资源
        最近更新 更多