骯髒碗盤偵測器

九月 12, 2015
Facebook
Twitter

乾淨的水槽令人心曠神怡!結合網路攝影機和即時電腦視覺軟體,在水槽有碗盤堆積時發出通知。

家中是否常有人不洗碗,使得流理臺的水槽堆滿碗盤呢?你家裡或是自造者空間的廚房整潔是否需要加強控管呢?為了讓家裡、辦公室或工作室全面自動化,你首先要做的事情,就是利用視覺系統偵測動向和物品,而且只要一臺支援OpenCV視覺軟體的電腦即可。
「骯髒碗盤偵測器」結合價格合理的BeagleBone Black單板電腦和羅技網路攝影機——再加上許多開放程式碼軟體——只要水槽裡一有碗盤,就會發出通知。關鍵在於免費電腦視覺軟體OpenCV的應用,可以協助辨識像是水槽或碗的形狀,並且能偵測其變化。
這項專題的步驟大致如下:

  • 從BeagleBone Black的MicroSD記憶卡更新韌體至最新的Debian作業系統,包括OpenCV和Python程式庫。
  • 接著設定組態,使其能自動連上你的無線網路。
  • 你可以使用普通的接線盒,不過我們3D列印了一組創源(Logic Supply)的BeagleBone Black專用外殼,可以裝上USB集線器(只要稍微挖個洞)並接上網路攝影機。

提醒:如欲進行此專題,必需對指令介面有一定熟悉度,並且知道如何管理區域網路。若有寫程式(無論是Python、PHP,甚至是HTML)的經驗,會很有幫助。專題頁面上詳列了所有的程式碼供參考,不過你可以依自己的喜好作調整。

  •  將偵測器裝設於水槽上方。
  • BeagleBone將自動連上你的無線網路。透過Cloud9 IDE介面連接偵測器,並使用我們所提供的現成Python指令稿,進行編程作業。
  • 擷取乾淨和髒亂的水槽圖像。

提醒:精準的偵測系統需要充足的光線,利用廚房裡所有的燈光來測試,尋找最佳光線。

這項專題需要對命令列工具有一定的熟悉度,加上能夠管理自己的區域網路。對電腦程式瞭若指掌(Python、PHP或HTML),有助於深入這項專題。下面羅列了所有必要的程式碼,但仍可能視個人需求改寫那些程式碼。
專題程式碼的順序非常重要。在水槽裡擺一些杯碗瓢盆,然後用腳本程式碼「試拍」照片,當作校準空水槽的影像。以後OpenCV處理影像時,就有標準影像可供參考,方便發現骯髒的杯盤。
在系統中建立參照基準——也就是乾淨的水槽——後,就可以設定程式,使系統每偵測到水槽變髒時,便會寄發電子郵件和/或多媒體簡訊通知。實際上,如此設定後,無論水槽變髒或變乾淨,只要狀態上有變化的時候都會收到通知。因此,骯髒碗盤偵測器的主要功能就是偵測,並且把偵測結果通知你。最後回到指令介面,寫入crontab指令,使系統每5分鐘便會自動拍攝一張照片。網路攝影機的LED狀態顯示燈會在每次執行指令時亮起,如下圖所示:

鏡頭的角度和水槽
在離水槽適當的距離安裝骯髒碗盤偵測器,能拍攝到大部分的水槽為佳。廚房的櫃子規格都差不多,像我就發現家裡的櫥櫃內側,能夠帶給攝影機絕佳的視野。鏡頭距離水槽23 1/2″,我大約可以拍到16″x12″的水槽範圍。安裝偵測器之前,不妨先測試攝影機的鏡頭,確認到底可以拍到什麼。

3D列印保護殼
你看著下列步驟,期待組裝屬於自己的骯臟碗盤偵測器,那也為BeagleBone Black列印保護殼吧。我用過Logic Supply的保護殼,在Github平臺就買得到,推薦你挑選自己喜歡的顏色,營造出不同的組裝設計,順便在下面留個言,因為我想看你的前衛設計!

整體視覺檢測
鏡頭拍得到水槽的影像,並不代表可以完全拍得到骯髒碗盤,光線和軟體本身都有影響。我測試偵測器的水槽時,有許多光線反射進來,所以偵測器從早晨到傍晚都運作順利,但之後就要碰運氣了,必須要有室內燈光才行,就算是在白天,陰天或烏雲密佈,都可能影響亮度和產生錯誤結果。你難免要隨著環境稍微調整軟體。在final Dirty-Dish-Detective.py 最終檔,尋找#match circles with drains註解以及tolerance 變數,有需要的話可以調整tolerance。數值低恐提高錯誤肯定的機率,但數值高則會拉大髒碗盤的定義。

