脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - 树莓派动作捕捉抓拍存储图像脚本

树莓派动作捕捉抓拍存储图像脚本

2021-07-18 14:53soft2buy Python

这篇文章主要为大家详细介绍了树莓派动作捕捉抓拍存储图像脚本,支持Python 2.7,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了树莓派动作捕捉抓拍存储图像的具体代码,供大家参考,具体内容如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/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
 
import stringio
import subprocess
import os
import time
from datetime import datetime
from 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 flip
threshold = 10
sensitivity = 20
forcecapture = true
forcecapturetime = 60 * 60 # once an hour
filepath = "/home/pi/picam"
filenameprefix = "capture"
diskspacetoreserve = 40 * 1024 * 1024 # keep 40 mb free on disk
camerasettings = ""
 
# settings of the photos to save
savewidth  = 1296
saveheight = 972
savequality = 15 # set jpeg quality (0 to 100)
 
# test-image settings
testwidth = 100
testheight = 75
 
# this is the default setting, if the whole image should be scanned for changed pixel
testareacount = 1
testborders = [ [[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 above
debugmode = 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.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 disk
def 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 level
def 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 space
def getfreespace():
  st = os.statvfs(filepath + "/")
  du = st.f_bavail * st.f_frsize
  return du
 
# 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 xrange(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 xrange(testborders[z][0][0]-1, testborders[z][0][1]): # = xrange(0,100) with default-values
      for y in xrange(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()
    saveimage(camerasettings, savewidth, saveheight, savequality, diskspacetoreserve)
 
  # swap comparison buffers
  image1 = image2
  buffer1 = buffer2

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

延伸 · 阅读

精彩推荐