<style>
.source{
color: gray;
font-size: 13px;
}
</style>
<p>文/台灣人工智慧學校AI工程師</p>
<p>這個專案結合了深度學習，edge AI 邊緣計算裝置，與機器手臂的控制</p>
<p>以下是爸爸的碎念…</p>


<blockquote><p>市面上的檯燈大多僅注重亮度，少數會多注意到光線柔和不反光。但如果家裡有小小學生就會知道，更多的狀況是小朋友根本沒開燈，或寫字區域根本不在燈的照射範圍內，另外更需要有人時時提醒小朋友的寫字坐姿，請他頭抬起來，腰挺直…</p></blockquote>

<p><img src="/wp-content/uploads/2020/07/1.png" alt="" width="700" height="450" class="alignnone size-full wp-image-13614" /></p>

<p>檯燈能不能更聰明，幫家長解決以上問題？</p>
<p>
<strong>產品主要功能</strong>
<ul>
	<li>是個檯燈</li>
	<li>追蹤小朋友的寫字區域</li>
	<li>提醒小朋友的坐姿</li>
</p>
<strong>產品結構分析</strong>
<p>檯燈本身的樣子就跟機器手臂有 87% 像，因此我用機器手臂來取代檯燈的支架，讓檯燈能夠藉由馬達控制來改變照射的區域與角度，另外也能縮短開發時間。</p>
<p>怎麼知道該照射哪個區域呢？這就是該使用 AI 的地方。由 webcam 擷取影像，<a href="https://up-board.org/upsquared/specifications/">Intel Up Squared </a>開發板做運算，使用 posenet pre-trained model 來找到身體各個主要關節在影像中的位置，然後將右手腕關節位置換算成馬達控制的座標，傳送到 Arduino 控制機器手臂的馬達，便可以讓燈光照射在適當的位置；另外計算各關節的相對位置來判斷坐姿是否正確；同時也以 Arduino 輸出 PWM 訊號控制 LED 燈的亮度。概念圖如下：</p>
<p><img src="/wp-content/uploads/2020/07/1_0tA5m9uXpe3FNv6E4k3LvA.png" alt="" width="700" height="408" class="alignnone size-full wp-image-13616" /></p>
<p><strong>Intel Up Squared 開發板</strong></p>
<p>或許大家對於這個開發板較為陌生，但如果提到 Intel NCS 神經計算棒，應該滿多人有聽過，Up squared 開發板就是使用 Intel 的 CPU 再加上與 NCS 同系列晶片的 VPU，專做 AI model 的 inference 工作；使用起來就跟一般電腦沒兩樣，可以安裝 Windows 10 或 Ubuntu 等作業系統，另外還提供與 Raspberry Pi 相同的 40 pin GPIO 腳位，方便外加其他裝置使用。</p>
<p>近期 Intel 的 CPU 裡都有內建 GPU，因此這塊開發板可以同時使用 GPU 和 VPU 來跑兩個不同的 AI model，需要的話還可以在 USB 插上神經計算棒來跑更多 model。當然要使用這些功能是需要安裝<a href="https://software.intel.com/content/www/us/en/develop/tools/openvino-toolkit/get-started.html"> Openvino toolkit </a>的，安裝方式在官網中有 step by step 的步驟說明。</p>
<p><img src="/wp-content/uploads/2020/07/1_yEksq8ETTUJW1-nib5VWeA.png" alt="" width="1000" height="305" class="alignnone size-full wp-image-13618" /></p>
<p><strong>Openvino</strong></p>
<p><a href="https://software.intel.com/content/www/us/en/develop/tools/openvino-toolkit/get-started.html">Openvino toolkit </a>是 Intel 提供的一個深度學習工具包，為了能在 Intel 平台上快速的做 inference，需要使用這個工具包把已經在其他平台訓練好的模型縮減並轉化成 Openvino 的中繼表示 (IR) 檔們。</p>
<p>以下指令將 tensorflow 的 pb 檔轉成 Openvino 的 IR 檔，並且指定輸入大小、輸出層與精度，執行後會產生一個 .xml 檔與一個 .bin 檔。</p>
<img src="/wp-content/uploads/2020/07/螢幕快照-2020-07-25-上午12.39.13.png" alt="" width="688" height="224" class="alignnone size-full wp-image-13619" /></p>
<p>簡化後的程式主要執行步驟如下：</p>
<p><img src="/wp-content/uploads/2020/07/螢幕快照-2020-07-25-上午12.40.26.png" alt="" width="681" height="311" class="alignnone size-full wp-image-13620" /></p>
<p><strong>PoseNet</strong></p>
<p>Openvino 提供了很多 pre-trained model 可以使用，也試過裡面提供的 single-human-pose-estimation-0001 來標出各關節的位置，雖然準確度較高，但 frame rate 只剩不到 2fps，用來控制機器手臂比較不順暢。</p>
<p>因此使用了 PoseNet，本來就開發給 mobile devices 和瀏覽器使用，因此硬體需求較低，雖然準確度也較低，但已足敷使用。Google 只有提供 Tensorflow lite 的 PoseNet pre-trained model，因此需要轉成 Tensorflow 的 pb 檔（這裡有詳細流程），再轉成 Openvino 的 IR 檔（指令如上）。</p>
<p><strong>程式流程</strong></p>
<p>程式流程如下圖，左邊是在 Intel Up squared 開發板上執行的流程，起始時先將 PoseNet 與物件偵測（使用 mobilenet_ssd，只做人物偵測) model 分別載入 GPU 與 HDDL，接下來針對攝影機擷取的每一張影像做身體關節偵測與人物偵測，使用這些資訊來判斷右手的位置與坐姿正確與否，並輸出座標給 Arduino Uno 開發板。</p>
<p>由於目標是快速做出樣品，因此坐姿的判斷是以傳統 rule-based 的方式來做，但缺陷其實很多，這部分應該也要改以 AI 的方式來做判斷較為準確。</p>
<p>右邊的 Arduino 開發板經由 UART 收到右手座標後轉換成每個馬達的轉動角度與方向資訊，用以控制機器手臂。（如下圖，當物體由 X 移動到 Y，底座馬達與第三節馬達分別要轉動的角度為 ?1 與 ?2），但因為沒有距離資訊 d，所以無法以三角函數直接算出最終角度，只能計算方向（正轉或反轉）與相對的大小，所以就以每次轉動小角度慢慢逼近的方式處理。</p>
<p><img src="/wp-content/uploads/2020/07/1_9MurAsnEdTfgQ7LVwXRMuA.png" alt="" width="700" height="390" class="alignnone size-full wp-image-13621" /></p>
<p><strong>Up Squared 與 Arduino 的溝通</strong></p>
<p>前面說到 Up Squared 會計算出右手在影像中的座標，接下來我們使用 UART 這種序列式傳輸技術把座標傳送到 Arduino。</p>
<ul>
	<li>在 Arduino 端，可以使用 Serial 這個函式庫</li>
	<li>在 Intel Up Squared 端，則使用 pySerial 這個函式庫</li>
