Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Raspberry Pi Camera Python

Raspberry Pi Camera Python

本投影片介紹 Raspberry Pi Camera 的使用方式,配合實體課程約八小時,涵蓋以下內容:
1. 環境設定(0.5 小時)
- 使用 Serial + WiFi
- 使用 VNC 和 X-Forwarding

2. Raspberry Pi Camera 簡介(1 小時)
- 標準 Camera 和 NoIR Camera 介紹
- Camera 應用介紹
- Camera 改裝套件介紹
- Camera 安裝與設定

3. 基礎 Camera 使用 (2 小時)
- 用 Python 控制
- 手機控制與網路串流
- 週邊硬體與 Camera 的互動
- 串接網路服務

4. 進階 Camera 使用 (2.5 小時)
- 影像處理原理
- 人臉偵測

範例程式(使用 Python2):
https://github.com/piepie-tw/camera-python

台灣樹莓派

July 09, 2015
Tweet

More Decks by 台灣樹莓派

Other Decks in Technology

Transcript

  1. 2

  2. 姓名標示 — 非商業性 — 相同方式分享 CC (Creative Commons) 姓名標示 —

    你必須給予 適當表彰、提供指向本授權 條款的連結,以及 指出(本作品的原始版本)是否已 被變更。你可以任何合理方式為前述表彰,但不得以 任何方式暗示授權人為你或你的使用方式背書。 非商業性 — 你不得將本素材進行商業目的之使 用。 相同方式分享 — 若你重混、轉換本素材,或依本 素材建立新素材,你必須依本素材的授權條款來 散布你的貢獻物。
  3. 9 環境設定: Serial + WiFi 1. 樹莓派 Serial 連線 2.

    樹莓派 WiFi 連線 用 Serial 來設定 WiFi 3. 筆電、手機、樹莓派 在同一個 LAN
  4. 10 • 以 USB 轉 TTL 傳輸線和 Pi 相連 •

    接線方式 • 黑色: Pin 6 (GND) • 白色: Pin 8 (Tx) • 綠色: Pin 10 (Rx) • 紅色:不接 Serial 連線方式
  5. 11 Raspberry Pi B 的 GPIO (P1) 黑色線接 6 號

    ( 第三根 ) 白色線接 8 號 ( 第四根 ) 綠色線接 10 號 ( 第五根 ) http://elinux.org/RPi_Low-level_peripherals
  6. 12 Raspberry Pi B+ 的 GPIO (P1) 黑色線接 6 號

    ( 第三根 ) 白色線接 8 號 ( 第四根 ) 綠色線接 10 號 ( 第五根 ) http://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/
  7. 13 • 安裝驅動程式 , http://goo.gl/QC5Q3O • 從裝置管理員找到 COM 的埠號 (

    本例為 COM9) • 下載 putty, http://goo.gl/zdD9G9 • 執行 putty • Session • Serial line 填 COM9 • Speed 填入 115200 • Open ! • 沒畫面 , 重新插拔電源 Serial Port in Windows
  8. 14 • $ ls /dev/ttyUSB* • 開啟 putty • 選擇

    Session • 在 Serial line 填入 /dev/ttyUSB0 ( 本例為 ttyUSB0) • Speed 填入 115200 • Open ! • 無法連線時 , 使用 sudo 執行 putty Serial Port in Linux
  9. 15 • 安裝驅動程式 , http://goo.gl/htlt3F • 重開機生效 • $ ls

    /dev/cu* • 如果有 /dev/cu.usbserial • $ screen /dev/cu.usbserial 115200 • 如果沒畫面,重新插拔電源 Serial Port in Mac
  10. 16 • 預設帳號 / 密碼: pi / raspberry • 如果沒有畫面,將電源重新插拔

    • 如果出現亂碼,確定 baud rate 為 115200 連線成功
  11. 17 • 登入畫面 • pi 是登入的使用者 • @ 表示”在” •

    raspberrypi 是主機名稱 • ~ 表示在家目錄 (home directory) • $ 表示該使用者所使用的 shell( 一種文字工具介面 ) • 例如 $ nano myfile.txt • 表示用 nano 編輯器開 myfile.txt 檔案 符號說明
  12. 18 使用: nano 離開: Ctrl + x > 令存新檔: y

    > 不存離開: n > 離開: Ctrl + c nano 編輯器使用
  13. 19 $ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf # /etc/wpa_supplicant/wpa_supplicant.conf ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1

    • 請參考“ [ 基礎 ] 命令列設置無線網路” • http://www.raspberrypi.com.tw/2152/setting-up- wifi-with-the-command-line/ 在文字模式下設定無線網路
  14. 20 $ sudo ifdown wlan0 $ sudo ifup wlan0 $

    sudo kill -9 $(ps -ef | grep wpa | awk '{print $2}') $ sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf $ sudo dhclient wlan0 指令列設定 WiFi - 連線
  15. 23 • Raspberry Pi 端 • $ sudo apt-get install

    tightvncserver • $ vncserver • PC 端 • Linux 使用 vncviewer • Windows 下載 TightVNC • 連線 Raspberry Pi ( 下為範例 IP) • vncviewer 192.168.43.102: 5901 • tightvnc 192.168.43.102::5901 • 更多使用方法 • http://www.raspberrypi.com.tw/586/setting-up-vnc/ 想要視窗 , 設定 VNC( 今天不需設 定 )
  16. • $ sudo apt-get install -y vlc • $ sudo

    apt-get install -y gpac mplayer • $ sudo apt-get install -y mencoder • $ sudo apt-get install -y python-opencv • $ sudo apt-get install -y python-pip • $ sudo pip install requests • $ sudo pip install flask 安裝今日所需軟體
  17. 從手機相機模組講起 http://www.phonearena.com/news/13MP-camera-tipped-for-Samsung-Galaxy-S-IV_id35168 1. Lens( 透鏡 ) 2. VCM( 音圈馬達 )

    3. IR-Cut( 紅外光濾片 ) 4. Sensor( 感光元件 ) 5. PCB( 印刷電路板 ) 6. ISP( 影像訊號處理器 )
  18. • Sensor: OmniVision OV5647 Color CMOS QSXGA (5M) • 靜態拍照最高解析度:

    2592 x 1944 pixel • Pixel Size: 1.4 x 1.4 um • Lens: f=3.6 mm, f/2.9 • Angle of View: 54 x 41 degrees • Field of View: 2.0 x 1.33 m at 2 m • Fixed Focus: 1m to infinity • 動態攝影最高解析度: 1080p@30 FPS with H.264/AVC 技術規格
  19. • No IR = No 'IR cut filter' installed •

    因此 CMOS 可吸收到不可見光 (Infrared) • No IR 相機 ≠ 夜視相機 • 除非有額外的紅外線發光源 No IR Camera 黑色 PCB 板
  20. • 只預覽 2 秒 (-t), 不存檔 • $ raspistill -t

    2000 • 5 秒後拍照 , 檔案 test.jpg(-o), 印出詳細訊息 (-v) • $ raspistill -v -o test.jpg • 3 秒後拍照 , 並編碼成 png 格式 (-e), 長 640x 寬 480 • $ raspistill -t 3000 -o test.png -e png -w 640 -h 480 RaspiStill https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspistill.md
  21. • 錯誤訊息: Camera is not enabled in this build •

    解法:進 raspi-config 重新 enable camera • $ sudo raspi-config
  22. • 錯誤訊息: Camera is not detected • 解法:重新安裝 camera, 或是更換排線

    或是檢查 camera module 是否鬆脫 https://www.modmypi.com/blog/how-to-replace-the-raspberry-pi-camera-cable
  23. • 錄 5 秒 (-t) 1080p30 影片 ( 預設 w/h

    = 1920/1080) • $ raspivid -t 5000 -o video.h264 • 影片存檔名稱 video.h264(-o), bitrate 為 3.5MBits/s(-b) • $ raspivid -t 5000 -o video.h264 -b 3500000 • 錄 5 秒的 1080p30 影片 , 長 640x 寬 480 • $ raspivid -t 5000 -w 640 -h 480 RaspiVid https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspivid.md
  24. $ nano camera_effect.sh • #!/bin/bash for effect in none negative

    solarise sketch denoise emboss oilpaint hatch gpen pastel watercolour film blur saturation colourswap washedout posterise colourpoint colourbalance cartoon do echo $effect raspivid -d -ifx $effect done $ chmod 755 camera_effect.sh $ ./camera_effect.sh 用 RaspiVid 看 Camera 內建的效果 http://www.ics.com/blog/raspberry-pi-camera-module
  25. 65 $ git clone https://github.com/raspberrypi-tw/camera-python.git $ cd camera-python $ cd

    01_hello_camera $ ./camera_effect.sh 需要接上螢幕才能看到效果 執行方式
  26. 68 • 是一種圖形應用標準 • Client/Server 架構 • X Client :

    應用程式 • X Server : 管理硬體輸入 / 輸出 • 可透過網路傳輸 • TCP/IP 或是 Unix Domain Socket • X11 是通訊協定名稱 X Window System http://keyj.emphy.de/files/linuxgraphics_en.pdf
  27. 69 • Windows( 使用 Xming + putty) • Xming 安裝

    (http://sourceforge.net/projects/xming/)+ 下一步到底 • putty > SSH > X11 > Enable X11 forwarding • Linux/Mac : ssh -X [email protected] X11 Forwarding using SSH
  28. • 看照片 • $ gpicview image.jpg • 看影片 • H.264

    格式可直接用 VLC 看 • $ vlc video.h264 • 或是將 H.264 轉成 MP4 後用 mplayer 看 • $ MP4Box -fps 30 -add video.h264 video.mp4 • $ mplayer video.mp4 X11 Forwarding 連線成功後
  29. • 第一步:編輯 /etc/sshd_config 修改這行 # X11Forwarding no 把它改成 yes 並且把註解拿掉

    • 第二步:下載安裝 XQuartz 並重開機 http://xquartz.macosforge.org/landing/ • 感謝 Dami 和 YUN-TAO CHEN 的貢獻 “Can not open display” on Mac https://hackpad.com/X11-Forwarding-FcyKHioKxmW
  30. • 在 Pi • $ sudo ifconfig eth0 192.168.2.2 netmask

    255.255.255.0 • 在 Windows • 在 Linux/Mac • $ sudo ifconfig eth0 192.168.2.1 netmask 255.255.255.0 網路設定
  31. • 60 秒內每 1 秒拍一張 , 檔案名稱遞增 (4 位數 )

    • $ raspistill -t 60000 -tl 1000 -o image%04d.jpg -bm -w 640 -h 480 • 所有的照片接在一起 • $ ls *.jpg > stills.txt • 調整播放速度 4 = 4 倍速的視覺效果 • $ mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=4/3:vbitrate=8000000 -vf scale=640:480 -o timelapse.avi -mf type=jpeg:fps=4 mf://@stills.txt 實做 http://www.raspberrypi.org/learning/timelapse-setup/
  32. RTSP 通訊協定 RTSP Client RTSP Server RTSP (TCP) : initiate

    RTP (UDP) : content RTCP (UDP) : control
  33. • 在 Raspberry Pi $ raspivid -o - -t 0

    -w 320 -h 240 -n | cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/}' :demux=h264 • 在 Windows/Linux 使用 VLC • rtsp://raspberrypi 的 ip:8554/ • 在 iPhone/iPad 上 • rtsp://raspberrypi 的 ip:8554/ • 8554 後面的斜線很重要 , 要加 如何使用 RTSP + H.264 ? http://www.raspberry-projects.com/pi/pi-hardware/raspberry-pi-camera/streaming-video-using-vlc-player
  34. • 在 Raspberry Pi 上 ( 需要先安裝 UV4L) • cvlc

    v4l2:///dev/video0 --v4l2-width 320 --v4l2-height 240 --sout '#transcode{vcodec=MJPG,width=320,height=240,vb =1000}:duplicate{dst=std{access=http{mime=multipar t/x-mixed-replace;boundary=-- 7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,d st=:8080/video.mjpg}'} • 開啟 Browser • http://raspberrypi 的 ip:8080/video.mjpg HTTP + MJPEG https://goo.gl/U9zhEO
  35. • 預定義好的 Userspace API • Video and radio streaming devices

    • video cameras • analog and digital TV receiver cards • AM/FM receiver cards Video4Linux 2nd(V4L2) http://free-electrons.com/doc/embedded_linux_multimedia.pdf /dev/video0 Driver Hardware App1 (fd1) App2 (fd2) ioctl() ioctl() read() write() Identifying App1 and App2 by different file descriptors, the driver can send them different data.
  36. 101 • 開放多媒體加速層 (Open Media Acceleration) • 由 Khronos Group

    提出的標準 • 統一的介面,加速大量多媒體資料的處理 OpenMAX https://www.khronos.org/openmax/
  37. 103 • Kernel driver • 使用 camera 像是 webcam 一樣

    • sudo modprobe bcm2835-v4l2 • 可直接存取 /dev/videoX • v4l2-ctl --list-devices • v4l2-ctl --list-formats • v4l2-ctl -L ×Official V4L2 Driver https://github.com/raspberrypi/linux/blob/rpi-3.10.y/Documentation/video4linux/bcm2835-v4l2.txt
  38. 104 • 安裝 • $ sudo apt-get install v4l-utils •

    缺點 • closed sourced • slow because it runs as a user program • 相關應用 • Real-time HTTP Streaming Server with the native uv4l-server module(MJPEG/H264/JPEG) • Object detection and object tracking • Compute module: stereoscopic vision User Space V4L2 Driver(UV4L) http://www.linux-projects.org/modules/sections/index.php?op=viewarticle&artid=16
  39. 105 • 參考這幾隻程式吧 • raspicam • https://github.com/raspberrypi/userland/tree/master/h ost_applications/linux/apps/raspicam • rpi-omx-tutorial

    • https://github.com/SonienTaegi/rpi-omx-tutorial • omxcam • https://github.com/gagle/raspberrypi-omxcam • rpi-mmal-demo • https://github.com/tasanakorn/rpi-mmal- demo/tree/develop 但我想使用 C 語言接到 OpenMAX
  40. 108 • 變數 , 物件 , 型別 , 註解 •

    模組 • 縮排 • 迴圈 • 條件判斷 • 函式 • 例外處理 • with as Python 五分鐘速成
  41. 109 • 動態型別 (dynamic typing) # 這是註解 i = 3

    # 變數 i 指到數字物件 3 i = [1, 2, 3, 4, 5] # 變數 i 指到串列物件 print(i[2]) # 印出串列中第三個元素 i = “abcde” # 變數 i 指到字串物件 print(i[2]) # 印出字串中第三個元素 變數 , 物件 , 型別 , 註解
  42. 110 # import MODULE import RPi.GPIO # import MODULE as

    ALIAS import RPi.GPIO as GPIO # from MODULE import FUNCTION from time import sleep 模組 http://programmers.stackexchange.com/questions/187403/import-module-vs-from-module-import-function
  43. 112 • 自動迭代 (iterator) for TARGET in LIST : #

    aaa • # bbb # ccc # nameS = ["paul", "mary", "tom", "rita"] # for name in nameS : # print name 迴圈
  44. 113 if CONDITION_1 : PROCESS_1 elif CONDITION_2 : PROCESS_2 else

    : PROCESS_3 • # grade = 60 # if grade > 60 : # print "great" # else : # print "too bad" 條件判斷
  45. 114 def FUNCTION() : PROCESS def FUNCTION( PARAM ) :

    PROCESS def FUNCTION( PARAM = 3) : PROCESS # def my_function(input = 5) : # print (input) 函式
  46. 115 • 程式何時會結束 ? • 在正常情況下執行完畢結束 • 遇到錯誤跳出 • 受到中斷停止

    ( 收到終止訊號 , 例如 Ctrl+c) file = open('demo.py', 'r', encoding='UTF-8') try: for line in file: print(line, end='') except: print(' 讀取檔案發生錯誤 ') finally: file.close() try, except, finally http://openhome.cc/Gossip/Python/WithAs.html
  47. 116 • 使用 with as 來簡化 try exception 程式 with

    open('demo.py', 'r', encoding='UTF-8') as file: for line in file: print(line, end='') with... as... http://openhome.cc/Gossip/Python/WithAs.html
  48. #!/usr/bin/python • import time import picamera with picamera.PiCamera() as camera:

    • camera.start_preview() # The default resolution is 1280x800 camera.capture('image.jpg') • 預設相片解析度為 1280x800 照相 http://picamera.readthedocs.org/en/release-1.8/recipes1.html
  49. 119 • 使用 scp • 一個實做 SCP(Secure Copy Protocol) 的應用程式

    • 透過 SSH(Secure Shell) 傳輸資料 • Windows 請安裝 WinSCP • http://winscp.net/eng/download.php • 從 Pi 複製檔案到 PC 上 • scp [email protected]:/home/pi/file.txt . • scp file.txt [email protected]:/home/pi 如何讓 Pi 和 PC 互傳檔案? http://winscp.net/
  50. #!/usr/bin/python • import picamera • • with picamera.PiCamera() as camera:

    • camera.start_recording('video.h264') • camera.wait_recording(3) camera.stop_recording() • 錄 3 秒鐘影像 , 儲存到檔案 video.h264 • 預設錄影格式為 H.264/AVC 壓縮 , 解析度 1280x800 錄影 http://picamera.readthedocs.org/en/release-1.8/recipes1.html
  51. #!/usr/bin/python • import picamera • • with picamera.PiCamera() as camera:

    • camera.resolution = (640, 480) • camera.iso = 200 • camera.exposure_mode = 'off' • g = camera.awb_gains • camera.awb_mode = 'off' • camera.awb_gains = g • camera.start_recording('video.h264', quality=23) • camera.wait_recording(3) camera.stop_recording() 更多使用參數 http://picamera.readthedocs.org/en/release-1.8/recipes1.html
  52. 124 • 開關:按鍵式 , 滑動式 , 傾斜式 ... • 常開

    (normal open, N.O.) • 常閉 (normal close, N.C.) 按鍵 Button / 開關 Switch http://nicegear.co.nz/
  53. 125 • 開關:按鍵式 , 滑動式 , 傾斜式 ... • 常開

    (normal open, N.O.) • 常閉 (normal close, N.C.) 按鍵 Button / 開關 Switch
  54. 128 • GPIO is a flexible software-controlled digital signal •

    A generic pin on an IC General Purpose Input Output(GPIO) http://raspberrypihobbyist.blogspot.tw/2012/09/so-many-inputs-so-few-gpio-pins.html
  55. 132 • 6 、 9 、 14 、 20 等腳位為接地,可互相交換

    GPIO 腳位意義對照表 http://wiringpi.com/wp-content/uploads/2013/03/pins.pdf
  56. 141 線路圖 ( 上拉電阻 ) BUTTON RPi 腳 1 Pin6

    (Ground) 腳 3 Pin11 (GPIO0) Pin1 (3.3V) 1K 電阻 2K 電阻
  57. 142 BTN_PIN = 11 GPIO.setup(BTN_PIN, GPIO.IN) try: while True: if

    GPIO.input(BTN_PIN) == GPIO.LOW: print("Button.Click") except KeyboardInterrupt: print "Exception: KeyboardInterrupt" finally: GPIO.cleanup() 按下按鍵的判斷條件 ( 上拉電阻 )
  58. 143 DEMO sudo python push_button_poll.py 讀寫 GPIO 會存取 /dev/mem, 需

    root 權限 sudo 表示暫時切換身份到其他使用者 (root)
  59. 146 TIME_LAPSE = 0.2 GPIO.setup(BTN_PIN, GPIO.IN) previousTime = time.time() try:

    while True: currentTime = time.time() if GPIO.input(BTN_PIN) == GPIO.LOW and \ (currentTime - previousTime) > TIME_LAPSE: previousTime = currentTime print("Button.Click") except KeyboardInterrupt: GPIO.cleanup() 軟體方法:不反應在延遲時間內的觸發
  60. 149 • 輪詢 (polling) • SoC 每隔一段時間檢查週邊硬體的資料 • 中斷 (interrupt)

    • 當週邊硬體的狀態改變時 , 通知 SoC 輪詢與中斷
  61. 150 • 建立回呼函數 • def callback() • 綁定事件和回呼函數 • add_event_detect(gpio,

    edge, callback=None, bouncetime=0) • 多個事件可以綁定同樣的回呼函數 中斷的程式寫法 source/py_gpio.c
  62. 151 BTN_PIN = 11 GPIO.setup(BTN_PIN, GPIO.IN) def callback_function(channel): print("Button.Click...") try:

    GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, \ callback=callback_function, bouncetime=200) while True: time.sleep(10) except KeyboardInterrupt: GPIO.cleanup() 讀取按鍵
  63. 153 BTN_PIN = 11 GPIO.setup(BTN_PIN, GPIO.IN) def callback_function(channel): with picamera.PiCamera()

    as camera: time.sleep(2) camera.capture('image.jpg') try: GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, \ callback=callback_function, bouncetime=200) while True: time.sleep(10) except KeyboardInterrupt: GPIO.cleanup() 按鍵控制拍照
  64. 156 • R= 電阻 , C= 電容 • 利用電容放電維持準位 硬體方法:使用

    RC 電路 http://www.eng.utah.edu/~cs5780/debouncing.pdf 按鍵還沒按下時 - 充電 按鍵按下後 - 放電
  65. 157 線路圖 (RC 電路 ) BUTTON RPi 腳 1 Pin6

    (Ground) 腳 3 Pin11 (GPIO0) Pin1 (3.3V) Pin14 (Ground) 1k 電阻:棕黑黑棕 ( 棕 1k 電阻:棕黑黑棕 ( 棕 0.1u 電容: 104
  66. 1. 註冊與認證 – https://imagga.com/auth/signup 2. 取得 API Key 和 API

    Secret – https://imagga.com/profile/dashboard 3. 串接 – input: 命令列 / 程式 – output: JSON 字串 如何開始使用服務? http://docs.imagga.com/
  67. • 原型 • $ curl --request GET \ --url 'http://api.imagga.com/v1/tagging?url=/url/to/image'

    \ --header 'accept: application/json' \ --header 'authorization: Basic Base64_Encode(api_key:api_secret)' • 範例(記得將紅色部份換成自己的api_key和api_secret) • $ curl --request GET \ --url 'http://api.imagga.com/v1/tagging?url=http%3A%2F \ %2Fplayground.imagga.com%2Fstatic%2Fimg%2Fexample_photo.jpg' \ --header 'accept: application/json' \ --header 'authorization: Basic \ YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1N TQ1MmYwNTgzMQ==' 命令列 (shell) 串接 http://docs.imagga.com/
  68. • JSON(JavaScript Object Notation) 是一種資料結構 • 物件 (object) 以 {

    } 表示 • 鍵 / 值 (collection) 以 : 表示 • 陣列 (array) 以 [ ] 表示 回傳結果 (JSON) http://docs.imagga.com/
  69. • $ sudo apt-get install -y libtool automake • $

    wget http://stedolan.github.io/jq/download/source/jq- 1.4.tar.gz • $ tar zxvf jq-1.4.tar.gz • $ cd jq-1.4 • $ sudo ln -s /usr/bin/automake-1.11 /usr/bin/automake- 1.14 • $ ./configure • $ make 在 shell 解析 JSON 字串 - jq 安裝 http://stedolan.github.io/jq/
  70. { "results": [ { "image": "http://playground.imagga.com/static/img/example_photo.jpg", "tags": [ { "confidence":

    100, "tag": "shore" }, • 取出results : json | ./jq '.results' • 取出tags : json | ./jq '.results[0].tags' • 取出第一個tag : json | ./jq '.results[0].tags[0].tag' 在 shell 解析 JSON 字串 - jq 使用 http://stedolan.github.io/jq/
  71. import requests url = "http://api.imagga.com/v1/tagging" querystring = {"url":"http://playground.imagga.com/static/img/example_photo.jpg"} headers =

    { 'accept': "application/json", 'authorization': "Basic YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1 NTQ1MmYwNTgzMQ==" } response = requests.request("GET", url, headers=headers, params=querystring) print(response.text) Python 程式串接 (File URL) - 記得將紅色部份換成自己的 api_key 和 api_secret http://docs.imagga.com/
  72. import requests import json • url = "http://api.imagga.com/v1/tagging" querystring =

    {"url":"http://playground.imagga.com/static/img/example_photo.jpg"} headers = { 'accept': "application/json", 'authorization': "Basic YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1NTQ1 MmYwNTgzMQ==" } response = requests.request("GET", url, headers=headers, params=querystring) data = json.loads(response.text.encode("ascii")) • print(data["results"][0]["tags"][0]["tag"].encode("ascii")) 加上解析 JSON - 記得將紅色部份換成自己的 api_key 和 api_secret
  73. import requests import json • url = “http://api.imagga.com/v1/content” files =

    {“file”: open(“/home/pi/file.png”, “rb”)} headers = { 'accept': "application/json", 'authorization': "Basic YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1NTQ1M mYwNTgzMQ==" } response = requests.post(url, files=files, headers=headers) print(response.text) • data = json.loads(response.text.encode("ascii")) • print(data["uploaded"][0]["id"]) 上傳檔案取得檔案 uid - 記得將紅色部份換成自己的 api_key 和 api_secret
  74. # … 接前頁 • url = "http://api.imagga.com/v1/tagging" querystring = {"content":data["uploaded"][0]["id"]}

    response = requests.request("GET", url, headers=headers, params=querystring) data = json.loads(response.text.encode("ascii")) print(data["results"][0]["tags"][0]["tag"].encode("ascii")) • 將 uid 以參數方式送出查詢
  75. • Ivan 說 , 短邊 300px 傳輸最快 • $ sudo

    apt-get install imagemagick • $ convert b.jpg -resize widthxheight a.jpg • $ convert b.jpg -resize widthxheight! a.jpg // 強制 • 除了印出結果 , 還可以讓 Pi 發聲 • $ sudo apt-get install festival • $ echo tag | festival --tts 小技巧 & 延伸功能 由 imagga 回傳的 tag
  76. • 跨平台的計算機函式庫 , 主要由 C/C++ 撰寫 OpenCV - Open Source

    Computer Vision Library http://www.embedded-vision.com/technology/computer-vision-algorithms
  77. import cv2 • import sys • imagePath = sys.argv[1] image

    = cv2.imread(imagePath) • • cv2.imshow("preview", image) cv2.waitKey(0) cv2.destroyAllWindows() • 載入圖檔並顯示
  78. import cv2 cap = cv2.VideoCapture(0) cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 320) cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 240) while

    True: ret, frame = cap.read() cv2.imshow(“preview”, frame) if cv2.waitKey(1) & 0xFF == ord(“q”): break cap.release() cv2.destroyAllWindows() 讀取 Camera 並顯示
  79. • 由 Viola & Jones 提出,並由 Lienhart & Maydt 改善

    • 監督式學習 • 特徵比對 (Haar features) • 積分影像計算 (Integral Image) • 學習機制 (AdaBoost) • 串接分類器 (Cascade) Face Detection - Haar Classifiers http://www.open-electronics.org/raspberry-pi-and-the-camera-pi-module-face-recognition-tutorial/
  80. • Haar-like features • A "cascade" is a series of

    "Haar-like features" that are combined to form a classifier Haar-Like Features & Haar Cascade https://www.youtube.com/watch?v=sWTvK72-SPU
  81. • Pick a scale (ex: 24x24 pixels) for the feature

    • Slide it across the image • Compute the average pixel values under the white area and the black area • If the difference between the areas is above some threshold, the feature matches 特徵比對 https://www.youtube.com/watch?v=sWTvK72-SPU
  82. • A "summed area table" is created in a single

    pass across the image • The sum of any region in the image can be computed by a single formula 積分影像計算 https://www.youtube.com/watch?v=sWTvK72-SPU
  83. • Adaptive Boosting • Adaboost tries out multiple weak classifiers

    over several rounds, selecting the best weak classifier in each round and combining the best weak classifiers to create a strong classifier AdaBoost https://www.youtube.com/watch?v=sWTvK72-SPU
  84. • A single classifier isn't accurate enough • It's called

    a "weak classifier" • Haar cascades consists of a series of weak classifiers - those barely better than 50% correct • If an area passes a single classifier, go to the next classifier; otherwise, area doesn't match 串接分類器 https://www.youtube.com/watch?v=sWTvK72-SPU
  85. faceCascade = cv2.CascadeClassifier(sys.argv[2]) • image = cv2.imread(sys.argv[1]) • gray =

    cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) • • faces = faceCascade.detectMultiScale( • gray, • scaleFactor=1.1, • minNeighbors=5, • minSize=(30, 30), • flags = cv2.cv.CV_HAAR_SCALE_IMAGE • ) • for (x, y, w, h) in faces: • cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2) 載入圖檔並辨識 https://sites.google.com/site/5kk73gpu2012/assignment/viola-jones-face-detection
  86. • 搜索視窗 vs. 檢測視窗 • 搜索視窗在整個影像中移動 , 檢測視窗在搜索視 窗中移動並計算特徵值 •

    scaleFactor: 搜索視窗成長比率 • minNeighbors: 檢測區域鄰域內最少包含的檢測出 的備選人臉區域 ( 次數 ) • minSize: 檢測視窗的最小尺寸 可調整的參數
  87. faceCascade = cv2.CascadeClassifier(sys.argv[1]) cap = cv2.VideoCapture(0) while True: ret, frame

    = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.cv.CV_HAAR_SCALE_IMAGE • ) • for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) 讀取 Camera 並辨識
  88. • 一個軟體 • 回應從 80/8080 port 進來的 HTTP 要求 •

    可透過 CGI 或 module 方式擴充 • 如 Apache, Nginx, Boa 網頁伺服器 (Web Server) http://www.resultantsys.com/index.php/general/what-is-a-web-application-server/
  89. $ vi app-hello.py from flask import Flask app = Flask(__name__)

    @app.route("/") def index(): return "Hello Flask" if __name__ == "__main__": app.run(host='0.0.0.0', port=80, debug=True) Hello Flask
  90. $ sudo python app-hello.py * Running on http://0.0.0.0:80/ (Press CTRL+C

    to quit) * Restarting with stat 192.168.11.2 - - [29/May/2015 15:37:31] "GET / HTTP/1.1" 200 - 192.168.11.2 - - [29/May/2015 15:37:31] "GET /favicon.ico HTTP/1.1" 404 - 執行
  91. from flask import Flask, render_template • • app = Flask(__name__)

    @app.route("/") def index(): return render_template('link.html') • @app.route("/foo") • def foo(): • extns = ['Flask', 'Jinja2', 'Awesome'] • return render_template('bar.html', extns=extns) if __name__ == "__main__": app.run(host='0.0.0.0', port=80, debug=True) 新增一個 route & template
  92. $ mkdir templates $ vi templates/link.html <h1>Hello Template</h1> <a href="{{

    url_for('foo') }}">foo</a> $ vi templates/bar.html <ul> {% for ext in extns %} <li>{{ ext }}</li> {% endfor %} </ul> 建立 template
  93. from camera import Camera • from flask import Flask, render_template,

    Response • app = Flask(__name__) • • @app.route("/") • def index(): • return render_template('index.html') • • def gen(camera): • while True: • frame = camera.get_frame() • yield (b'--frame\r\n' • b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n') • • @app.route('/video_feed') • def video_feed(): • return Response(gen(Camera()), • mimetype='multipart/x-mixed-replace; boundary=frame') Streaming 圖片
  94. $ vi stream_pi.py from time import time class Camera(object): def

    __init__(self): self.frames = [open(f + '.jpg', 'rb').read() for f in ['1', '2', '3']] def get_frame(self): return self.frames[int(time()) % 3] 建立 Camera 類別
  95. • MJPEG = Motion JPEG • 一種視訊壓縮格式 • 每一個 frame

    都使用 JPEG 編碼 • 對運算能力與記憶體的需求較低 HTTP + MJPEG
  96. $ vi camera_pi.py import cv2 class Camera(object): def __init__(self): self.video

    = cv2.VideoCapture(0) def __del__(self): self.video.release() def get_frame(self): success, image = self.video.read() ret, jpeg = cv2.imencode('.jpg', image) • return jpeg.tostring() 從 Camera 讀取影像
  97. class Camera(object): • def __init__(self): • self.video = cv2.VideoCapture(0) •

    self.video.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 320) • self.video.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 240) • • def get_frame(self): • success, frame = self.video.read() • gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) • faces = faceCascade.detectMultiScale( • gray, • scaleFactor=1.1, • minNeighbors=5, • minSize=(30, 30), • flags=cv2.cv.CV_HAAR_SCALE_IMAGE • ) • for (x, y, w, h) in faces: • cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) • ret, jpeg = cv2.imencode('.jpg', frame) • return np.array(jpeg).tostring() Camera + OpenCV + HTTP Streaming $ vi camera_pi.py
  98. 227 • WiFi 連不上怎麼辦 ? • 接螢幕用 GUI 設定吧 •

    WiFi Config 的 Adapter 不見了怎麼辦 ? • 將 /etc/network/interface 和 /etc/wpa_supplicant/wpa_supplicant.conf 回復成預設值 常見問與答
  99. 228 $ cat /etc/network/interfaces auto lo iface lo inet loopback

    iface eth0 inet dhcp auto wlan0 iface wlan0 inet manual wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp $ cat /etc/wpa_supplicant/wpa_supplicant.conf ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 兩個檔案的預設值