樹莓派超簡單監(jiān)控攝像頭python+picamera或openCV編程
1、在raspi-config中使能攝像頭
打開樹莓派終端,輸入sudo raspi-config
?




? ?????????????? ??
完成后重啟樹莓派
2、檢查攝像頭運(yùn)行情況
vcgencmd get_camera
raspistill命令行測試拍照
raspistill -v -o test.jpg
執(zhí)行后如下圖操作:

?

3、上面都是設(shè)置開啟攝像頭及測試,我們接下來要使用python調(diào)用攝像頭,完成拍照和直播流的功能。
?
樹莓派4B安裝opencv:
sudo apt-get install -y libopencv-dev python3-opencv
網(wǎng)絡(luò)不好的,下載會中斷,多執(zhí)行以上命令幾次就好了,段點續(xù)傳。
安裝完成后
輸入命令:
python3
import CV2
看到以下無錯誤顯示即可

4、使用opencv調(diào)用樹莓派拍照
(1)、 打開usb攝像頭讀取一張照片
import CV2
import matplotlib.pyplot as plt
#opencv調(diào)用csi攝像頭優(yōu)先0,然后usb按順序排列下去
capture = CV2.VideoCapture(0)
# 獲取一幀
ret, frame = capture.read()
plt.imshow(frame[:,:,::-1])#BGRtoRGB
plt.show()
# 釋放資源
capture.release()
?
5、Csi排線的可以直接用樹莓派官方系統(tǒng)自帶的picamera庫
(1)、捕捉一個圖像輸出至文件
使用capture方法可以輕松將捕捉到的圖像輸出至指定文件。 下面這個實例是捕捉一個分辨率為1024*768的圖像,并將之輸出到foo.jpg中
?
import time
import picamera
with picamera.PiCamera() as camera:
??? camera.resolution = (1024, 768)
??? camera.start_preview()
??? #攝像頭預(yù)熱2秒
??? time.sleep(2)
??? #camera.capture('foo.jpg', resize=(320, 240))#可改變分辨率
??? camera.capture('foo.jpg')
(2)、如果你不想使用有損JPEG編碼,并希望加快這一解碼過程的話,可以使用picamera自帶的picamera.array模塊??梢允褂肞iRGBArray類簡單的捕獲’brg’格式的數(shù)據(jù)。(假定RGB與BGR是分辨率相同的數(shù)據(jù),只是具有相反的顏色)
import time
import picamera
import picamera.array
import CV2
?
with picamera.PiCamera() as camera:
??? camera.start_preview()
??? time.sleep(2)
??? with picamera.array.PiRGBArray(camera) as stream:
??????? camera.capture(stream, format='rgb')#format類型:bgr\rgb\h264
??????? # 此時就可以獲取到bgr的數(shù)據(jù)流了
????? ??image = stream.array
import matplotlib.pyplot as plt
?
image_resize = CV2.resize(image,(320, 240)) #opencv改變分辨率
plt.imshow(image_resize)
?
6、使用python做一個簡單的遠(yuǎn)程監(jiān)控攝像頭
使用opencv 和python自帶的http庫就能完成(為什么不用picamera?因為通用呀,不一定樹莓派,只要裝了opencv的硬件,這代碼就可以運(yùn)行),使用瀏覽器,輸入樹莓派地址:8080直接顯示,上代碼:
import CV2
from http import server
import time
#做一個響應(yīng)主頁面html
PAGE="""\
??? <html>
????? <head>
??????? <title>Video Streaming Demonstration</title>
????? </head>
????? <body>
??????? <h1>Video Streaming Demonstration</h1>
??????? <img src="/video_feed">
????? </body>
??? </html>
?
"""
?
# 通過opencv獲取實時視頻流
video = CV2.VideoCapture(0)?
def get_frame(v):
??? success, image = v.read()
??? # 因為opencv讀取的圖片并非jpeg格式,因此要用motion JPEG模式需要先將圖片轉(zhuǎn)碼成jpg格式圖片
? ??ret, jpeg = CV2.imencode('.jpg', image)
??? return jpeg.tobytes()
def gen(camera):
??? while True:
??????? frame = get_frame(camera)
??????? # 使用generator函數(shù)輸出視頻流, 每次請求輸出的content類型是image/jpeg
??????? yield (b'--frame\r\n'
?????????????? b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
???????
class HTTPHandler(server.BaseHTTPRequestHandler):
??? def do_GET(self):#get數(shù)據(jù)處理
??????? if self.path == '/': #跳轉(zhuǎn)至默認(rèn)頁面
??????????? self.send_response(301)
??????????? self.send_header('Location', '/index.html')
??????????? self.end_headers()
??????? elif self.path == '/index.html':
??????????? content = PAGE.encode('utf-8')
??????????? self.send_response(200)
??????????? self.send_header('Content-Type', 'text/html')
????????? ??self.send_header('Content-Length', len(content))
??????????? self.end_headers()
??????????? self.wfile.write(content)
??????? elif self.path == '/video_feed':
??????????? self.send_response(200)
??????????? self.send_header('Content-Type','multipart/x-mixed-replace; boundary=frame')
??????????? self.end_headers()
??????????? while True:
??????????????? self.wfile.write(next(cam)) #必須用next()才能運(yùn)行生成器
??????????????? self.wfile.write(b'\r\n')
??????? else:
??????????? self.send_error(404)
??????????? self.end_headers()
cam = gen(video)#生成器
try:
??? print("http server start...")
??? address = ('', 8080)
??? server = server.HTTPServer(address, HTTPHandler)
??? server.serve_forever()
finally:
??? print('done')
?