亞馬遜剛剛推出了DeepLens 。這是一款專門面向開發人員的全球首個支持深度學習的攝像機,它所使用的機器學習算法不只能夠檢測物體活動和麪部表情,並且還能夠檢測相似彈吉他等複雜的活動。雖然DeepLens還未正式上市,但智能攝像機的概念已經誕生了。python
今天,咱們將本身動手打造出一款基於深度學習的照相機,當小鳥出如今攝像頭畫面中時,它將能檢測到小鳥並自動進行拍照。最終成品所拍攝的畫面以下所示: 相機不傻,它能夠很機智web
咱們不打算將一個深度學習模塊整合到相機中,相反,咱們準備將樹莓派「掛鉤」到攝像頭上,而後經過WiFi來發送照片。本着「一切從簡」(窮)爲核心出發,咱們今天只打算搞一個跟DeepLens相似的概念原型,感興趣的同窗能夠本身動手嘗試一下。算法
接下來,咱們將使用Python編寫一個Web服務器,樹莓派將使用這個Web服務器來向計算機發送照片,或進行行爲推斷和圖像檢測。 咱們這裏所使用的計算機其處理能力會更強,它會使用一種名叫 YOLO 的神經網絡架構來檢測輸入的圖像畫面,並判斷小鳥是否出如今了攝像頭畫面內。flask
咱們得先從YOLO架構開始,由於它是目前速度最快的檢測模型之一。該模型專門給Tensorflow(谷歌基於DistBelief進行研發的第二代人工智能學習系統)留了一個接口,因此咱們能夠輕鬆地在不一樣的平臺上安裝和運行這個模型。友情提示,若是你使用的是咱們本文所使用的迷你模型,你還能夠用CPU來進行檢測,而不僅是依賴於價格昂貴的GPU。瀏覽器
接下來回到咱們的概念原型上… 若是像框內檢測到了小鳥,那咱們就保存圖片並進行下一步分析。bash
檢測與拍照 正如咱們所說的,DeepLens的拍照功能是整合在計算機裏的,因此它能夠直接使用板載計算能力來進行基準檢測,並肯定圖像是否符合咱們的標準。服務器
可是像樹莓派這樣的東西,咱們其實並不須要使用它的計算能力來進行實時計算。所以,咱們準備使用另外一臺計算機來推斷出如今圖像中的內容。網絡
我使用的是一臺簡單的Linux計算機,它帶有一個攝像頭以及WiFi無線網卡( 樹莓派3 + 攝像頭 ),而這個簡單的設備將做爲個人深度學習機器並進行圖像推斷。對我來講,這是目前最理想的解決方案了,這不只大大縮減了個人成本,並且還可讓我在臺式機上完成全部的計算。架構
咱們須要使用Flask來搭建Web服務器,這樣咱們就能夠從攝像頭那裏獲取圖像了。app
from import lib import import_module
import os
from flask import Flask, render_template, Response
#uncomment below to use Raspberry Pi camera instead
#from camera_pi import Camera
#comment this out if you're not using USB webcam
from camera_opencv import Camera
app =Flask(__name__)
@app.route('/')
def index():
return "hello world!"
def gen2(camera):
"""Returns a single imageframe"""
frame = camera.get_frame()
yield frame
@app.route('/image.jpg')
def image():
"""Returns a single currentimage for the webcam"""
return Response(gen2(Camera()),mimetype='image/jpeg')
if __name__ == '__main__':
app.run(host='0.0.0.0', threaded=True)複製代碼
若是你使用的是樹莓派視頻照相機,請確保沒有註釋掉上述代碼中from camera_pi那一行,而後註釋掉from camera_opencv那一行。
你能夠直接使用命令python3 app.py或gunicorn來運行服務器,這跟Miguel在文檔中寫的方法是同樣的。若是咱們使用了多臺計算機來進行圖像推斷的話,咱們還能夠利用Miguel所開發的攝像頭管理方案來管理攝像頭以及計算線程。
當咱們啓動了樹莓派以後,首先須要根據IP地址來判斷服務器是否正常工做,而後嘗試經過Web瀏覽器來訪問服務器。
在樹莓派中加載Web頁面及圖像來肯定服務器是否正常工做: 圖像導入及推斷
既然咱們已經設置好了終端來加載攝像頭當前的圖像內容,咱們就能夠構建一個腳原本捕捉圖像並推斷圖像中的內容了。
這裏咱們須要用到request庫(一個優秀的Python庫,用於從URL地址獲取文件資源)以及 Darkflow (YOLO模型基於Tensorflow的實現)。
不幸的是,咱們沒辦法使用pip之類的方法來安裝 Darkflow ,因此咱們須要克隆整個代碼庫,而後本身動手完成項目的構建和安裝。安裝好Darkflow項目以後,咱們還須要下載一個YOLO模型。
由於我使用的是速度比較慢的計算機和板載CPU(而不是速度較快的GPU),因此我選擇使用YOLO v2迷你網絡。固然了,它的功能確定沒有完整的YOLO v2模型的推斷準確性高啦!
配置完成以後,咱們還須要在計算機中安裝Pillow、numpy和OpenCV。最後,咱們就能夠完全完成咱們的代碼,並進行圖像檢測了。
最終的代碼以下所示:
from darkflow.net.build import TFNet
import cv2
from io import BytesIO
import time
import requests
from PIL import Image
import numpy as np
options= {"model": "cfg/tiny-yolo-voc.cfg", "load":"bin/tiny-yolo-voc.weights", "threshold": 0.1}
tfnet= TFNet(options)
birdsSeen= 0
def handleBird():
pass
whileTrue:
r =requests.get('http://192.168.1.11:5000/image.jpg') # a bird yo
curr_img = Image.open(BytesIO(r.content))
curr_img_cv2 =cv2.cvtColor(np.array(curr_img), cv2.COLOR_RGB2BGR)
result = tfnet.return_predict(curr_img_cv2)
print(result)
for detection in result:
if detection['label'] == 'bird':
print("bird detected")
birdsSeen += 1
curr_img.save('birds/%i.jpg' %birdsSeen)
print('running again')
time.sleep(4)複製代碼
此時,咱們不只能夠在命令控制檯中查看到樹莓派所檢測到的內容,並且咱們還能夠直接在硬盤中查看保存下來的小鳥照片。接下來,咱們就可使用YOLO來標記圖片中的小鳥了。
假陽性跟假陰性之間的平衡
咱們在代碼的options字典中設置了一個threshold鍵,這個閾值表明的是咱們用於檢測圖像的某種成功率。在測試過程當中,咱們將其設爲了0.1,可是如此低的閾值會給咱們帶來是更高的假陽性以及誤報率。更糟的是,咱們所使用的迷你YOLO模型準確率跟完整的YOLO模型相比,差得太多了,但這也是須要考慮的一個平衡因素。
下降閾值意味着咱們能夠獲得更多的模型輸出(照片),在個人測試環境中,我閾值設置的比較低,由於我想獲得更多的小鳥照片,不過你們能夠根據本身的須要來調整閾值參數。