How to detect motion between two PIL images? (wxPython webcam integration example included)

后端 未结 1 1659
暗喜
暗喜 2020-12-23 23:27

Does anyone have any suggestions as to how I might do image comparison in python to detect changes within an image? I\'m currently working on an app that will monitor my are

相关标签:
1条回答
  • 2020-12-24 00:22

    This might be a naive approach, but it's a simple place to begin. I'm sure you will be influenced by camera noise and you may want to distinguish changes in lighting from changes in image composition. But here's what came to my mind:

    You can use PIL ImageChops to efficiently take a difference between images. Then you can take the entropy of that diff to get a single-value threshold.

    It seems to work:

    from PIL import Image, ImageChops
    import math
    
    def image_entropy(img):
        """calculate the entropy of an image"""
        # this could be made more efficient using numpy
        histogram = img.histogram()
        histogram_length = sum(histogram)
        samples_probability = [float(h) / histogram_length for h in histogram]
        return -sum([p * math.log(p, 2) for p in samples_probability if p != 0])
    
    # testing..
    
    img1 = Image.open('SnowCam_main1.jpg')
    img2 = Image.open('SnowCam_main2.jpg')
    img3 = Image.open('SnowCam_main3.jpg')
    
    # No Difference
    img = ImageChops.difference(img1,img1)
    img.save('test_diff1.png')
    print image_entropy(img) # 1.58496250072
    
    # Small Difference
    img = ImageChops.difference(img1,img2)
    img.save('test_diff2.png') 
    print image_entropy(img) # 5.76452986917
    
    # Large Difference
    img = ImageChops.difference(img1,img3)
    img.save('test_diff3.png')
    print image_entropy(img) # 8.15698432026
    

    This, I believe is a much better algorithm for image entropy since it bins 3-dimensionally in color-space rather than creating a separate histogram for each band.

    EDIT- this function was changed 6-Apr-2012

    import numpy as np
    def image_entropy(img):
        w,h = img.size
        a = np.array(img.convert('RGB')).reshape((w*h,3))
        h,e = np.histogramdd(a, bins=(16,)*3, range=((0,256),)*3)
        prob = h/np.sum(h) # normalize
        prob = prob[prob>0] # remove zeros
        return -np.sum(prob*np.log2(prob))
    

    These are my test images:

    enter image description here

    Image 1

    enter image description here

    Image 2

    enter image description here

    Image 3

    0 讨论(0)
提交回复
热议问题