無線網路
製作這項專題時,以BeagleBone Black架設無線網路並不容易,也是整個專題最耗時間的部分。我的無線轉接器至今仍然差強人意,每開機三次只有一次,能夠成功啟動和連接無線網路,我也不知道原因。3.6A電源轉換器電力很足,我測試過幾款Netgear的轉換器,最後選擇G54作為低功耗的轉換器套裝。
祕訣:無線轉接器不要直接插入BeagleBone Black的USB插座,就算在製作原型也不要這麼做。這可能跟電路板的訊號互相衝突。切記隨時都要用USB集線器。

網路瀏覽器
任何會用到網路瀏覽器的專題,都需要用不同瀏覽器測試。這項專題測試過Chrome和Safari(Windows和Mac系統分別都試過),其餘網路瀏覽器(尤其是IE)並不適用。

程式碼(複製+貼上)

在下列步驟中,每當看到程式碼就必須複製到Cloud9 IDE,我個人使用程式碼剪貼簿嵌入必要程式碼,建議以右鍵選取右下方「view raw」,接著選取「Open link in new tab」,就會出現未格式化的文字檔,複製到Cloud9 IDE自製Python檔案。
我很感謝傑森‧克里德納(Jason Kridner)提供大量程式碼,還要感謝London Hackerspace的湯姆幾年前就分享的解決方案
材料

  • BeagleBone Black入門套件組:Maker Shed網站商品編號#MSGSBBK2。
  • 網路攝影機,寬螢幕視訊:例如羅技公司的C270。
  • MicroSD記憶卡
  • USB AC配接器,5V/3.6A
  • M型AC接頭
  • USB集線器,4埠
  • USB無線網卡,Netgear G54/N150

 
工具

  • 配有USB埠的電腦
  • 熱熔膠槍
  • 鉗子
  • 3D印表機(非必要)
  • 束線帶
  • 各種五金材料:用以架設偵測器。
步驟一:更新BeagleBone Black
你首先要做的是更新BeagleBone Black,必須是最新版的Debian。換言之,我們要更新BeagleBone Black的作業系統,我為OSXWindows使用者分別撰寫簡單的步驟,你只要按表操課就行了。更新後再回到這個步驟,繼續朝著骯髒碗盤偵測器邁進!
下列步驟以「2015-05-14」的影像為基礎,影像在 http://beagleboard.org/latest-images,若有更近期的影像就用那個,但還是要在BeagleBone Black安裝Debian。
步驟二:安裝無線網路
按照這個簡單的說明步驟,就可以將BeagleBone Black連接到無線網路了。
請注意:這裡使用Netgear G54/N150「微型」USB轉換器,其他無線轉換器應該也可以,若你試過其他款式,不妨在下面留言分享。

步驟三:列印骯髒碗盤偵測器的保護殼

為BeagleBone Black列印Logic Supply保護殼,可以挑選自己喜歡的顏色,或者跟櫥櫃速配的顏色。保護殼分成兩個部分:底部(主體)和頂部(蓋)。

步驟四:在保護殼的蓋子鑽洞

保護殼蓋子的一端有凹口,這是配合BeagleBone Black的乙太網路轉換器。把蓋子放在工作臺上,蓋子左上方的箭頭朝向左上方,從箭頭的角落開始,由左向右測量1 3/4″,由上向下測量1 1/16″(圖一),找到兩者的交會點做記號,參見圖三。
 
步驟五:在保護殼的蓋子鑽孔
以3/4″ 鏟型鑽頭小心鑽洞,把鑽頭中心對準你做的記號。鑽好洞以後,以鉗子移除洞裡的塑膠碎片。

步驟六:把USB集線器安裝到蓋子上

USB集線器的一側有突起物,插入你在保護蓋鑽的洞,記得從保護蓋頂部插入,這樣闔上保護蓋以後,集線器就會在頂部。突起物比洞口大一些,所以要用一些蠻力,但絕對可以卡進去(圖一)。
現在調整一下集線器,緊靠保護蓋的邊緣(圖二)。把集線器壓著不要動,把蓋子翻過來,以熱熔膠固定集線器(圖三)。我建議壓個幾分鐘,確保熱熔膠乾了,以免晃動。我們希望集線器靠著保護蓋的邊緣,因為後來還要安裝攝影機,剛好在保護殼和集線器的周圍,沒想到意外的搭!
 
步驟七:把攝影機安裝到保護殼上
图片

