Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 1251

Python • Detect motion with pi camera v1

$
0
0
So I have found this python script and it detects motion.
The problem - it uses raspistill and I don’t know how to make it work with picamera 2

https://thezanshow.com/electronics-tuto ... utorial-16

Code:

#!/usr/bin/python# original script by brainflakes, improved by pageauc, peewee2 and Kesthal# www.raspberrypi.org/phpBB3/viewtopic.php?f=43&t=45235# You need to install PIL to run this script# type "sudo apt-get install python-imaging-tk" in an terminal window to do this# StringIO is not available in Python 3import io#import StringIOimport subprocessimport osimport timefrom datetime import datetimefrom PIL import Image# Motion detection settings:# Threshold          - how much a pixel has to change by to be marked as "changed"# Sensitivity        - how many changed pixels before capturing an image, needs to be higher if noisy view# ForceCapture       - whether to force an image to be captured every forceCaptureTime seconds, values True or False# filepath           - location of folder to save photos# filenamePrefix     - string that prefixes the file name for easier identification of files.# diskSpaceToReserve - Delete oldest images to avoid filling disk. How much byte to keep free on disk.# cameraSettings     - "" = no extra settings; "-hf" = Set horizontal flip of image; "-vf" = Set vertical flip; "-hf -vf" = both horizontal and vertical flipthreshold = 10sensitivity = 20forceCapture = TrueforceCaptureTime = 60 * 60 # Once an hourfilepath = "/home/pi/picam"filenamePrefix = "capture"diskSpaceToReserve = 40 * 1024 * 1024 # Keep 40 mb free on diskcameraSettings = ""# settings of the photos to savesaveWidth   = 1296saveHeight  = 972saveQuality = 15 # Set jpeg quality (0 to 100)# Test-Image settingstestWidth = 100testHeight = 75# this is the default setting, if the whole image should be scanned for changed pixeltestAreaCount = 1testBorders = [ [[1,testWidth],[1,testHeight]] ]  # [ [[start pixel on left side,end pixel on right side],[start pixel on top side,stop pixel on bottom side]] ]# testBorders are NOT zero-based, the first pixel is 1 and the last pixel is testWith or testHeight# with "testBorders", you can define areas, where the script should scan for changed pixel# for example, if your picture looks like this:##     ....XXXX#     ........#     ........## "." is a street or a house, "X" are trees which move arround like crazy when the wind is blowing# because of the wind in the trees, there will be taken photos all the time. to prevent this, your setting might look like this:# testAreaCount = 2# testBorders = [ [[1,50],[1,75]], [[51,100],[26,75]] ] # area y=1 to 25 not scanned in x=51 to 100# even more complex example# testAreaCount = 4# testBorders = [ [[1,39],[1,75]], [[40,67],[43,75]], [[68,85],[48,75]], [[86,100],[41,75]] ]# in debug mode, a file debug.bmp is written to disk with marked changed pixel an with marked border of scan-area# debug mode should only be turned on while testing the parameters abovedebugMode = False # False or True# Capture a small test image (for motion detection)def captureTestImage(settings, width, height):    command = "raspistill %s -w %s -h %s -t 200 -e bmp -n -o -" % (settings, width, height)    #imageData = StringIO.StringIO()    imageData = io.BytesIO()    imageData.write(subprocess.check_output(command, shell=True))    imageData.seek(0)    im = Image.open(imageData)    buffer = im.load()    imageData.close()    return im, buffer# Save a full size image to diskdef saveImage(settings, width, height, quality, diskSpaceToReserve):    keepDiskSpaceFree(diskSpaceToReserve)    time = datetime.now()    filename = filepath + "/" + filenamePrefix + "-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second)    subprocess.call("raspistill %s -w %s -h %s -t 200 -e jpg -q %s -n -o %s" % (settings, width, height, quality, filename), shell=True)    print("Captured %s" % filename)# Keep free space above given leveldef keepDiskSpaceFree(bytesToReserve):    if (getFreeSpace() < bytesToReserve):        for filename in sorted(os.listdir(filepath + "/")):            if filename.startswith(filenamePrefix) and filename.endswith(".jpg"):                os.remove(filepath + "/" + filename)                print("Deleted %s/%s to avoid filling disk" % (filepath,filename))                if (getFreeSpace() > bytesToReserve):                    return# Get available disk spacedef getFreeSpace():    st = os.statvfs(filepath + "/")    du = st.f_bavail * st.f_frsize    return dudef motion():    # Get first image    image1, buffer1 = captureTestImage(cameraSettings, testWidth, testHeight)    # Reset last capture time    lastCapture = time.time()    while (True):        # Get comparison image        image2, buffer2 = captureTestImage(cameraSettings, testWidth, testHeight)        # Count changed pixels        changedPixels = 0        takePicture = False        if (debugMode): # in debug mode, save a bitmap-file with marked changed pixels and with visible testarea-borders            debugimage = Image.new("RGB",(testWidth, testHeight))            debugim = debugimage.load()        for z in range(0, testAreaCount): # = xrange(0,1) with default-values = z will only have the value of 0 = only one scan-area = whole picture            for x in range(testBorders[z][0][0]-1, testBorders[z][0][1]): # = xrange(0,100) with default-values                for y in range(testBorders[z][1][0]-1, testBorders[z][1][1]):   # = xrange(0,75) with default-values; testBorders are NOT zero-based, buffer1[x,y] are zero-based (0,0 is top left of image, testWidth-1,testHeight-1 is botton right)                    if (debugMode):                        debugim[x,y] = buffer2[x,y]                        if ((x == testBorders[z][0][0]-1) or (x == testBorders[z][0][1]-1) or (y == testBorders[z][1][0]-1) or (y == testBorders[z][1][1]-1)):                            # print "Border %s %s" % (x,y)                            debugim[x,y] = (0, 0, 255) # in debug mode, mark all border pixel to blue                    # Just check green channel as it's the highest quality channel                    pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1])                    if pixdiff > threshold:                        changedPixels += 1                        if (debugMode):                            debugim[x,y] = (0, 255, 0) # in debug mode, mark all changed pixel to green                    # Save an image if pixels changed                    if (changedPixels > sensitivity):                        takePicture = True # will shoot the photo later                    if ((debugMode == False) and (changedPixels > sensitivity)):                        break  # break the y loop                if ((debugMode == False) and (changedPixels > sensitivity)):                    break  # break the x loop            if ((debugMode == False) and (changedPixels > sensitivity)):                break  # break the z loop        if (debugMode):            debugimage.save(filepath + "/debug.bmp") # save debug image as bmp            print("debug.bmp saved, %s changed pixel" % changedPixels)        # else:        #     print "%s changed pixel" % changedPixels        # Check force capture        if forceCapture:            if time.time() - lastCapture > forceCaptureTime:                takePicture = True        if takePicture:            lastCapture = time.time()            return True            #saveImage(cameraSettings, saveWidth, saveHeight, saveQuality, diskSpaceToReserve)        else:            return False        # Swap comparison buffers        image1 = image2        buffer1 = buffer2
Will aprreciate any help to make it work with bookworm.

Statistics: Posted by dror_israel — Fri Oct 25, 2024 9:55 pm



Viewing all articles
Browse latest Browse all 1251

Trending Articles