</ul>

<p><img src="/wp-content/uploads/2020/07/1_ZdapGuFKZ8acftfJa6_xhA.png" alt="" width="700" height="468" class="alignnone size-full wp-image-13622" /></p>
<p><strong>執行畫面</strong></p>
<p>淺藍色圈圈是關節位置，深藍色框框是物件偵測的結果。右邊模擬姿勢不正的狀態，在左上角有顯示提醒，並且也發出警示音效。</p>
<p><img src="/wp-content/uploads/2020/07/1_ra_mfYR2D8Pg6uUyNCy8gA.png" alt="" width="1000" height="400" class="alignnone size-full wp-image-13623" /></p>
<p><strong>Tinkerkit Braccio 機器手臂</strong></p>
<p><a href="https://store.arduino.cc/usa/tinkerkit-braccio">Tinkerkit Braccio </a>是支六軸機器手臂，也就是有六顆伺服馬達，每個馬達的工作範圍都是180度，分別控制底座旋轉角度、三節手臂的角度、與末端夾具的開合角度，我們以<a href="https://github.com/kk6axq/BraccioV2"> BraccioV2 函式庫</a>控制手臂各個馬達。</p>
<p><img src="/wp-content/uploads/2020/07/1_rmaX7EI9ROHrdNs7Myhfdg.png" alt="" width="1000" height="413" class="alignnone size-full wp-image-13624" /></p>
<p>由於不需要抓握東西，因此拆除夾具轉接上燈罩，轉接器與燈罩內的 LED 固定支架則是由 3D 列印製成。</p>
</p><img src="/wp-content/uploads/2020/07/1_OQBh93beuCgXUAmdpCkarQ.jpeg" alt="" width="700" height="933" class="alignnone size-full wp-image-13625" /></p>
<p><strong>References</strong></p>
<p><a href="https://www.tensorflow.org/lite/models/pose_estimation/overview"><img src="/wp-content/uploads/2020/07/螢幕快照-2020-07-25-上午12.54.24.png" alt="" width="682" height="179" class="alignnone size-full wp-image-13626" /></a></p>
<p><a href="https://medium.com/@oviyum/real-time-human-pose-estimation-on-the-edge-with-movidius-ncs-and-openvino-ac3b13536"><img src="/wp-content/uploads/2020/07/螢幕快照-2020-07-25-上午12.55.25.png" alt="" width="680" height="171" class="alignnone size-full wp-image-13627" /></a></p>
<p><a href="https://www.arxiv-vanity.com/papers/1812.08008/"><img src="/wp-content/uploads/2020/07/螢幕快照-2020-07-25-上午12.56.46.png" alt="" width="684" height="173" class="alignnone size-full wp-image-13628" /></a></p>
<p><a href="https://github.com/rwightman/posenet-python"><img src="/wp-content/uploads/2020/07/螢幕快照-2020-07-25-上午12.57.54.png" alt="" width="680" height="167" class="alignnone size-full wp-image-13629" /></a></p>
<p>原文<a href="https://medium.com/ai-academy-taiwan/%E7%9C%9F%E6%99%BA%E6%85%A7%E6%AA%AF%E7%87%88-prototype-a731b638bad6">請點</a></p>
<code>本文引自<a href="https://medium.com/ai-academy-taiwan">台灣人工智慧學校medium專欄</a>，medium專欄是由台灣人工智慧學校所經營，學校AI工程師們將定期於medium上分享近期技術研究及AI相關知識</code>