拆解C270攝影機,移除托座「頸部」的塑膠膜。把USB集線器插入BeagleBone Black的USB Type A插孔。把攝影機USB線插入集線器。如同圖一拿著保護殼,你會看到攝影機托座剛好符合保護殼和集線器加起來的厚度!這也就是集線器要靠邊的原因。
把攝影機固定好,如同圖二調整束線帶的位置,束線帶纏繞著保護殼,把攝影機固定在保護殼上(圖三)。接著就可以把骯髒碗盤偵測器安裝在水槽上方。
 
步驟八:把偵測器安裝在水槽上方
你可以自行決定怎麼安裝,這需要一些木工,取決於水槽上方有沒有櫥櫃,有幾個水槽要偵測,櫥櫃是什麼材質等。
我櫥櫃下方安裝幾個吊環,攝影機再以束線帶固定在吊環上(我的櫥櫃是複合材料),測量攝影機托座每一側的距離(圖一),把攝影機置於櫥櫃下方,做好準備鑽洞的記號。我從內側安裝三個吊環,使用了兩條小束線帶(橘色,參見圖三),再把保護殼的束線帶固定在吊環上,把攝影機電線的束線帶穿過吊環,藉此固定所有多餘的電線。攝影機鏡頭可以前後轉動,但托座固定在櫥櫃下方。
 
步驟九:利用Cloud9說「Hello World」!
好了,我們要開始在區域網路跟BeagleBone Black互動了,還有為電路板撰寫程式。
既然BeagleBone Black自動連接無線網路,綁定IP位址(我個人是192.168.1.108),打開網路瀏覽器,鍵入電路板的IP位址,接著按輸入。
連線成功後,上方會出現綠色的方格,顯示「電路板已連線,好極了!」網頁向下捲動,按下「Cloud9 IDE」的連結,在BeagleBone Black開啟Cloud 9。你可能很熟悉裡面很多工具:檔案瀏覽器、指令行介面和檔案編輯器等。
我們讓BeagleBone Black確認自身的存在,按「檔案」、「新檔案」開啟新檔,鍵入

#!/usr/bin/python

按輸入兩次,然後鍵入

print “Hello World!”;

​按「檔案」、「儲存為…」,檔名定為「helloworld.py」儲存在cloud9檔案夾,現在按「啟動」鍵,腳本就會在下方的顯示方格
出現,看到「Hello World!」的字樣,大成功!
 
步驟十:攝影機測試

按「檔案」、「新檔案」並建立子資料夾「Dish-Detector」(圖一),這兩個單字中間絕對要有破折號,因為待會的程式碼就有破折號。
按「檔案」、「新檔案」,在Dish-Detector資料夾開啓新檔camera-test.py,把下列程式碼複製到檔案中儲存起來:
https://gist.github.com/nicknormal/347c18d0b27d45e33f73
程式碼複製到camera-test.py以後,按下「啓動」鍵,腳本就會在下方格出現,你不時也會看到下列錯誤訊息:「VIDIOC_QUERYMENU: Invalid argument」,但不要管它(圖二),這不會影響骯髒碗盤偵測器的運作。
現在Dish-Detector資料夾有camera-test.jpg檔案,你會看到攝影機拍到的水槽照片,耶!
 
步驟十一:捕捉空水槽的影像,設定骯髒碗盤偵測器
注意:你必須做一些測試,以取得可靠的偵測結果。把下列程式碼複製到新檔案sink-empty.pyand 然後啟動:
https://gist.github.com/nicknormal/b46775673ee654f4a262.js

這個程式碼創造出一個JPG檔案「sink-empty.jpg」,以及一個文字檔「sink-empty.txt」(這就是「空」水槽的設定檔)。如果你有一個水槽,那個檔案會讀取

790,382,64

但如果你有兩個水槽,那個檔案會讀取

200,170,15 192,76,6

對照sink-empty.jpg,從XY座標觀察其方向。這個腳本不要刪除,以免需要重設空水槽的模樣,或者以備攝影機移動之需。

步驟十二:捕捉骯髒水槽的影像,對照空水槽的影像
做頓飯(我是泡杯咖啡!),把髒盤子放在水槽,先別急著洗!
把下列程式碼複製到新檔案,命名為sink-latest.py,然後按啟動:
https://gist.github.com/nicknormal/fc32f22c35f46c76044b.js
步驟十三:發送通知
利用Google信箱等SMTP提供者,就可以發給自己電子郵件或簡訊。把下列程式碼複製到新檔案sink-phone-home.py儲存起來:
https://gist.github.com/nicknormal/760a20ba8f05b6c00539.js
你會發現程式碼下方有變數,可鍵入Gmail信箱的使用者名稱和密碼,以及手機簡訊服務選項。若你輸入自己的Gmail資料,按啟動執行這個腳本,就會看到錯誤訊息SMTPAuthenticationError,因為你沒有把這個App連接到Gmail帳戶的安全許可。
這會直接導向 https://support.google.com/accounts/answer/185833,進而要求你輸入Google帳戶的密碼
拖曳下拉式選單,接著選擇「其他」(自定名稱),鍵入「Dish-Detector」,按下「產出」鍵(圖二),你就會取得該裝置的App密碼,讓SMTP認證以Gmail帳戶執行App「盤子偵測器」。
把App密碼移轉到上述程式碼的「密碼」變數,檔案命名為sink-phone-home.py ,儲存在Cloud9 IDE資料夾,接著按啟動。
 
