AIOT 邊緣運算工作坊
機器學習模型實戰布署,手把手體驗邊緣運算的威力
內容簡介
作者介紹
適合人群
你將會學到什麼
購買須知
-
AIOT手把手課程內容
-
01 - RaspberryPI 介紹
10/30(六) 課程時程表 知識地圖 – Raspberry PI介紹 重要知識點 Raspberry Pi 版本介紹。 Raspberry Pi 4 所需材料。 Windows、Linux 的平台製作 PI 開機映像 。 Raspberry PI 開機失敗可能的原因。 Raspberry PI 各版本比較 Raspberry Pi 4 介紹 A 1.5GHz quad-core 64-bit ARM Cortex-A72 CPU (~3× performance) 1GB, 2GB, or 4GB of LPDDR4 SDRAM Full-throughput Gigabit Ethernet Dual-band 802.11ac wireless networking Bluetooth 5.0 Two USB 3.0 and two USB 2.0 ports Dual monitor support, at resolutions up to 4K VideoCore VI graphics, supporting OpenGL ES 3.x 4Kp60 hardware decode of HEVC video Complete compatibility with earlier Raspberry Pi products 補充資料:Raspberry Pi Blog Pi4 相關所需的材料 Raspberry PI4 記憶體 4G 版本 樹莓派原廠 Raspberry Pi 4B 電源供應器,USB-C 接頭 5V / 3A SDCard,建議 32G Byte,PI4開機硬碟 樹莓派官方原廠 Micro HDMI 轉 HDMI (A/M)傳輸線(1m/2m) | Micro HDMI to Standard HDMI (A/M) 1m/2m Cable (或者可以買轉接頭) 雙風扇散熱模組(Pi 4 適用) Raspberry PI 如何開機 準備一張 MicroSD 卡 下載 PI 的開機映像檔案,安裝至 MicroSD 卡上 Raspberry Pi OS downloads 透過較新的 PiImager 來下載映像檔案 下載各作業系統的 PiImager Raspberry Pi Imager for Windows Raspberry Pi Imager for macOS Raspberry Pi Imager for Ubuntu 準備一個可以燒錄 SDCard 的裝置 Raspberry PI 建議的安裝作業系統 Pi Imager 安裝各種 Pi 的開機映像檔案 Choose OS(選擇作業系統) Raspberry PI OS(32-bit) Choose Card(選擇要寫入的SD Card) Write(開始寫入映像檔案) Pi Imager 寫入過程 寫入映像檔案完成 可以將 SDCard 拔出,再重新插入一次 Raspberry PI OS 燒錄成功後 Raspberry PI OS 燒錄成功後,將 SDCard 重新插入 windows 電腦,顯示的磁碟機內容 還有許多不同的 Pi 開機映像檔案 Raspberry PI OS(桌面或純文字版本) Rasberrpy PI Imager 優點 直接選擇要下載安裝的作業系統版本 網路直接下載 選好 SDCard 位置直接開始寫入 要注意的是 網路穩定性與傳輸速度影響製作時間 會有等待重新傳輸的情形 先下載好映像檔案再燒錄 可以先下載好個別的映像檔案,之後再進行多次的燒錄。 可以使用 etcher 這類開機映像檔案燒錄至 sdcard 的軟體,進行開機 sdcard 的製作。 資料來源:https://www.balena.io/etcher Etcher 燒錄畫面,與 Pi Imager 類似 可以自行選擇硬碟中預先下載好的映象檔案,只要符合 img 格式就可以燒錄。 PI 4 開機與周邊接線圖 資料來源:Connect your Raspberry Pi 可以準備 Pi 開機了 準備一個PI專屬的電源供應器。 一般的手機電源供應器如果輸出電流,小於 2.5A 會有問題。(廠商建議5V/3A的電源) 電流太低可能還是可以開機, 但是後續在接攝影機、 繼電器、感測器,可能會無預警 電源過低重新開機。 開機過程電源不足 開機的過程中,如果看到右上角出現閃電的符號,代表輸入的電源不足,隨時可能會重新開機。 盡量避免這樣的狀態,因為這就很像電腦不斷的重新不正常重新開機,sdcard 的資料內容很可能產生寫入不完整的問題,最後導致sdcard資料毀損而無法再開機。 PI 為何開不了機 如果插上螢幕線,電源也確定插好了,沒有看到螢幕,很可能是 SDCard 寫入失敗。 因為 SDCard 開機,在 Pi3 跟 Pi4 的開機過程不同,剛燒好的 SDCard 在第一次開機的時候會偵測是在何種 pi 上面開機,會自動依據目前開機所用的 pi 做系統調整,pi4 的 sdcard 拔下來在 pi2,3 有可能會無法開機。 Pi4 的螢幕是用右邊的 HDMI 作為內定輸出。 開機內定顯示螢幕 HDMI 輸出 知識點回顧 PI 有各個硬體不同的版本,目前常見的有 pi zero wh, 2, 3, 4 等版本,各版本都可以用Raspberry PI OS(32-bit) 開機。 Pi Imager 可以直接下載PI的開機映像檔案直接燒錄至 SDCard,可以邊下載邊寫入,寫入的時間相對較長(跟網路傳輸速度有關)。 可以先單獨下載開機映像檔案之後,再使用 etcher 相關的軟體寫入 sdcard,相對比較容易確定寫入時間跟穩定性。 PI運作時電源的穩定性決定了運作的成敗,一般的手機電源可能不適合,建議一定要用 5V/3A 以上的電源,目前只有 Pi 4 是使用 Type-C 的電源接頭,其他的版本建議用 2.5A micro USB Supply。 作業 請參閱作業範例: 作業1:觀察 Raspberry PI OS 桌面與純文字版本映像檔案的檔案大小,實際下載之後解壓縮,紀錄實際下載與解壓縮的時間。 作業2:Raspberry PI OS 開機後會自動的將 sdcard 的硬碟空間擴展成 SDCard 所有的區域,觀察開機的過程,確定可以順利的開機並且使用內定的帳號 pi,密碼 raspberry 登入系統。 作業3:練習設定 pi 無線網路,確定 pi 的網路可以穩定的連線至無線基地台,順利的取得無線基地台發送的 ip 與網路設定,並且啟動瀏覽器順利上網。 參考資料 Pi Imager 使用步驟 本影片為官網提供之短片,按照官網軟體操作,可以直接進行映像檔案的安裝,網路穩定快速的狀況下,可以方便的開始使用 Raspberry PI。 設定 PI 的無線網路 Raspberry Pi 4 安裝 Raspbian Buster,本文章描述過去在沒有 pi imager 之前,如何透過官網的下載點,下載最新版本的 Raspbian 作業系統映像檔案,並且透過 etcher 寫入 sdcard 製作開機 sdcard 的過程。 之後透過桌面管理的控制流程,設定網路以及遠端連線進入的各項設定。
-
02 - Linux 常用指令教學
知識地圖 – Raspberry PI 介紹 重要知識點 Raspberry PI 系統管理指令 df 、date、 sudo、raspi-config、apt、systemctl、cron、/etc/crontab Linux 的檔案管理、權限控制、裝置掛載、檔案下載 pwd、mkdir、cd、rmdir、cp、rm、chmod、uptime、top、mount、wget Linux 檔案文字編輯器 vi、nano、joe Linux 檔案壓縮 tar、bzip2 Linux 網路設定 ip、/etc/wpa_supplicant/wpa_supplicant.conf 顯示 Linux 裝置容量 用 df -h 來觀察目前系統各個硬碟跟裝置掛載使用量。 顯示系統版本、系統目前時間 uname -a:顯示系統核心的版本與編號 cat /etc/os-release:顯示作業系統版本 Linux 的 sudo 指令 Linux 使用者登入系統之後,並沒有辦法執行系統管理者所擁有權限的指令,為了方便管理者管理一般使用者執行特定指令的安全性,系統管理者可以在 /etc/sudoers 設定,哪一個使用者可以採用 sudo 的方式來取得系統管理者的權限,執行需要安全性權限的指令。 在系統安全性執行的管理上,一般使用者要取得系統管理者權限,執行具有與管理者相同權限的動作,可以透過 sudo 指令取得系統管理者權限後,開始執行相關後續的指令。 只有超級使用者有權限編輯 /etc/sudoers 文件,一般會用 visudo 來編輯 /etc/sudoers 文件,避免一些潛在的語法錯誤。 /etc/sudoers 檔案範例 /etc/sudoers 檔案說明 看檔案中 root 有所有權限,參考 root 的例子就行,在下面加一行 (最好用 Tab 作為空白),例子中加入了一個 aiot 帳號身分的使用者具有使用 sudo 指令的設定。 上面的設定可以讓 aiot 使用 sudo 指令時,權限跟 root 一樣,如果感覺權限太大,可以限制使用者可以使用 sudo 時候可以執行的指令。 那三個 ALL 到底是什麼意思。第一個 ALL 指網路中的機器名稱,可以把它改成某台機器名。第二個括弧裏的 ALL 是指哪一個身份可以執行命令。最後一個 ALL 是哪一個命令可以執行,如果是全部都可以就寫 ALL。 /etc/sudoers 檔案更改需要注意的事項 例如,我們想讓 aiot 用戶在主機上不用輸入密碼,又可以執行 /bin/cat 以及 /bin/ls 這些指令,可以按照這樣寫 要注意的是 /etc/sudoers 的內容一定要全部都是正確的狀態,否則會造成之後無法從遠端登入使用 sudo 指令的狀態,同時也無法從遠端修復 /etc/sudoers 內容的錯誤 (因為無法再透過 sudo 命令列切換 root 身分) 嚴格的說,/etc/sudoers 錯誤之後,將會產生無法線上處理修復的狀態,這個情況在每次修改 /etc/sudoers 的時候,需要非常小心撰寫設定檔案,因為錯了就無法遠端修復了。 Raspberry PI 系統設定指令 (raspi-config) raspi-config 需要超級使用者身分才能使用 要先執行 sudo su 的指令,將使用者身分切換為超級使用者,密碼為使用者登入的密碼 底下是 raspi-config 提供系統的設定選項。 raspi-config 設定 pi 各種基礎環境工作模式 raspi-config 是 pi 特有的系統設定指令,讓使用者可以很容易的設定 pi 的工作方式,使用者可以透過 raspi-config 設定管理者的密碼、系統工作的模式(視窗模式、純文字模式)、登入無線網路基地台的帳號密碼等。 raspi-config 常用的系統運作設定在系統的語系、時區、鍵盤配置設定,以及硬體接腳設定等部分。 raspi-config 硬體接腳設定在 Interfacing Options 選項中,因為 pi 避免在板子上面做太多的跳線開關,一方面省下跳線接腳占用的主板空間,另外一方面直接用軟體設定相對方便許多,因此提供了軟體設定接腳在各種狀態下的設定,如啟動 i2c、spi、RX/TX 接腳介面的設定。 raspi-config 內 Display Options 選項 raspi-config 第二個選項的 Display Options,提供各種顯示解析度給使用者選擇,這個選項的設定對於沒有外接顯示器的情況下,可以強迫軟體使用固定的解析度輸出,對於使用者在沒有實體螢幕但要用 VNC 遠端連線時非常重要。 raspi-config 內 Interfacing Options 選項 Camera:如果有用板子上的攝影鏡頭傳輸線,需要將這個選項點選啟動。 SSH:啟動 ssh 伺服器,讓其他的電腦可以使用 ssh 遠端連線至 pi。 VNC:啟動 vnc server,客戶端可以用 RealVNC 連接至 pi。 SPI:系統啟動時自動載入 SPI 的核心模組。 I2C:系統啟動時自動載入 I2C 核心模組。 Serial:使用 RX/TX 接腳作為核心訊息傳遞。 1-Wire:啟動 1-Wire 感測器接腳的運作模式。 Remote GPIO:啟動遠端存取 GPIO 接腳的模式。 Debian 升級套件指令 apt APT 是 Debian 及其衍生的 Linux 軟體包管理器。apt 最主要的用途在安裝以及升級各種的軟體套件。 Apt 主要是透過一個軟體更新列表,提供目前最新的軟體版本狀態,平常需使用 apt update 進行更新軟體版本列表。 透過 apt 可以方便的安裝例如 ffmpeg(影片壓縮)、imagemagic(影像格式轉換)、mplayer(媒體撥放器)、joe(文字編輯器)等程式。 apt install ffmpeg:安裝 ffmpeg 程式 apt install mplayer:安裝 mplayer 媒體撥放程式 apt remove ffmpeg:移除 ffmpeg 程式 apt search ffmpeg:搜尋可以安裝跟 ffmpeg 相關的軟體 systemctl 設定 pi 開機時自動啟動背景服務 開機時可以啟動各種服務,例如自動取得 ip、網路芳鄰(samba)、週期性服務(cron)、遠端連線(ssh)等,都可以用 systemctl 來設定或更改啟動狀態,以及關閉各種目前啟動的服務。 systemctl 操作指令 服務名稱,需要注意 systemctl 需要在 root 的權限下才能使用,因此常搭配 sudo 使用。例如 ssh 服務: systemctl start ssh:啟動 ssh 服務(可以遠端連線至 pi) systemctl stop ssh:停止 ssh 服務(這樣就斷線了,小心) systemctl restart ssh:重新啟動 ssh 服務 systemctl status ssh:目前 ssh 服務的狀態(啟動或關閉) cron 設定週期執行指令 自動化週期設定,可以讓我們在某一個設定好的時間,自動的讓系統可以執行某一個程式,這對於 pi 而言,可以大幅度的提升各種時間搭配環境的應用。 cron 透過 systemctl 可以設定開機之後就自動執行,並且將 /etc/crontab 的設定載入至記憶體中,然後觀察目前的時間點,需要啟動哪一個程式開始執行。 我們可以透過 /etc/crontab 設定固定多少分鐘執行一次指令,或者多少小時或多少天之後自動執行我們需要的動作,這樣只要專心的將各個單獨功能的程式寫好,時間到了 cron 就會依據 /etc/crontab 裡面設定好的時間條件,幫我們自動執行所需要的功能。 /etc/crontab 設定週期工作排程內容 Linux 的檔案管理指令 檔案的建立、顯示、複製、搬移、刪除、搜尋是最常用的部分 顯示檔案內容:cat 檔案內容 顯示目前路徑所含有的檔案:ls –al * 複製檔案:cp 來源檔案名稱或目錄名稱 目的檔案名稱或目錄名稱 搬移檔案:mv 來源檔案名稱 目的檔案路徑 刪除檔案:rm 檔案名稱 搜尋檔案:find ./ -name “*aiot*” 找尋目前所在目錄內,含各子目錄內有 *aiot* 檔案名稱 補充資料:Setting up your Raspberry Pi Linux 檔案命令範例 pwd:顯示目前的工作路徑 mkdir piaiot:在目前所在路徑的子目錄,建立 piaiot 子目錄 cd piaiot:切換至 piaiot 子目錄 ls -al:顯示目前工作目錄(aiot)的所有檔案 cp *aiot* /tmp:將名稱包含 aiot 的檔案複製到 /tmp 底下 chmod 755 *:將目錄內所有檔案權限設定為 +rwxr-xr-x rm *aiot*:將名稱包含 aiot 檔案刪除(要小心,刪除無法復原) uptime:目前系統從開機到現在已經經過多久的時間(這可以觀察是否 pi 運作的過程中,是否有不穩定重開機的現象) top:系統運作的狀態,可以觀察記憶體與 cpu 的使用量 Linux 掛載外部周邊裝置(mount) Linux 許多的周邊裝置都是用檔案的概念來做為存取資源的途徑。在 linux 使用 mount 指令來掛載許多外部的資源。 一般使用 mount 指令掛載 device,最常見方式像這樣 mount -t type device dir 例如掛載光碟映像 .iso 檔案至某一個子目錄之下 mount -t iso9660 -o loop /home/seal/myiso.iso /mnt/myiso 如果想查看系統中所有設備掛載的狀況,可以直接執行 mount 指令不加任何參數。 要卸載目前掛載的資源, 可以使用 umount 掛載目錄,例如上面卸載的指令為 umount /mnt/myiso。 Linux 壓縮、解壓縮指令 有各式各樣的壓縮軟體可以在 linux 底下執行 最常用的是tar,近年來常用的有 bzip2 以及 xz, windows 上常用的 zip 在 linux 上也有支援,7z 需要用 apt install p7zip-full 來安裝。 tar cvf pi.tar /home/pi : 將/home/pi打包成為 pi.tar (無壓縮)。 tar zcvf pi.tar.gz /home/pi:將 /home/pi 壓縮成 pi.tar.gz 檔案。 bzip2 pi.tar : 將 pi.tar 用 bzip2 壓縮為 pi.tar.bz2。 tar zxvf pi.tar.gz:將 pi.tar.gz 解壓縮至目前工作的目錄。 tar jxvf pi.tar.bz2:解壓縮 pi.tar.bz2 至目前工作的目錄。 Linux 的文字編輯器 大部分 linux 內建文字編輯器為 vi。 近年來有輕量級的文字編輯器 nano。 另外可以透過 apt 指令安裝如 joe、emacs、sublime、vscode 等文字編輯器。 各編輯器的操作方式都不太一樣,vi 需要背一些常用的操作指令,目前大都使用 vi 的新版 vim,來做為內建的文字編輯器軟體。 用 ip 指令來觀察跟設定 ip 位址 ip 指令整合 ifconfig 與 route 這兩個指令,同時能 進行額外的 IP 協定設定,包括多 IP 設定。 ip address show:顯示目前的 ip 設定 ip link set wlan0 down:關閉網路介面(斷網, 要在單機測試) ip link set wlan0 address cc:cc:cc:cc:cc: 更改 wlan0 的 mac ip address add 192.168.50.50/24 broadcast 255.255.255.0 dev wlan0 label wlan0:test (新增一個子網路設定) ip address del 192.168.50.50/24 dev wlan0:test (刪除 wlan0:test 設定) 用 ip 指令來觀察跟設定 ip 路由 ip route show:顯示目前網路卡的路由 ip route add 192.168.5.0/24 dev wlan0:test ip route add 192.168.10.0/24 via 192.168.50.50 dev wlan0 (增加對 192.168.10.0/24 的路由, 必須由 192.168.50.50 轉發) ip route add default via 192.168.1.254 dev wlan0 (wlan0 的預設 gateway,記得 default gateway 只能有一個) Pi 如何設定無線網路 Pi 無線設定在 /etc/wpa_supplicant/wpa_supplicant.conf,這個檔案內包含連線時的 ssid 以及連線用的密碼。 按照格式修改 ssid(無線基地台名稱)與 psk(無線基地台的密碼),可以設定很多個基地台的資料,方便在不同場地自動登入。 知識點回顧 可以設定 /etc/sudoers,讓一般使用者能夠使用 sudo 指令切換為 root 的身分,透過 apt 指令來進行 pi 軟體的升級。 擁有 root 身分之後,可以使用 systemctl 來設定各種的系統服務,以及 cron 來執行特定或週期時間的各種指令。 pwd 可顯示目前工作的路徑,之後使用 mkdir 可建立子目錄,cd 切換工作路徑,cp 複製檔案,rm 刪除檔案或子目錄。chmod 可以更改檔案的權限,在安裝系統或程式的時候需要注意權限的正確性。 uptime 可以顯示目前 pi 從開機到現在已經工作多久,top 可以顯示目前那些程式使用 cpu 以及記憶體的狀態。 mount 指令可以掛載 usb 的硬碟,以及各種外部的裝置。 ip指令能夠設定網路卡 ip 的設定以及 route 路由的設定,相對過去 ifconfig 以及 route 相對方便許多。 /etc/wpa_supplicant/wpa_supplicant.conf 可以設定多個 ap 的 ssid 跟密碼,方便之後切換不同場地時的無線網路連線。 作業 請參閱作業範例 : 作業1 : 使用 raspi-config 更改 root 的密碼,設定連線的無線基地台,開啟 ssh 伺服器,確定可以用遠端連線進入 pi。 作業2 : 切換至 /opt 路徑,建立一個 /opt/aiot 子目錄,切換至 /opt/aiot 子目錄,用 wget 指令下載一個網路上的檔案,下載完成後用 ls –al 指令,確定下載的檔案存在。 作業3 : 切換至 / 根目錄(指令: cd /),壓縮 /opt 子目錄進行備份,使用 tar zcvf opt.tar.gz /opt,以及bzip2 opt.tar.gz 壓縮成 bz2 格式,最後將 opt.tar.gz 用 tar zxvf opt.tar.gz 指令練習解壓,或者將 opt.tar.gz 解壓至 /tmp 之下,確定 /opt 子目錄有壓縮備份成功 。 參考資料 一次做好 Raspberry Pi 3B+ 系統安裝 ( 沒螢幕 沒鍵盤 沒滑鼠 ) 本文件講解有關 raspi-config 的操作設定,內含如何設定不用滑鼠、鍵盤、螢幕的 pi 遠端控制安裝模式。 Ubuntu apt 安裝指令 本篇是常用 apt 指令的簡易說明,可以方便常用只會用最簡單的指令。 15 Examples of How to Use New Advanced Package Tool (APT) in Ubuntu/Debian 想要瞭解深入的 apt 指令各種參數的範例,可以看這一篇文件,偶爾在 apt 出現一些問題時,可以參考用來修復一些可能的 apt 問題。 Linux systemd 系統服務管理基礎教學與範例 本篇介紹如何在各種 Linux 下使用 systemctl 指令管理 Systemd 的系統服務。 傳統上的 Linux 都是靠 System V 的 init 來啟動各項系統服務,而後來新的 Systemd 出現之後,許多主流的 Linux 發行版都改用 Systemd 來管理系統服務,新的 Systemd 跟傳統 System V 的 init 相比,開機速度更快、效能更好、具有相依性檢查功能。 Linux 設定 crontab 例行性工作排程教學與範例 本篇介紹如何在 Linux 系統上使用 crontab 工作排程,設定讓系統定時自動執行指定的指令或程式。 Linux 的管理者或使用者如果需要定期執行某些指令或程式,最常見的方式就是使用 cron 來幫忙管理例行性工作排程,只要設定好 crontab 設定檔之後,系統就會自動依照設定的時間,定期執行重複性的工作。 External storage configuration 掛載一個週邊裝置是很重要的概念,Unix 所有的周邊裝置都是使用檔案形式來做為存取的進入點。 Linux 檔案系統掛載(mount)使用教學與範例 這裡將介紹在 Linux 中常用的掛載方式,也就是 mount 與 umount 兩個指令的使用方式 GNU/Linux各種壓縮與解壓縮指令 壓縮軟體是系統備份重要的工具,最主要要參考的是不同壓縮軟體的壓縮與解壓縮參數,本文可以當作一個快速提示的參考。 讓 Ubuntu 可以壓縮/解壓縮 RAR 檔案 linux 剛安裝的時候是不能解壓 rar 檔案的,只有在安裝瞭解壓工具之後,才可以解壓 rar。 apt install rar。 apt install unrar。 每個開發者都應該要會用的編輯器 – vim Vim 是大部分系統都有內建的編輯器,所以當你打開一個全新的電腦,或是用任何人的電腦,他們不一定會裝你熟悉的 sublime 或是 vs code,但是一定有 vim 可以用。再者,它可以直接在 terminal 介面裡面操作,當你只是需要快速修改某個檔案,或是握一些簡單的編輯又不想開肥大的 IDE 時,vim 是個非常方便的選擇。 設定 pi 的無線網路 講述如何透過 raspi-config 直接設定網路的方法,相對需要更多設定的時候,會需要 /etc/wpa_supplicant/wpa_supplicant.conf 相關的設定,可以參考官方文件的做法。 [基礎] 命令列設置無線網路 這一篇是中文版本的文件,包含了無密碼方式的設定,以及 wep 的密碼設定方式。 修復/etc/sudoers 如果你的 /etc/sudoers 壞掉了,最簡單的方法是把你的 sdcard 拔下來,另外稍一片 sdcard 可以開機的狀態下,將原始的 sdcard 掛在 pi 上面當作另外一個硬碟來使用,這樣就會可以修改另外一個硬碟的內容。 重新編輯 /etc/sudoers 完成存檔後,可以關機,然後把修好的 sdcard 插在 pi 上開機,這樣的方式與 ubuntu 失敗的過程修復方式是相同的。 How to Fix “Username is not in the sudoers file. This incident will be reported” in Ubuntu
-
03 - 攝影機影像與控制儲存
知識地圖 – Raspberry PI 介紹 重要知識點 video4Linux 媒體裝置存取檔案架構 WebCam 作為 Linux 週邊裝置存取方式 fswebcam 介紹 fswebcam 安裝與使用介紹 透過 Python 呼叫 fswebcam 進行 WebCam 操控 讓 WebCam 拍一張相片,並且儲存 Video4Linux 介紹 Video4Linux(V4L) 是視訊擷取及裝置輸出的 API,以及 Linux 的驅動程式框架,支援很多 USB 網路攝影機、影像擷取裝置與其他裝置,如影片監控軟體、webcam 控制與資料讀取,同時也常使用在 linux 嵌入系統的開發環境。 Video4Linux 常見支援的軟體有,Ffmpeg、FreeJ、Gstreamer、Mplayer、OpenCV、Skype、VLC 多媒體播放器等。 V4L 分為兩層架構,底層為影音設備在核心中的驅動程式,上層為系統提供的 API,希望能達成讓程式開發人員透過核心所提供的 API,控製影片和音頻設備,這樣的好處是對程式開發人員只需要學習系統 API 就可以控制不同類型的影音設備。 補充資料:raspberry-gpio-python Video4Linux 框架簡介 當 /dev 內有某個檔案名稱出現時,代表作業系統與外部周邊裝置使用某一個方式來進行資料的存取。 視頻擷取/輸出(/dev/videoX) 編碼/解碼器(/dev/videoX,streaming 和控制) 原始和切割 VBI 擷取與輸出(/dev/vbiX,streaming 和控制) 無線電調諧和調製(/dev/radioX,控制,ALSA 傳輸) RDS 接收器/發射器(/dev/radioX,AM and FM (analog) radio 接收以傳送) 軟體定義無線電(/dev/swradioX, Software Defined Radio tuners ) 低級別子設備控制(/dev/v4l-subdevX,控制) 設備拓撲發現/控制(/dev/mediaX,控制) 觸控裝置: ( /dev/v4l-touchX,觸控感測器 ) 橋驅動控制的 DMA 傳輸 / USB / PCI 等硬體,電路板配置(USB ID,PCI ID,內核配置,Device Tree,模塊選項),掛載必要子設備驅動程序,註冊橋驅動程序需要的設備節點。 video4Linux2 內含於 Linux 核心 在 Linux 系統中各種設備,本質上都是用檔案形式來存取使用,在 Linux 中各種外部設備的使用,於 dev 目錄下,如果它們已經正確的被驅動,在之後寫程式存取與控制時,基本上與檔案操作的觀念,本質上是沒有什麽區別的。 V4L2(Video4Linux 2nd)是一套 Linux 針對視訊設備(例如 Webcam)所定義好的 Userspace API,因此硬體廠商只要能實做 API 的功能,就能讓使用者透過統一的介面控制硬體。如此一來上層的使用者就即使不知道硬體的廠牌與底層的實做方法,只要知道呼叫相同的函式就能得到相同的結果。 安裝 v4l2 模組,以 python 存取 video4Linux 官方的下載網址是:https://pypi.org/project/v4l2/。 python3 內建的安裝命令是 pip3 install v4l2,在實際操作的過程中,會發現官方提供的 v4l2 版本在 python3 匯入時會發生錯誤。 目前可以透過以下的指令下載與安裝修正過的 v4l2 模組。 UVC 介紹 USB video class(又稱為USB video device class or UVC),目的是提供視訊產品不需要安裝任何驅動程式下即插即用,包括網路攝影機(Webcam)、數位攝影機(Digital Camcorders)、類比影像轉換器(Transcoders)、電視卡(TV Receiver Card)等。 在 Linux 上如果有一個支援 UVC 的 Webcam 插到 USB,就會向 Kernel 註冊為 Webcam 設備,裝置節點為 /dev/videoX。 最新的 UVC 版本為 UVC 1.5,由 USB-IF(USB Implementers Forum)定義包括基本協議及負載格式。 簡單的說 V4L2 就是用來管理 UVC 裝置,提供視訊 API。 補充資料:Linux下Camera程式設計–V4L2 UVC 裝置查詢 UVC 視訊顯示需要滿足三個條件: UVC 的 Camera 硬體支援 UVC 驅動程式支援,包括 USB 裝置驅動以及 V4L2 的支援 應用程式支援 Linux UVC 驅動程式為了全面支援 UVC 裝置,視訊裝置或 USB 視訊定義視訊串流,UVC 只需通用驅動支援就能正常工作,就像 USB 大容量儲存裝置一樣。 判斷視訊裝置是否支援 UVC 規格的方法: 使用 lsusb 命令或其他硬體資訊檢視工具,找出視訊裝置的裝置標號(Vendor ID)和產品號(Product ID)。 查詢是否有視訊周邊裝置的資訊,使用下面的指令 lsusb -v | grep “14 Video” 如果相容 UVC,則會輸出類似資訊 bFunctionClass 14 Video bInterfaceClass 14 Video 如果沒有以上資訊,則是沒有支援 UVC 的裝置(non-UVC)。 取得 webcam 支援的擷取解析度 取得連接 webcam 支援擷取解析度與 frame rate v4l2-ctl --list-formats-ext -d /dev/video0 fswebcam 介紹與安裝 fswebcam 可以從這裡下載,有原始碼與相關的參數,webcam 擷取產生影像,由 GD 繪圖函式庫繪製減少雜訊的影像。 http://www.sanslogic.co.uk/fswebcam/ https://github.com/fsphil/fswebcam fswebcamfswebcam 的安裝方式: sudo apt install fswebcam 要拍照片最簡單的方法: fswebcam image.jpg 設定影像擷取的解析度為 640x360,忽略前面 10 張影像,由 /dev/video0 的裝置取得資料,儲存在 webcam.jpg fswebcam -r 640x360 -S 10 -d /dev/video0 webcam.jpg fswebcam 擷取影像,參數範例 Fswebcam 可以用來做背景執行,或者也可以透過 crontab 設定定時的執行來執行固定時間的拍照動作,可以將參數設定寫在檔案裏面,執行 fswebcam 的時候,使用指令: fswebcam –c fs.conf # fs.conf 內容是 fswebcam 執行時所設定的參數 fs.conf 的範例 device /dev/video0 #使用第一個webcam loop 15 #每隔15張執行一次擷取 skip 10 #忽略前面10張不要使用 Invert #儲存的影像像素反轉 (變成負片) background #使用背景執行 resolution 1920x1080 #擷取的解析度設定為1920x1080 (需要查詢 webcam 可以支援的解析度) set brightness=50% #亮度調整為50% set contrast=30% #對比度30% top-banner #將文字標題列放置在頂端 (共有no-banner, top-banner, bottom-banner等設定) font /usr/share/fonts/truetype/msttcorefonts/arial.ttf:64 #使用的字型:字型大小 (font:size) title “AIOT-Demo“ #標題內容 timestamp “%d-%m-%Y %H:%M:%S (%Z)“ #時間格式 %d:日期, %m:月份, %Y:年, %H:小時, %M: 分, %S: 秒, %Z: 時區 jpeg 95 #jpeg壓縮率 (另外有png 可以選擇) greyscale #儲存灰階檔案,將彩色轉換成灰階 save /video/avi/%H-%M-%S-viewcam.jpg #儲存的檔案路徑與檔案名稱,%H-%M-%S-viewcam.jpg是檔案名稱 使用 python 執行 fswebcam 透過 python 呼叫外部指令的做法,可以簡單的透過 fswebcam 每隔一個時間區段,透過攝影機拍照取得影像,fswebcam 執行方式與前面介紹的方式相同。範例程式如下: 知識點回顧 video4Linux 對於使用者使用各種媒體設備,提供非常方便的開始與使用的介面,當電腦插上 webcam 以後,可以觀察 /dev/video* 的變化。 透過 lsusb 的指令可以很容易的觀察支援 UVC 的周邊裝置,使用 lsusb -v | grep “14 Video”,查看影像相關的設備。 fswebcam 提供清楚簡易的操作命列格式,透過 fswebcam 可以將擷取的影像透過命令參數執行灰階、縮放、調整亮度、對比度、負片、時間戳記影像格式、設定影樣標題文字與時間等功能。 透過 python 外部命令執行 fswebcam,可簡易的擷取 webcam 的影像後續再透過 python 程式處理。 作業 請參閱作業範例 : 作業1 : 執行 lsusb -v 指令,觀察系統顯示的 usb 裝置,透過 grep “14 Video” 指令篩選顯示的結果,了解 webcam 裝置在系統層次支援的狀態。 作業2 : 安裝 fswebcam,執行 fswebcam 拍一張照片,確定 webcam 動作正常,並且透過更改參數與設定參數檔案的方式,執行fswebcam,確定可以產生隨時間依序儲存的檔案。 作業3 :透過 python 呼叫 fswebcam,觀察 python 呼叫 fswebcam 執行外部參數的方式,並且練習更改 fswebcam 的參數檔案,不更動 python 程式碼的方式,儲存各種類型的拍照結果。 參考資料 Linux 下 Camera 程式設計 – V4L2 linux UVC 驅動是為了全面的支援 UVC 裝置。它包括 V4L2 核心驅動程式和使用者空間工具補丁。這個視訊裝置或者 USB 視訊類的 USB 裝置類的定義定義了在 USB 上的視訊流的功能。UVC 型別使得只需要一個通用的驅動支援就能夠正常工作,就像 USB 大容量儲存裝置一樣。 UVC 的 linux kernel 驅動程式和支援的硬體裝置相關的描述在這裡:http://www.ideasonboard.org/uvc/。 fsphil / fswebcam fswebcam - Small and simple webcam software for *nix. fswebcam 是一個簡潔明了的網絡攝像頭應用程序。它從兼容 V4L1 / V4L2 的設備或文件中擷取影像,對其進行平均以減少噪聲,並使用 GD 圖形庫繪製標題,該庫還可以將圖像壓縮為 PNG 或JPEG。生成的圖像將保存到文件或發送到標準輸出入裝置(stdio),之後可以透過管線將其傳輸到 ncftp 或 scp 之類的程式,進行後續的處理。
-
04 - YOLO 介紹
知識地圖 – YOLO 介紹 YOLO 簡介 YOLO,全名 You only look once。是一種物件偵測的演算法, 並且在所有物件偵測的方法中,YOLO 也可以說是最為突出的方法之一 YOLO 的發展目標,並不是以物件偵測的準確率為優先,他把重點放在了運算速度上,並且需要消耗的運算資源也隨之下降。 本節將介紹 YOLO,以及它的效果、成績以及技術原理。 重要知識點 理解物件偵測的兩種常見手法 (two-stage,one-stage) 知道 YOLO 的歷史與成績 能夠說明 YOLO 的核心技術原理 什麼是物件偵測? 通常物件偵測會是像這樣的 上面提到的方法稱為 two-stage 的物件偵測方法 所以當然也有 one-stage 的物件偵測方法,其中最具代表性的就是 YOLO YOLO 的效果與成績 YOLO 的發展時間史: YOLOV1,2016年5月 YOLOV2,2016年12月 YOLOV3,2018年4月 在 YOLOV3 的版本中,可以達到最高 33.0 的 mAP 以及最短 22ms 的 Inference time。 這代表了在 2018 年中流以上的準確率,和名列前茅的推論速度。 YOLO 的核心技術原理 YOLO 在給定圖片後,會先切成 SxS 個小方格。接下來會平行的做兩件事: 對每個方格產生 k 個定界框,並計算裡面包含物件的可信度。 對每個方格進行影像分類,計算方格屬於不同類別的可能機率。 知識點回顧 物件偵測包含 two-stage 和 one-stage 兩種方法。 Two-stage 的方法中,首先要對物件的定位,然後對已定位的物件做分類。 YOLO 最早發表於 2016 年,並在 2018 年有當時相當不錯的準確率和幾乎最高的推論速度。 YOLO 在切割 Grid 以後,會平行的進行定位和分類兩個任務。 YOLO 的定位是在每個 Grid 中,隨機產生定界框並計算可信度,當可信度超越定值(Valve),該定界框成立。 YOLO 的分類是直接對每個 Grid 做影像分類,不需要先定位。 參考資料 Object Detection Part 4:Fast Detection Models 本文主要是在描述各種快速的 Object detection,除了 YOLO 外也包括 SSD、RetinaNet 等等 one-stage 的物件偵測模型。 這些模型都跳過了候選區域的階段,直接在影像上進行物件偵測。
-
05 - Raspberry PI 執行 YOLO
知識地圖 – YOLO 介紹 重要知識點 執行 Yolo 需要準備的執行環境 安裝 Yolo 執行環境 熟悉 Yolo 運作流程 在 Raspberry PI 上執行 Yolo 標準版 Yolov3 Yolov3-tiny 在 Raspberry PI 執行 Yolo 在 Raspberry PI 安裝 Yolo 下載訓練完成的 Yolo 模型權重和參數檔 參數檔案要包含模型設定檔、分類名稱 開始執行 Yolo 模型進行推論 在 Raspberry PI 安裝 Yolo 在 google 查詢 yolov4 github 安裝 yolov4 的這個版本後續系統相容性比較好 Alexey Github Alexey 的 github,點 darknet 進入連結 準備下載 darknet,用 git clone 下載 在 Raspberry PI 安裝 Yolo 在 Raspberry PI 上執行下面的指令,下載 darknet。 git clone https://github.com/AlexeyAB/darknet 編譯 darknet,執行 make 指令編譯 make 完成後,執行 ./darknet 確認編譯成功 準備在 raspberry 上執行 yolo 的範例 透過 Joseph Redmon 的 darknet 官方網站來練習執行 yolo,文件相對的比較直覺簡單。用 yolov3 darknet 來搜尋 google YOLO: Real-Time Object Detection 接下來會依照 Joseph Redmon 的 darknet 官方網站來練習執行 yolo。 執行 yolo 需要準備下列幾個檔案 yolov3.weights可以用底下的指令下載 wget https://pjreddie.com/media/files/yolov3.weights yolov3.cfg檔案在darknet/cfg的子目錄中。 coco.data 檔案在darknet/cfg的子目錄中。 coco.names檔案在darknet/data子目錄中。 最基本 yolo 範例,Darknet 預測基本指令形式 執行結果輸出至 predictions.png cfg/coco.data 的內容,來觀察看看 如果想要改類別的名稱,例如變成中文 類別名稱不能用中文,程式碼會執行錯誤要改 試試看進一步的執行參數 _dont_show –ext_output 把 OpenCV 安裝起來,後續要使用 OpenCV 接下來會依照 Joseph Redmon 的 darknet 官方網站來練習執行 yolo。 OpenCV 4.5.2 Sources 下載 把 opencv-4.5.2.zip 複製到 Raspberry PI 的 /opt 解壓縮 OpenCV 完成後,進入 OpenCV 子目錄 在 build 目錄執行 make –j4 指令,等待編譯完成 編譯完成 OpenCV,在 build 子目錄下 make install 辛苦編譯完成 OpenCV,要在 build 子目錄下執行 make install,才能將編譯完成 OpenCV 函式庫安裝至系統內,供後續呼叫使用。 有了 OpenCV 函示庫之後,可以重新編譯 darknet,這樣 darknet 就可以支援 OpenCV 並且執行 webcam 的功能。 編譯完成 100%,執行 make install 安裝 OpenCV 最後終於完成 OpenCV 的安裝 設定 Darknet 的 Makefile,重新編譯使用 OpenCV 有 OpenCV 編譯的 yolo 執行結果 Darknet 用 webcam 當資料來源進行推論 Raspberry PI 執行 darknet 用 webcam 當資料來源時,沒有其他的推論硬體加速會很慢。 Raspberry PI 此時可以用 yolo-tiny 來執行輕量級的 darknet 推論模式,比較有機會執行後續的範例。 有 OpenCV 函式庫了,可以用 OpenCV DNN 的功能來執行 yolo 模型的推論。 Darknet 用 yolo-tiny 推論 yolov3-tiny.weights 可以用底下的指令下載 wget https://pjreddie.com/media/files/yolov3-tiny.weights yolov3-tiny.cfg 檔案在 darknet/cfg 的子目錄中。 coco.data 檔案在 darknet/cfg 的子目錄中。 coco.names 檔案在 darknet/data 的子目錄中。 Darknet 執行 yolo-tiny 推論 yolov3-tiny 推論的結果 Darknet 執行 yolo-tiny 推論,使用 -ext_output yolo-tiny 用 -ext_output 預測的輸出結果 參考資料 YOLO and Tiny-YOLO object detection on the Raspberry Pi and Movidius NCS 基於樹梅派加上 intel 神經棒的架構進行 yolo 推論(我們的教學不需要用到神經棒)
-
06 - 使用 LabelImg 進行物件標注
知識地圖 – 使用 LabelImg 進行物件標注 LabelImg 下載與安裝 重要知識點 選擇正確的標註格式(YOLO) LabelImg 如何框選物件 參考影片連結 LabelImg 簡介 LabelImg 影像標註工具 LabelImg 是基於 Python 開發的,可以用多邊形標註影像的一個工具。這邊是他的 Github 連結(https://github.com/tzutalin/labelImg)。 那為什麼需要標註工具呢?這是因為我們即將要使用的 YOLO,是一個物件偵測模型,而物件偵測模型的學習有兩個目標: 物件在哪裡?是什麼? 而標註就是由人類去提供物件的座標,以及該物件的類別。為了更容易的實現這件事,我們就要學習標註工具的使用。 LabelImg 下載 解壓縮下載的 LabelImg 壓縮檔 執行 python labelImg.py 如果要執行 python labelImg.py ,系統顯示缺模組,需要安裝缺少的 python 模組。 安裝模組的指令是 pip3 install 模組名稱。 有部分的 python3 之前的版本可能會少 lxml 模組,那就要執行 pip3 install lxml 來安裝。 安裝缺少的模組(sip) 安裝缺少的模組(PyQt5) 都安裝好了還是會出現 libs.resources 的錯誤 資料來源:LabelImg的安裝出現No module named 'libs.resources'錯誤 確定 pyrcc5 程式可以執行 確定 pyrcc5 這個程式可以執行,libs.resources 檔案錯誤訊息,需要一個 resoures.py 在 libs 的子目錄裡面,可以用 pyrcc5 把 resources.qrc 資源配置的檔案轉換成 resources.py。 labelImg 成功執行,可以準備開始標注資料 使用 LabelImg 標注之前的注意事項 依據準備要標示的物件類別,需要預先設定好 predefined_classes.txt 檔案。 (這個步驟一定要在標注之前準備好) predefined_classes.txt 在 labelImg 的 data 子目錄。 目前只標注橘子一個類別,predefined_classes.txt 只有 orange 一行。 predefined_classes.txt 的位置以及內容 改好 predefined_classes.txt 重新啟動 LabelImg 更改 predefined_classes.txt 之後,需要先關閉 labelImg,重新執行 python labelImg.py, 系統會載入新的 predefined_classes.txt 標註前的設定 選擇標註輸出格式為 YOLO 選擇 View 的 Auto Save Mode 用 Open Dir 指定要標示圖片的資料夾 先設定輸出格式為 YOLO、Auto Save 最後設定要標注影像資料的資料夾 收集圖片 用手機拍照進行照片收集 我們要偵測的物件是橘子,用手機拍一些手邊的橘子照片。 也可以到網路上尋找更多的橘子圖片作為我們的補充資料,資料越多效果通常會更好(準確率提升和抗雜訊能力提升)。 用 Google 圖片資料找橘子 用 LabelIMG 標註橘子 - 標註前的設定 設定 Change Save Dir 指向橘子圖片資料夾。 Change Save Dir 會設定標註檔被儲存的位置,可以將標注路徑設定成和橘子圖片同樣的資料。 目的在設定標註檔儲存的位置,讓影像和標註檔放在同一個位置,避免日後找不到圖片跟標注檔案的對應。 LabelIMG 狀態說明 LabelImg 對指定資料夾內影像進行標註 Edit 頁籤選取 Create RectBox,或是按下介面中 Create RectBox 按鈕 2. 選取橘子 3. 選擇 orange 這個剛才在 predefined_classes.txt 設定的類別 按下 Save 後,就完成一個物件的 Label 囉! 標註完所有物件的樣子 用 RectBox 把所有物件框選,並指定類別。 每完成一張圖片的標註,都要存一次檔。 最後把 classes.txt 刪除 完成標註後... 完成標註後,依據被標註圖片的檔名,會產生與其對應的 TXT 檔(FOR YOLO,如果你看到 xml 表示你選到 pascal voc 了,需要轉檔不然 YOLO 無法使用),標註檔裡面描述了物件的位置和各物件的類別。 標註圖片與標註檔 標註檔的內容,最前面的數字表示類別,後面則代表定界框的座標 壓縮標註資料 使用壓縮工具將 images 資料夾壓縮成 images.zip 知識點回顧 LabelImg 的路徑必須是全英文。 標註格式選擇 YOLO。 善用快捷鍵來加速 (W 可以拉框、Ctrl+S 可以存檔) 每完成一張圖片的標註,都要存檔一次。
-
07 - 使用 YOLO 進行標注資料模型訓練
知識地圖 – 使用 YOLO 進行標注資料集模型訓練 在樹梅派上進行橘子的 yolov3-tiny 推論的步驟 取得我們訓練完成的橘子 tiny-Yolo 模型權重和參數檔 在樹梅派上建置 Yolo 環境 環境是 Yolo 和 tiny-yolo 通用的 3. 讓參數檔就定位 4. 在樹梅派上使用 tiny-yoloV3 模型進行推論 檢查原始檔案的名稱與數量 以橘子標注為例,在標注前將蒐集好的圖片放在某個子目錄。 例如圖片全部放在 /opt/orange_capture 準備把資料整理複製到 /opt/orange_data 把原始的檔案編號,方便之後標注 準備來標注整理好的檔案名稱圖片 把圖片依序地都標註完,記得要按下 Save 儲存 訓練之前一定要檢查一下影像與標注檔案數量 如何開始訓練 YOLO,要做哪些檔案設定 標注檢查好,準備 yolo 要訓練的設定檔案 設定檔案的範例,包含類別與環境設定 yolo.cfg 中 [net] 的參數意義 設定 yolo.cfg,設定錯無法訓練 不同的網路架構以及類別數量,決定了要如何調整成對的 yolo.cfg 設定值。 調整的概念如下,因為在 region 前最後一個卷積層的 filters 數是特定的,計算公式為 filter=num*(classes+5) 。 yolov3 沒有 [region] 了,改成 [yolo],所以在 [yolo] 之前的最後一個卷積層filter=num*(classes+5),而 yolov3 的 masks 是 3,因此 num 的值是 3。 filters 與 classes 在 [yolo] 之前的設定方法 filters = (classes + 5) * 3 = (classes + width + height + x + y + confidence) * num = (classes + 1+1+1+1+1) * num = (classes + 5) * num YOLOv3 dectects 3 boxes per grid cell, so it is filters = (classes + 5) * 3 In YoloV3 you have to change each filters= in 3 convolutional layers before [yolo] layer and classes in [yolo] layer Formula is filters = (classes+5)*3 in yoloV3 (3 masks only) 如何設定 [yolo] 之前 filters 的說明 最後檢查所有的條件是否正確 要執行訓練之前,一定要再檢查一次訓練模型輸出的子目錄是否存在,有沒有打錯字,不然訓練的結果會因為沒有辦法寫入,到某一代的結果之後,訓練就會因為錯誤暫停。 train.txt 路徑所指到的所有的 .jpg 或 .png 的影像檔案是不是都存在,不然一樣會因為找不到檔案錯誤。 train.txt 找到 .jpg 或 .png 圖檔後,要確定所有的跟 .jpg 或 .png 圖檔相同的 .txt 標注檔案是不是都存在,否則一樣錯誤。 valid.txt 路徑所指到的所有的 .jpg 或 .png 的影像檔案是不是都存在,不然一樣會因為找不到檔案錯誤。 valid.txt 找到 .jpg 或 .png 圖檔後,要確定所有的跟 .jpg 或 .png 圖檔相同的 .txt 標注檔案是不是都存在,否則一樣錯誤。 全部都檢查過了,可以開始執行訓練了。 使用 Darknet 執行訓練 一代在 Raspberry PI 上訓練要 918 秒 在 Google Colab 上只用 CPU,一代要 156 秒 在 Google Colab 上使用 GPU,一代不到 1 秒 在 Google Colab 上使用 GPU,4000 代時已到 98% 每一代的訓練時間其實不太一樣 Raspberry PI:前面 10 代都是 900 秒以上。 Google Colab CPU: 1-10 代:平均約在 155 秒 11-20 代:平均約在 55 秒 21-30 代:平均約在 136 秒 Google Colab GPU: 每 1000 代:平均約 7 分鐘,約 420 秒。 在樹梅派上使用 YoloV3 模型進行推論 用下面的指令移動到 Yolov3 的環境,並執行推論
-
08 - 使用 OpenCV 載入自己訓練的模型
知識地圖 – 使用 LabelImg 進行物件標注 用 python 寫一個推論程式 撰寫 opencv_pic.py。 載入已經訓練好的 YOLO 模型。 設定模型路徑與設定檔案。 設定類別名稱檔案。 讀取辨識的影像。 依序按照框格大小移動,由模型預測 各類別的機率值。 大於門檻值區域繪製辨識結果 3. 範例程式碼下載連結。 用 OpenCV 的程式架構執行 開始執行 OpenCV 預測 把前面的程式碼儲存成 opencv_pic.py。 程式可以使用下面的指令執行。 a) python3 opencv_pic_yolo.py "圖片路徑" b) 如Python3 opencv_pic_yolo.py image.jpg Yolov3 的權重和參數檔的路徑寫在程式碼的第 9 行,可以依據自己的檔案路徑更改模型,就可以每次換成用不同的模型預測跟分類同一張圖片,可自行練習將這幾個參數換成用外部參數傳入。 推論結果 門檻值設定為 0.1 門檻值設定為 0.45 可以自己多試幾次不同的門檻值,觀察輸出結果 推論結果,程式如果有執行失敗
-
09 - 口罩模型辨識實作
專題實作 - 口罩辨識 - 流程 步驟1:蒐集訓練集資料。 步驟2-3:練習在 Google Colab 上執行 yolo 訓練模型。 步驟4:在 pi 使用 yolo 官方套件測試訓練模型 步驟5:在 pi 執行 OpenCV DNN 呼叫 yolo 模型 專題實作 - 口罩辨識 步驟1:蒐集足夠的 tagging 資料集,口罩辨識資料集,透過網路搜尋,發現有一些可以嘗試練習的資料集,下載資料集之後,進行資料的整理,確定可以做為資料訓練集使用。 步驟2:將資料集進行分類,挑選足夠代表的資料集數量,準備使用 Yolov3 進行訓練,使用程式工具產生 yolov3 訓練集與測試集使用的資料格式。 步驟3:設定 yolov3 訓練時所需要更改的各種設定檔案,準備環境參數與訓練資料路徑,啟動 yolov3 開始進行訓練。 步驟4:將 Yolov3 訓練完成的模型,透過 python 程式載入模型,將範例的影片檔案載入進行辨識,輸出每個畫面中辨識到的物件位置、機率數值。 步驟5:透過 OpenCV DNN 方式即時辨識是否戴口罩,進行前端即時口罩辨識。 步驟 1 蒐集足夠的 tagging 資料集,口罩辨識資料集,透過網路搜尋,發現有一些可以嘗試練習的資料集,下載資料集之後,進行資料的整理,確定可以做為資料訓練集使用。 解答: 搜尋口罩標註資料,可以發現有一些已經準備好的資料集,透過這些過去已經整理好的口罩標注資料集,減少訓練集與測試集資料的準備時間。 網址:https://www.kaggle.com/datasets?search=mask 步驟 1 - 解答 需要訓練一個模型來偵測使用者是否有戴口罩,Dataset 可以從 mouth_mask.7z下載,這是由伊甸基金會所屬的數位資料處理庇護工場所標記,免費開源釋出。 標記格式:PASCAL VOC 圖片總張數:682 張 標記種類三種: good(有正確的戴好口罩) none(臉部露出鼻孔沒有戴好口罩) bad(臉部沒有戴上口罩) 各類別的標記數目: good(有正確的戴好口罩):3,129 個 none(臉部露出鼻孔沒有戴好口罩):126 個 bad(臉部沒有戴上口罩):667 個 使用這個資料庫練習訓練出一個偵測臉部是有戴(好)口罩的模型。 步驟 2 將資料集進行分類,挑選足夠代表的資料集數量,準備使用 yolov3 進行訓練,使用程式工具產生 yolov3 訓練集與測試集使用的資料格式。 解答: 在進行訓練集挑選之前,主要要確定資料的合理性,例如框選的資料範圍,在資料夾中是否確實存在標注的檔案名稱,這些部份需要先加以確定。 步驟2 - 解答 本次練習我們拿這個資料集 100 張圖例作為訓練集。 將每個檔案另外編碼,要注意的規則是影像檔案名稱,其標註檔案即為 txt 副檔名。 準備好資料後,我們可以準備訓練集與測試集列表檔案。 以下是 A001.jpg 的圖像,右邊為標註的資料內容,透過 lableImg 軟體標註的結果。 可以看到影像中有三類的資料類型,分別為 good、bad、none 三個類型,要注意的是編號分別為 0,1,2,類別編號跟標註記得要對應,在後續預測的時候,進行預測的範圍框選時,系統會自動依據框選的物件預測類型,標上類別的名稱。 資料分類名稱的內容順序,就依照資料類型的編號,在此專題中將檔案命名為 obj.names,檔案的內容如下。 將訓練集的資料檔案名稱,編輯成一個列表,這個列表之間可以沒有順序的關聯。 我們打算直接把全部的資料都拿來訓練,所以 train.txt 裡面有 100 個要訓練的影像的檔案名稱。 測試集我們也使用這 100 個檔案,所以很簡單的 train.txt 與 test.txt 可以用同一個檔案內容。 步驟 3 設定 yolov3 訓練時所需要更改的各種設定檔案,準備環境參數與訓練資料路徑,啟動 yolov3 開始進行訓練。 解答: 這個步驟主要能進行 yolov3 分類器的設定,針對訓練集與測試集,設定相對的 yolov3 各種參數設定檔案,同學只要學會使用多分類方式的參數設定,之後就會具備自己設定不同種類類別數量,以及如何準備自己的訓練與測試資料的能力。 步驟 3 - 解答 在這裡說明使用 google colab 進行 yolov3 安裝編譯的方式,因為 google colab 對於 GPU 的支援已經非常成熟,使用 google colab 安裝 yolov3,直接設定 Makefile 內部相關的編譯參數,即可很方便的將支援。 首先我們會啟動一個 colab 環境,然後測試 python3 的 cv2 模組是否已經存在運作的環境中,並且顯示一下 cv2 模組的版本。 import cv2 cv2.__version__ 然後可以用 colab 連接自己的 google Drive,後面的 yolo 訓練步驟會需要事先已經準備好的設定檔案與資料集。 我們會先放置在 google 雲端硬碟的某一個子目錄,因為 google Drive 在 colab 中連接成功時,路徑名稱會是 /content/drive/MyDrive,我們需要點左邊的檔案夾符號進行 google Drive 的連接。 這個步驟最主要的就是安裝 yolo,以及搭配對應的訓練與測試資料集,設定 yolo 參數設定檔,即可進行模型訓練。 搜尋 google,關鍵字為 yolov4 alexeyab。 git clone https://github.com/AlexeyAB/darknet.git 然後切換目錄到 /content/drive/MyDrive/darknet 裡面 在編譯時可能會出現沒有 cmake 套件,因為編譯 darknet 會需要,所以先安裝。 現在可以編譯 darknet 了,使用 make 指令即可編譯。 編譯完成後,我們可以準備開始進行訓練了,在此之前做最後的確認,darknet 能夠正常的啟動執行。 在經驗上在單機與 google colab 上進行 yolo 訓練時,刻意的把單機子目錄也設定成 /content/drive/MyDrive,然後把準備的設定檔跟訓練的資料集都擺在 /content/drive/MyDrive/darknet_train 之下,後續的動作會看起來 google colab 與單機的執行方式完全相同。 接下來我們準備開始進行訓練,yolo 訓練需要準備 4 個設定檔案,分別為(這四個檔案很重要,沒有就不能訓練) 1. yolo 設定檔案 2. 各種類別標號的名稱檔案 3. 訓練集資料檔案列表 4. 測試集資料檔案列表 要訓練 Yolo,以下 4 個檔案資料一定要準備好 Yolo 資料設定檔案,告訴 yolo 各個訓練要用的檔案位置 a. 設定 類別資料數量 b. 設定 訓練集資料檔案列表之路徑 c. 設定 測試集資料檔案列表之路徑 d. 設定 訓練模型輸出的磁碟之目錄 類別檔案 - 依照類別編號順序,列出各類別編號對應名稱 訓練集資料檔案列表 - 訓練集資料的類別編號與檔案名稱 測試集資料檔案列表 - 測試集資料的類別編號與檔案名稱 最後是依照類別的數量,修改 yolo.cfg 或是 yolo-tiny.cfg 開始進行口罩的資料訓練,先來設定 yolo 的環境檔案。 2. 然後準備口罩訓練集的資料檔案列表。 3. 開始準備口罩測試資料集,設定測試集資料的檔案名稱列表。 4. 然後設定口罩類別編號對應的名稱。 5. 最後是確定測試集資料檔案列表,以及訓練集資料檔案列表的檔案名稱,裡面的每個圖像檔案,都各自有一個標註檔案,副檔案名稱都要是 .txt。 6. 建立訓練模型輸出的路徑 (要對應 obj.data 設定檔案模型輸出) mkdir /content/drive/MyDrive/mask_50/tiny_weights/ 7. 最後要設定 yolov3-tiny.cfg 複製並修改 yolov3-tiny.cfg 如下: Line 3: set batch=24 → 每一次訓練使用 24 張影像 Line 4: set subdivisions=8 → 24 張影像分成 8 次訓練 Line 127: set filters=(classes + 5)*3 → 有 3 個類別,filters=(3+5)*3=24 Line 135: set classes=3 → 辨識共有 3 個類別 Line 171: set filters=(classes + 5)*3 → 有 3 個類別,filters=(3+5)*3=24 Line 177: set classes=3 → 辨識共有 3 個類別 經過上面的 7 個步驟以後,我們可以準備訓練 yolo 了。 參考資料:https://blog.csdn.net/phinoo/article/details/83022101 yolov3-tiny.cfg 檔案設定的地方會長這樣 yolov3-tiny.cfg 的171,177 行會依照資料分類數量設定。 可以進行辨識了,最近要進行辨識前,要準備一個預訓練的 weights,這個檔案可以在https://pjreddie.com/media/files/yolov3-tiny.weights 下載。 將 yolov3-tiny.weights 放在 tiny_weights 的子目錄裡面,這樣就可以開始訓練了,執行以下的命令。可以把訓練的過程輸出到某一個檔案裏面,在這裡將訓練過程輸出到 /content/drive/MyDrive/mask_50/tiny_weights/mask_50_tiny_2020_12_08.logs 檔案中。 !./darknet detector train \ /content/drive/MyDrive/mask_50/cfg/obj.data \ /content/drive/MyDrive/mask_50/cfg/yolov3-tiny.cfg \ /content/drive/MyDrive/mask_50/tiny_weights/yolov3-tiny.weights \ -dont_show -clear 2>&1 |tee -a \ /content/drive/MyDrive/mask_50/tiny_weights/mask_50_tiny_2020_12_08.logs 訓練的過程應該會看到啟動 GPU 以及相關的流程,並且開始各代訓練過程。 如果訓練到某個程度會被系統暫停,這時候可以把訓練輸出某代的模型檔案作為 weights 檔案,放在 darknet 的權重參數,並且將 -clear 的參數不要設定,就可以繼續的往後面的代數訓練了。 步驟 4 將 Yolov3 訓練完成的模型,透過 python 程式載入模型,將範例的影片檔案載入進行辨識,輸出每個畫面中辨識到的物件位置、機率數值。 解答: 此步驟的基礎知識是能夠將訓練好的模型下載回 pi 上面進行預測,此部分最重要的知識是如何把訓練好的模型透過 python 的環境來運作。 透過這樣的過程,之後各種自己訓練好的模型,就能夠自己發展不同情境應用的開發環境,此步驟主要透過 darknet 提供的 python 呼叫環境,因此我們只要學會如何啟動模型進行預測,將預測結果取出作為後續應用。 步驟 4 - 解答 將 yolov4 安裝在 pi 上面。 步驟 4 - 解答 要讓 python 能夠使用 yolov4 的函示庫,要把 Makefile 裡面的 LIBSO=0,變成 LIBSO=1,然後開始編譯。 同時因為 webcam 會用到 OPENCV,所以編譯時候,啟動 OPECV=1,另外需要先安裝 OPENCV 至 PI 的環境中。 執行 apt install python-opencv 安裝。 執行 pip3 install opencv-python 安裝 然後開始編譯 darknet。(需要一小段時間) 編譯完成後,驗證 python3 可以執行 darknet 的函示庫。 透過 darknet_image.py 或 darknet_video.py,把自己訓練好的模型透過這兩個 python 程式來執行。 先把 mask_50 的子目錄,放到 /opt 底下,然後把 /opt/mask_50/cfg/obj.data 內部的內容修改為 pi 上面的執行路徑環境,在 pi 執行時,路徑才會正常。 我們在 tiny_weights 底下準備了一個訓練了 88000 代的 weights 檔案。 在 /opt/darknet 之下,執行底下的指令,確定程式可以執行成功。 python3 darknet_images.py \ --weights /opt/mask_50/tiny_weights/yolov3-tiny_88000.weights \ --config_file /opt/mask_50/cfg/yolov3-tiny.cfg \ --data /opt/mask_50/cfg/obj.data \ --input /opt/mask_50/data/A001.jpg \ --ext_output --dont_show darknet_image.py 執行的方式與 darknet 執行程式相同,可以設定各種參數,例如影像檔案名稱、weights 預測模型、yolov3-tiny 網路參數、yolo 參數檔 obj.data 等。 執行會發現 darknet_image.py 不會產生預測的結果影像檔案,只會產生預測的區域的座標與類別。 如果你想要產生一個預測的影像結果,可以把在 darknet_image.py 最底下的程式碼,改成底下的形式,將 dont_show 沒有設定的時候,改以 cv2.imwrite 輸出影像的結果為 predictions.jpg。 步驟 5 透過 OpenCV DNN 方式即時辨識是否戴口罩,進行前端即時口罩辨識。 解答: 在這個步驟中透過 OpenCV DNN 匯入 yolo 模型,進行即時口罩辨識。 步驟 5 - 解答 本程式命名為 webcam_mask.py load_yolo(): 載入模型 start_webcam(): 啟動webcam攝影機 detect_objects(): 將影像輸入神經網路進行預測 get_box_dimensions() 將預測機率值超過設定的信賴值的區域取出來。 w:辨識區域的寬度 h:辨識區域的高度 X:辨識區域左上角橫座標 Y:辨識區域左上角直座標 [w,h,x,y] 加入 boxes 陣列 conf 加入 confs 陣列中 將 class_id 辨識種類加入 class_ids 的陣列中 透過 NMSBoxes 函數將目標檢測結果,消除重複多餘的框,結果儲存在 indexes 內。 將 boxes 裡面有的辨識區域畫出來,可以依此觀察辨識區域的位置。 最後將辨識的區域左上角區域點(x,y)以及區域的寬高(w,h)傳送至 pi 本身的 flask 執行的 web server。 最後透過 webcam_detect() 函式,啟動攝影機,開始讀取影像、偵測物體、取得物件預測結果的區域、將預測類別標籤畫在影像上,進入無窮迴圈的狀態,直到程式執行結束為止。 執行 python3 webcam_mask.py 前面 python3 webcam_mask.py,啟動了 webcam,載入了口罩辨識模型。 會看到不斷的辨識出有戴口罩或者是沒有口罩的狀態,並且會將辨識出來的結果剪下影像儲存至 pi 的 sdcard 上面。 在這個範例中,將 webcam_mask.py 與 mask_flask.py 都放在 /opt/webcam_mask 子目錄底下,因此會看到 /opt/webcam_mask 子目錄底下會出現辨識到的人臉結果影像。 可以抓取依照檔案名稱的影像。底下可以看到口罩辨識系統依序拍下的檔案名稱。 專題實作 - 完成 恭喜你完成了。 相信經過這個過程,應該學會了各個系統獨立測試的流程。 每個部分其實都可以當成一個獨立的部分驗證,然後再把這些部分組合起來。
-