Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Raspberry Pi Camera + Python

375,674 views

Published on

本投影片介紹 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 小時)
- 影像處理原理
- 人臉偵測

範例程式:
https://github.com/raspberrypi-tw/camera-python

Published in: Technology
  • Great discussion ! For what it's worth , people require a IRS W-9 , my boss filled a sample form here http://pdf.ac/7uVSiQ.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Raspberry Pi Camera + Python

  1. 1. Raspberry Pi Camera + Python 台灣樹莓派 <sosorry@raspberrypi.com.tw> May 31, 2015 / PyCon APAC 2015
  2. 2. 2
  3. 3. 3 ● 投影片下載 ● http://goo.gl/mLdZ18 ● 範例下載 ● https://goo.gl/1JdAT5 ● Hackpad 小抄 ● https://goo.gl/U9zhEO
  4. 4. 姓名標示 — 非商業性 — 相同方式分享 CC (Creative Commons) 姓名標示 — 你必須給予 適當表彰、提供指向本授權 條款的連結,以及 指出(本作品的原始版本)是否已 被變更。你可以任何合理方式為前述表彰,但不得以 任何方式暗示授權人為你或你的使用方式背書。 非商業性 — 你不得將本素材進行商業目的之使 用。 相同方式分享 — 若你重混、轉換本素材,或依本 素材建立新素材,你必須依本素材的授權條款來 散布你的貢獻物。
  5. 5. 5 ● Element14 指定台灣地區 Raspberry Pi 獨家經銷商 about 台灣樹莓派 http://farnell.com/raspberrypi-consumer/approved-retailers.php?region=apac&MER=MER-LM-OB-RPICC-76315
  6. 6. ● 專注於 Raspberry Pi 應用與推廣 ● 舉辦社群聚會 / 工作坊 / 讀書會 / 黑客松 ● Website : ● https://www.raspberrypi.com.tw/ ● Facebook : ● 搜尋 RaspberryPi.Taiwan ● https://www.facebook.com/RaspberryPi.Taiwan about 台灣樹莓派
  7. 7. 7 ● COSCUP, MakerConf, PyCon 講者 ● 投影片 ● http://www.slideshare.net/raspberrypi-tw/presentations ● 程式碼 ● https://github.com/raspberrypi-tw 分享 x 社群
  8. 8. ● Raspberry Pi Camera 簡介 ● 基礎 Camera 使用 ● 寫程式控制 今天會講
  9. 9. 沒有螢幕與鍵盤如何使用樹莓派?
  10. 10. 10 環境設定: Serial + WiFi 1. 樹莓派 Serial 連線 2. 樹莓派 WiFi 連線 用 Serial 來設定 WiFi 3. 筆電、手機、樹莓派 在同一個 LAN
  11. 11. 11 ● 以 USB 轉 TTL 傳輸線和 Pi 相連 ● 接線方式 ● 黑色: Pin 6 (GND) ● 白色: Pin 8 (Tx) ● 綠色: Pin 10 (Rx) ● 紅色:不接 Serial 連線方式
  12. 12. 12 Raspberry Pi B 的 GPIO (P1) 黑色線接 6 號 ( 第三根 ) 白色線接 8 號 ( 第四根 ) 綠色線接 10 號 ( 第五根 ) http://elinux.org/RPi_Low-level_peripherals
  13. 13. 13 Raspberry Pi B+ 的 GPIO (P1) 黑色線接 6 號 ( 第三根 ) 白色線接 8 號 ( 第四根 ) 綠色線接 10 號 ( 第五根 ) http://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/
  14. 14. 14 ● 安裝驅動程式 , http://goo.gl/QC5Q3O ● 從裝置管理員找到 COM 的埠號 ( 本例為 COM9) ● 下載 putty, http://goo.gl/zdD9G9 ● 執行 putty ● Session ● Serial line 填 COM9 ● Speed 填入 115200 ● Open ! ● 沒畫面 , 重新插拔電源 Serial Port in Windows
  15. 15. 15 ● $ ls /dev/ttyUSB* ● 開啟 putty ● 選擇 Session ● 在 Serial line 填入 /dev/ttyUSB0 ( 本例為 ttyUSB0) ● Speed 填入 115200 ● Open ! ● 無法連線時 , 使用 sudo 執行 putty Serial Port in Linux
  16. 16. 16 ● 安裝驅動程式 , http://goo.gl/htlt3F ● 重開機生效 ● $ ls /dev/cu* ● 如果有 /dev/cu.usbserial ● $ screen /dev/cu.usbserial 115200 ● 如果沒畫面,重新插拔電源 Serial Port in Mac
  17. 17. 17 ● 預設帳號 / 密碼: pi / raspberry ● 如果沒有畫面,將電源重新插拔 ● 如果出現亂碼,確定 baud rate 為 115200 連線成功
  18. 18. 18 ● 登入畫面 ● pi 是登入的使用者 ● @ 表示”在” ● raspberrypi 是主機名稱 ● ~ 表示在家目錄 (home directory) ● $ 表示該使用者所使用的 shell( 一種文字工具介面 ) ● 例如 $ nano myfile.txt ● 表示用 nano 編輯器開 myfile.txt 檔案 符號說明
  19. 19. 19 使用: nano 離開: Ctrl + x > 令存新檔: y > 不存離開: n > 離開: Ctrl + c nano 編輯器使用
  20. 20. 20 $ 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/ 在文字模式下設定無線網路
  21. 21. 21 $ 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 - 連線
  22. 22. 22 $ ifconfig wlan0 IP = 192.168.43.102 連線成功 查詢 IP
  23. 23. 23 ● 預設帳號 / 密碼: pi / raspberry 有了 IP, 用 SSH 連線
  24. 24. 24 ● 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( 今天不需設定 )
  25. 25. ● $ 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 安裝今日所需軟體
  26. 26. Raspberry Pi Camera 簡介
  27. 27. 從手機相機模組講起 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( 影像訊號處理器 )
  28. 28. ● 問:樹葉為什麼看起來是綠色的? ● 答:因為樹葉吸收了大部分可見光,只反射綠色光 基礎光學原理 https://www.raspberrypi.org/learning/infrared-bird-box/worksheet/
  29. 29. Type of Raspberry Pi Camera http://elinux.org/Rpi_Camera_Module Raspberry Pi Camera Module NoIR Camera Module
  30. 30. ● 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 ofView: 54 x 41 degrees ● Field ofView: 2.0 x 1.33 m at 2 m ● Fixed Focus: 1m to infinity ● 動態攝影最高解析度: 1080p@30 FPS with H.264/AVC 技術規格
  31. 31. Raspberry Pi Camera Module https://www.modmypi.com 15-Pins, CSI 介面 綠色 PCB 板
  32. 32. ● No IR = No 'IR cut filter' installed ● 因此 CMOS 可吸收到不可見光 (Infrared) ● No IR 相機 ≠ 夜視相機 ● 除非有額外的紅外線發光源 No IR Camera 黑色 PCB 板
  33. 33. 兩種相機效果比較 http://www.themagpi.com/issue/issue-18/ 1. 非 NoIR 相機 2. NoIR 相機 3. NoIR 相機 4. NoIR 相機 + 藍色濾光片
  34. 34. Raspberry Pi Camera 應用簡介
  35. 35. 移動偵測攝影 http://www.codeproject.com/Articles/665518/Raspberry-Pi-as-low-cost-HD-surveillance-camera
  36. 36. IP Camera 以樂高做外殼 加上 Camera 與按鍵
  37. 37. 37 雲端相機 http://learn.adafruit.com/diy-wifi-raspberry-pi-touch-cam 可做影像辨識的相機 5
  38. 38. 人臉辨識與追蹤 https://github.com/tasanakorn/rpi-mmal-demo/tree/develop
  39. 39. 脈博辨識 https://github.com/thearn/webcam-pulse-detector
  40. 40. 3D 建模計算深度 /2 Cameras http://www.raspberrypi.org/real-time-depth-perception-with-the-compute-module/
  41. 41. 360 度照片 https://vimeo.com/77218985
  42. 42. 效果
  43. 43. 3D 掃描 /50 Cameras http://www.pi3dscan.com/
  44. 44. 效果 + Autodesk Recap http://www.pi3dscan.com/
  45. 45. Camera 改裝套件
  46. 46. 固定的機構 http://www.modmypi.com/
  47. 47. 鏡頭改裝 http://www.modmypi.com/
  48. 48. 惡改鏡頭 http://www.truetex.com/raspberrypi
  49. 49. 外殼改裝 http://www.modmypi.com/ http://blog.pi3g.com/2013/11/coming-soon-raspberry-with-case-mounted-camera/
  50. 50. Camera 安裝
  51. 51. 安裝 Raspberry Pi Camera http://goo.gl/7LqyMY
  52. 52. $ sudo raspi-config
  53. 53. 啟用 Raspberry Pi Camera
  54. 54. 進階選項
  55. 55. 設定記憶體分配 >128M
  56. 56. 實戰 Camera 使用
  57. 57. 使用 Camera 前先消除靜電吧 http://www.wikihow.com/Remove-Static-Electricity
  58. 58. 58 實驗 1 : Hello Camera 目的:練習照相和攝影的指令
  59. 59. ● 只預覽 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
  60. 60. 常見 Camera 問題?
  61. 61. ● 錯誤訊息: Camera is not enabled in this build ● 解法:進 raspi-config 重新 enable camera ● $ sudo raspi-config
  62. 62. ● 錯誤訊息: Camera is not detected ● 解法:重新安裝 camera, 或是更換排線 或是檢查 camera module 是否鬆脫 https://www.modmypi.com/blog/how-to-replace-the-raspberry-pi-camera-cable
  63. 63. ● 錄 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
  64. 64. $ 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
  65. 65. 65 DEMO ./camera_effect.sh
  66. 66. 66 $ git clone https://github.com/raspberrypi-tw/camera-python.git $ cd camera-python $ cd 01_hello_camera $ ./camera_effect.sh 需要接上螢幕才能看到效果 執行方式
  67. 67. 更多參數或用法請看文件 http://goo.gl/VhyBaL https://www.raspberrypi.org/wp-content/uploads/2013/07/RaspiCam-Documentation.pdf
  68. 68. 如何看照片和影片?
  69. 69. 69 ● 是一種圖形應用標準 ● Client/Server 架構 ● X Client : 應用程式 ● X Server : 管理硬體輸入 / 輸出 ● 可透過網路傳輸 ● TCP/IP 或是 Unix Domain Socket ● X11 是通訊協定名稱 X Window System http://keyj.emphy.de/files/linuxgraphics_en.pdf
  70. 70. 70 ● Windows( 使用 Xming + putty) ● Xming 安裝 (http://sourceforge.net/projects/xming/)+ 下一步到底 ● putty > SSH > X11 > Enable X11 forwarding ● Linux/Mac : ssh -X pi@ip.of.pi X11 Forwarding using SSH
  71. 71. ● 看照片 ● $ 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 連線成功後
  72. 72. ● 第一步:編輯 /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
  73. 73. 嫌慢的話直接用網路線對接 https://pihw.wordpress.com/guides/direct-network-connection/
  74. 74. ● 在 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 網路設定
  75. 75. 75 實驗 2 :縮時攝影 目的:簡單合成影片做特效
  76. 76. 縮時攝影 (Time-Lapse Photography) http://en.wikipedia.org/wiki/Time-lapse_photography
  77. 77. ● 每間隔一段時間拍一張 ● 再將所有的照片接在一起 ● 調整播放速度 x = x 倍速的視覺效果 概念 http://en.wikipedia.org/wiki/Time-lapse_photography
  78. 78. ● 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/
  79. 79. 79 DEMO ./time_lapse.sh vlc timelapse.avi
  80. 80. 80 $ cd ../02_time_lapse $ ./time_lapse.sh 執行完畢後會多一個 timelapse.avi 檔案 , 使用 VLC 觀看 $ vlc timelapse.avi 執行方式
  81. 81. 81 實驗 3 :用手機 App 控制 目的:沒有螢幕也可以玩 camera
  82. 82. RaspiCam Remote @ Android
  83. 83. 連線 & 錄影
  84. 84. 調整效果:亮度
  85. 85. 85 實驗 4 :網路串流 目的:用播放器看結果
  86. 86. Streaming Media 技術架構 http://www.consilient-tech.com/strmmeda.shtml
  87. 87. RTSP 通訊協定 RTSP Client RTSP Server RTSP (TCP) : initiate RTP (UDP) : content RTCP (UDP) : control
  88. 88. ● 在 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
  89. 89. Live Media Player @ iPhone
  90. 90. 開啟 RTSP 串流
  91. 91. 91 DEMO ./rtsp_stream.sh 要配合電腦或手機觀看
  92. 92. ● 在 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=multipart/x-mixed- replace;boundary=-- 7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:80 80/video.mjpg}'} ● 開啟 Browser ● http://raspberrypi 的 ip:8080/video.mjpg HTTP + MJPEG https://goo.gl/U9zhEO
  93. 93. v4l2:///dev/video0 這是什麼東西? - 非官方的 V4L2 Driver
  94. 94. 回來看 camera 你有用過 webcam 嗎?
  95. 95. 95 Webcam http://www.slideshare.net/gxben/abs-2014-android-kit-kat-internals
  96. 96. ● 預定義好的 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.
  97. 97. Camera ≠ Webcam
  98. 98. 98 Modern Device Internal http://www.slideshare.net/gxben/abs-2014-android-kit-kat-internals
  99. 99. 99 Image Processing Pipeline http://www.slideshare.net/gxben/abs-2014-android-kit-kat-internals
  100. 100. 100 Image Processing Pipeline http://www.slideshare.net/gxben/abs-2014-android-kit-kat-internals ISP 在做的事 (HW) color space/format 轉換 (SW)
  101. 101. 101 http://elinux.org/Raspberry_Pi_VideoCore_APIs
  102. 102. 102 ● 開放多媒體加速層 (Open Media Acceleration) ● 由 Khronos Group 提出的標準 ● 統一的介面,加速大量多媒體資料的處理 OpenMAX https://www.khronos.org/openmax/
  103. 103. 103 Multimedia Stack Example http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Architecture/Multimedia_Domain
  104. 104. 104 ● Kernel driver ● 使用 camera 像是 webcam 一樣 ● sudo modprobe bcm2835-v4l2 ● 可直接存取 /dev/videoX ● v4l2-ctl --list-devices ● v4l2-ctl --list-formats ● v4l2-ctl -L ×OfficialV4L2 Driver https://github.com/raspberrypi/linux/blob/rpi-3.10.y/Documentation/video4linux/bcm2835-v4l2.txt
  105. 105. 105 ● 安裝 ● $ 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 SpaceV4L2 Driver(UV4L) http://www.linux-projects.org/modules/sections/index.php?op=viewarticle&artid=16
  106. 106. 106 ● 參考這幾隻程式吧 ● raspicam ● https://github.com/raspberrypi/userland/tree/master/host_ap plications/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
  107. 107. 107 實驗 5 :寫程式控制 Camera 目的:自己的 Camera 自己做
  108. 108. 使用 picamera (Python library)
  109. 109. 109 ● 變數 , 物件 , 型別 , 註解 ● 模組 ● 縮排 ● 迴圈 ● 條件判斷 ● 函式 ● 例外處理 ● with as Python 五分鐘速成
  110. 110. 110 ● 動態型別 (dynamic typing) # 這是註解 i = 3 # 變數 i 指到數字物件 3 i = [1, 2, 3, 4, 5] # 變數 i 指到串列物件 print(i[2]) # 印出串列中第三個元素 i = “abcde” # 變數 i 指到字串物件 print(i[2]) # 印出字串中第三個元素 變數 , 物件 , 型別 , 註解
  111. 111. 111 # 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
  112. 112. 112 ● 用縮排取代大括號 ● 程式碼的區塊是用縮排分隔 ● 不使用 tab, 使用空白鍵 ● 常見縮排為 4 個空白鍵 縮排
  113. 113. 113 ● 自動迭代 (iterator) for TARGET in LIST : # aaa ● # bbb # ccc # nameS = ["paul", "mary", "tom", "rita"] # for name in nameS : # print name 迴圈
  114. 114. 114 if CONDITION_1 : PROCESS_1 elif CONDITION_2 : PROCESS_2 else : PROCESS_3 ● # grade = 60 # if grade > 60 : # print "great" # else : # print "too bad" 條件判斷
  115. 115. 115 def FUNCTION() : PROCESS def FUNCTION( PARAM ) : PROCESS def FUNCTION( PARAM = 3) : PROCESS # def my_function(input = 5) : # print (input) 函式
  116. 116. 116 ● 程式何時會結束 ? ● 在正常情況下執行完畢結束 ● 遇到錯誤跳出 ● 受到中斷停止 ( 收到終止訊號 , 例如 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
  117. 117. 117 ● 使用 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
  118. 118. #!/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
  119. 119. 119 DEMO python picamera_take_photo.py 執行方式 $ cd ../05_picamera $ python picamera_take_photo.py
  120. 120. 120 ● 使用 scp ● 一個實做 SCP(Secure Copy Protocol) 的應用程式 ● 透過 SSH(Secure Shell) 傳輸資料 ● Windows 請安裝 WinSCP ● http://winscp.net/eng/download.php ● 從 Pi 複製檔案到 PC 上 ● scp pi@x.x.x.x:/home/pi/file.txt . ● scp file.txt pi@x.x.x.x:/home/pi 如何讓 Pi 和 PC 互傳檔案? http://winscp.net/
  121. 121. #!/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
  122. 122. #!/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
  123. 123. 123 DEMO python picamera_record_video.py python picamera_more.py
  124. 124. 加上一個按鍵吧
  125. 125. 125 ● 開關:按鍵式 , 滑動式 , 傾斜式 ... ● 常開 (normal open, N.O.) ● 常閉 (normal close, N.C.) 按鍵 Button / 開關 Switch http://nicegear.co.nz/
  126. 126. 126 ● 開關:按鍵式 , 滑動式 , 傾斜式 ... ● 常開 (normal open, N.O.) ● 常閉 (normal close, N.C.) 按鍵 Button / 開關 Switch
  127. 127. 127 按鍵的內部結構 ● 按下前 ● 長邊相連 (1&2, ¾3&4) ● 短邊不相連 ● 按下後 ● 四點都通
  128. 128. 128 要接哪一個腳位?
  129. 129. 129 ● 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
  130. 130. 130 Model B vs. B+ http://elinux.org/RPi_Low-level_peripherals http://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-header-details-and-pinout/
  131. 131. 131 Raspberry Pi Model B 的 GPIO (P1) http://elinux.org/RPi_Low-level_peripherals SPI / I2 C / UART / PWM Pin1 Pin2 Pin25 Pin26
  132. 132. 132 ● 決定是輸入還是輸出 ● 寫值到某根腳位 ● 從某根腳位讀值 ● 決定是前緣觸發還是後緣觸發 ● 等待中斷 (interrupt) 的發生 GPIO 是硬體的事 , 那軟體做什麼 ?
  133. 133. 133 ● 6 、 9 、 14 、 20 等腳位為接地,可互相交換 GPIO 腳位意義對照表 http://wiringpi.com/wp-content/uploads/2013/03/pins.pdf
  134. 134. 134 簡單的按鍵接法 BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO0)
  135. 135. 135 ● Input 空接會讀到雜訊 問題在哪裡? BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO0)
  136. 136. 136 麵包板的種類 https://goo.gl/JipVgH
  137. 137. 137 麵包板的使用 http://bugworkshop.blogspot.tw/2012/12/diy-breadboard.html 1. 藍色和綠色兩塊不通 2. 藍色垂直相通 3. 紅色水平相通 麵包板的內部結構
  138. 138. 138 更好的按鍵接法 http://geekgurldiaries.blogspot.tw/2012/12/part-2.html
  139. 139. 139 上拉電阻 / 下拉電阻 - 兩種電路的接法 http://playground.arduino.cc/CommonTopics/PullUpDownResistor
  140. 140. 140 上拉電阻 / 下拉電阻 - 還沒按下按鍵時 http://playground.arduino.cc/CommonTopics/PullUpDownResistor
  141. 141. 141 上拉電阻 / 下拉電阻 - 按下按鍵以後 http://playground.arduino.cc/CommonTopics/PullUpDownResistor
  142. 142. 142 線路圖 ( 上拉電阻 ) BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO0) Pin1 (3.3V) 1K 電阻 2K 電阻
  143. 143. 143 BTN_PIN = 11 GPIO.setup(BTN_PIN, GPIO.IN) try: whileTrue: if GPIO.input(BTN_PIN) == GPIO.LOW: print("Button.Click") except KeyboardInterrupt: print "Exception: KeyboardInterrupt" finally: GPIO.cleanup() 按下按鍵的判斷條件 ( 上拉電阻 )
  144. 144. 144 DEMO sudo python push_button_poll.py 讀寫 GPIO 會存取 /dev/mem, 需 root 權限 sudo 表示暫時切換身份到其他使用者 (root)
  145. 145. 145 ● 機械式開關在切換過程中會有訊號彈跳現象 ( 雜訊 ) 開關訊號的彈跳問題 (bounce) http://120.101.72.1/Onechip/PPT/ 實習單元三 .ppt 理想訊號輸出 實際輸出訊號
  146. 146. 146 ● 硬體方法:以 RC 電路或正回授的比較器電路解決 ● 軟體方法:調整觸發的延遲時間 ● 不同的按鍵會有不同的延遲時間 解決彈跳問題 (de-bounce) 10ms - 20ms
  147. 147. 147 TIME_LAPSE = 0.2 GPIO.setup(BTN_PIN, GPIO.IN) previousTime = time.time() try: whileTrue: currentTime = time.time() if GPIO.input(BTN_PIN) == GPIO.LOW and (currentTime - previousTime) >TIME_LAPSE: previousTime = currentTime print("Button.Click") except KeyboardInterrupt: GPIO.cleanup() 軟體方法:不反應在延遲時間內的觸發
  148. 148. 148 DEMO sudo python push_button_debounces.py & 一樣的線路圖 , 不一樣的程式
  149. 149. 149 但是這個程式的 CPU 用量挺大的 $ top -c 跑個按鍵偵測程式 CPU 使用率達 91.9% ( 如果使用 Pi 2 使用率約 2x%)
  150. 150. 150 ● 輪詢 (polling) ● SoC 每隔一段時間檢查週邊硬體的資料 ● 中斷 (interrupt) ● 當週邊硬體的狀態改變時 , 通知 SoC 輪詢與中斷
  151. 151. 151 ● 建立回呼函數 ● def callback() ● 綁定事件和回呼函數 ● add_event_detect(gpio, edge, callback=None, bouncetime=0) ● 多個事件可以綁定同樣的回呼函數 中斷的程式寫法 source/py_gpio.c
  152. 152. 152 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() 讀取按鍵
  153. 153. 153 DEMO sudo python push_button_interrupt.py 一樣的線路圖 , 不一樣的程式
  154. 154. 154 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() 按鍵控制拍照
  155. 155. 155 DEMO sudo python push_button_take_photo.py
  156. 156. 156 這 code 好像怪怪的 是我手有問題嗎?
  157. 157. 157 ● R= 電阻 , C= 電容 ● 利用電容放電維持準位 硬體方法:使用 RC 電路 http://www.eng.utah.edu/~cs5780/debouncing.pdf 按鍵還沒按下時 - 充電 按鍵按下後 - 放電
  158. 158. 158 線路圖 (RC 電路 )BUTTON RPi 腳 1 Pin6 (Ground) 腳 3 Pin11 (GPIO0) Pin1 (3.3V) Pin14 (Ground) 1k 電阻:棕黑黑棕 ( 棕 1k 電阻:棕黑黑棕 ( 棕 0.1u 電容: 104
  159. 159. 159 DEMO sudo python push_button_take_photo.py 一樣的程式 , 不一樣的線路圖
  160. 160. 160 實驗 6 :會認東西的 Camera 目的:串接網路服務
  161. 161. 影像辨識 http://googleresearch.blogspot.tw/2014/09/building-deeper-understanding-of-images.html
  162. 162. 更強大的看圖說故事 http://googleresearch.blogspot.tw/2014/11/a-picture-is-worth-thousand-coherent.html CNN : Convolutional Neural Network( 捲積式類神經網路 ) RNN : Recurrent Neural Network( 遞迴式類神經網路 )
  163. 163. 影像分類服務 https://imagga.com/
  164. 164. 看 DEMO http://imagga.com/auto-tagging-demo/?key=123#
  165. 165. Auto-Tagging http://imagga.com/auto-tagging-demo/?key=123#
  166. 166. 1. 註冊與認證 – https://imagga.com/auth/signup 2. 取得 API Key 和 API Secret – https://imagga.com/profile/dashboard 3. 串接 – input: 命令列 / 程式 – output: JSON 字串 如何開始使用服務? http://docs.imagga.com/
  167. 167. ● 驗證方式: Base64 Encode(api_key:api_secret) Base64 Encode - Online https://www.base64encode.org/ 冒號很重要 !
  168. 168. ● 原型 ● $ 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 YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1NTQ1Mm YwNTgzMQ==' 命令列 (shell) 串接 http://docs.imagga.com/
  169. 169. ● JSON(JavaScript Object Notation) 是一種資料結構 ● 物件 (object) 以 { } 表示 ● 鍵 / 值 (collection) 以 : 表示 ● 陣列 (array) 以 [ ] 表示 回傳結果 (JSON) http://docs.imagga.com/
  170. 170. ● $ 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/
  171. 171. { "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/
  172. 172. 172 DEMO
  173. 173. 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 YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1NTQ1M mYwNTgzMQ==" } response = requests.request("GET", url, headers=headers, params=querystring) print(response.text) Python 程式串接 (File URL) - 記得將紅色部份換成自己的 api_key 和 api_secret http://docs.imagga.com/
  174. 174. 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 YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1NTQ1MmY wNTgzMQ==" } 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
  175. 175. 175 DEMO python imagga_tag_file_url.py
  176. 176. ● 根據文件得知需要兩個步驟 ● 上傳檔案後取得檔案 uid ● 將 uid 以參數方式送出查詢 Python 程式串接 (Upload File) http://docs.imagga.com/
  177. 177. 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 YWNjXzJkYzdkNzNjMmYwODliMToxYzQ3Yzg2ZDg0YjdmYjdjYjZjNzQ1NTQ1MmYwNTgz MQ==" } 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
  178. 178. # … 接前頁 ● 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 以參數方式送出查詢
  179. 179. 179 DEMO python imagga_tag_upload_file.py
  180. 180. ● 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
  181. 181. 181 DEMO python imagga_tag_upload_and_speak.py
  182. 182. 182 實驗 7 :人臉偵測 目的:對 Camera 影像做處理
  183. 183. ● 跨平台的計算機函式庫 , 主要由 C/C++ 撰寫 OpenCV - Open Source ComputerVision Library http://www.embedded-vision.com/technology/computer-vision-algorithms
  184. 184. OpenCV 的架構 http://www.cse.iitk.ac.in/users/vision/dipakmj/papers/OReilly%20Learning%20OpenCV.pdf
  185. 185. import cv2 ● import sys ● imagePath = sys.argv[1] image = cv2.imread(imagePath) ● ● cv2.imshow("preview", image) cv2.waitKey(0) cv2.destroyAllWindows() ● ● ● 載入圖檔並顯示
  186. 186. 186 DEMO python image_load.py abba.png
  187. 187. 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 並顯示
  188. 188. 188 DEMO python camera_preview.py 使用前記得要先載入模組 $ sudo modprobe bcm2835-v4l2
  189. 189. ● 由 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/
  190. 190. ● 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
  191. 191. ● 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
  192. 192. ● 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
  193. 193. ● 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
  194. 194. ● 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
  195. 195. 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
  196. 196. 196 DEMO python image_face_detect.py abba.png haarcascade_frontalface_default.xml
  197. 197. ● 搜索視窗 vs. 檢測視窗 ● 搜索視窗在整個影像中移動 , 檢測視窗在搜索視 窗中移動並計算特徵值 ● scaleFactor: 搜索視窗成長比率 ● minNeighbors: 檢測區域鄰域內最少包含的檢測出 的備選人臉區域 ( 次數 ) ● minSize: 檢測視窗的最小尺寸 可調整的參數
  198. 198. scaleFactor - minNeighbors=5, minSize=(30, 30) scaleFactor=1.1 1.2 1.3 1.4 1.5 1.6
  199. 199. minNeighbors - scaleFactor=1.1, minSize=(30, 30) minNeighbors=1 2 3 5 10 20
  200. 200. minSize(x, y) - scaleFactor=1.1, minNeighbosr=5 minSize=(15, 15) (30, 30) (60, 60) (90, 90) (120 ,120) (150, 150)
  201. 201. 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 並辨識
  202. 202. 203 DEMO python camera_face_detect.py haarcascade_frontalface_default.xml
  203. 203. 204 實驗 8 : HTTP Video Streaming 目的:瞭解 Web Server 如何做 streaming
  204. 204. ● 原理 ● 向 Web Server 請求一個很大的檔案 ● 該檔案是一個即時的資料 使用 HTTP 做 Video Streaming
  205. 205. ● 一個軟體 ● 回應從 80/8080 port 進來的 HTTP 要求 ● 可透過 CGI 或 module 方式擴充 ● 如 Apache, Nginx, Boa 網頁伺服器 (Web Server) http://www.resultantsys.com/index.php/general/what-is-a-web-application-server/
  206. 206. 207 Flask - A Python Microframework
  207. 207. $ 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
  208. 208. $ 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 - 執行
  209. 209. 210 DEMO sudo python app-hello.py
  210. 210. 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
  211. 211. $ 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
  212. 212. $ sudo python app-route.py 執行
  213. 213. 214 DEMO sudo python app-route.py
  214. 214. 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'--framern' ● b'Content-Type: image/jpegrnrn' + frame + b'rnrn') ● ● @app.route('/video_feed') ● def video_feed(): ● return Response(gen(Camera()), ● mimetype='multipart/x-mixed-replace; boundary=frame') Streaming 圖片
  215. 215. $ 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 類別
  216. 216. $ vi templates/stream.html <h1>Hello Stream</h1> <img id="bg" src="{{ url_for('video_feed') }}"> ● 補個圖 1.jpg, 2.jpg, 3.jpg 修改 template
  217. 217. $ sudo python app-stream.py 執行
  218. 218. 219 DEMO sudo python app-stream.py
  219. 219. ● MJPEG = Motion JPEG ● 一種視訊壓縮格式 ● 每一個 frame 都使用 JPEG 編碼 ● 對運算能力與記憶體的需求較低 HTTP + MJPEG
  220. 220. $ 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 讀取影像
  221. 221. 222 DEMO sudo python app-camera.py
  222. 222. 223 加上 OpenCV 功能做撒尿牛丸吧
  223. 223. 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
  224. 224. 225 DEMO sudo python app-opencv.py
  225. 225. Raspberry Pi Rocks the World Thanks
  226. 226. 227 請幫忙填問卷 http://goo.gl/forms/4gzeuVdrWL
  227. 227. 228 ● WiFi 連不上怎麼辦 ? ● 接螢幕用 GUI 設定吧 ● WiFi Config 的 Adapter 不見了怎麼辦 ? ● 將 /etc/network/interface 和 /etc/wpa_supplicant/wpa_supplicant.conf 回復成預設值 常見問與答
  228. 228. 229 $ 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 兩個檔案的預設值

×