步驟十四:成功!
你可以自己互相寄信,沒有主旨,但夾帶檔名為noname.jpg的水槽照片。
 
步驟十五:只有從乾淨變骯髒才會發送通知
接著稍微修改程式碼,唯有水槽從乾淨變得骯臟才會發送通知,這就要看Dish-Detector目錄的status.txt檔案,把下列程式碼複製到新檔案,並命名為sink-phone-home_change.py按啟動:
https://gist.github.com/nicknormal/d64cb459bdfe7a8824f4.js

步驟十六:終極程式碼

最後以註解作結,把下列程式碼複製到新檔案,命名為Dirty-Dish-Detective.py儲存起來。
 https://gist.github.com/nicknormal/2a02718590992cd5f7af.js
當你按啟動鍵,可能會回覆「圓形物品」的位置,也會發生「沒發現水槽」的錯誤。偵測器就知道水槽是骯髒(正確)或不骯臟(錯誤)。
一旦確認水槽的狀態改變,就會發出email通知,接著清空水槽的髒盤子,繼續完成系統自動化設定。
 
步驟十七:執行Cron並每隔五分鐘拍照一次
為了自動化骯髒碗盤偵測器的主要Python腳本,我們只需要一個簡單卻很冗長的指令列。啟動你偏好的SSH客戶端,或者直接使用Cloud9 IDE的操作環境,並連接BeagleBone Black。接下來的指令會啟動Cron,你把它想成工作排程器,專門啟動不斷重覆的任務(這個例子就是拍照並分析髒盤子的照片)。這些任務就稱為crontabs。
鍵入下列程式碼並按輸入:

echo “*/5 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 * * * python /var/lib/cloud9/Dish-Detector/Dirty-Dish-Detective.py” | crontab –

為了確認Cron正在運作,鍵入下列程式碼並按輸入:

crontab –l

你就會看到之前輸入的程式碼。
骯髒碗盤偵測器正在自動偵測水槽乾淨與否!
Crontab祕訣:Admin’s Choice會簡易拆解Crontabs的解譯,我建議把資料輸入這個Crontab產生器,有助於瞭解Crontab如何產生,每個部分各有什麼意義。

結論
先前介紹時就有提到,光線不足時偵測器就會失靈。假如有人半夜把髒碗盤堆在水槽,偵測器就無法發現,除非等到周圍環境變明亮。有一個辦法就是把人體紅外線感應器安裝在部分光源上。這光線不用太亮,但必須夠直接,其他工作就交給偵測器完成。這種干擾因素很好解決,只要結合其他專題加以應用即可。你還有其他骯髒碗盤偵測器的點子嗎?你的保護殼可能會有不同的設計,或者改用其他容器來融入廚房環境。我等不及聽到你的分享。
此外,骯髒碗盤偵測器也可能變成偵探。搞不好可以偷偷藏在暗處,稍微調整軟體就可以抓到圖謀不軌的人。如果你想到其他擴充軟體的點子,或者有趣的解決方案,麻煩讓我們知道。
我參考過下列部落格和網站,特別感謝他們的建議:Linux Wireless Wiki,WikiDevi有關WNA1000M無線轉換器的資料AskUbuntu論壇,Ayoub Zaki的嵌入式系統部落格BeagleBone NotesDLF。我還要特別感謝德瑞克‧莫洛伊(Derek Molloy),他有關BeagleBone Black的資料很豐富,雖然我沒有採用他的步驟,卻很感謝他提供完整的資料。
 
Jason Kridner
傑森‧克里德納是名德州儀器(Texas Instruments)的資深員工,也是非營利基金會BeagleBoard.org的共同創辦人,致力於推廣嵌入式電腦的設計和開放軟硬體的應用。
 
Nick Normal
尼克‧諾莫是名來自紐約皇后區的藝術家和自造達人,也是藏書狂。在流動工廠(Flux Factory)藝文空間曾有5年的駐村經驗,是紐約市World Maker Faire的共同主辦人,致立於推廣宅拉松(geekathon)的一切相關事物。
 
[原文]
譯:林冠妤、謝明珊
Social media & sharing icons powered by UltimatelySocial