2017年8月18日

使用imagej的ROI Manager分析肌肉比例

這個案例是針對肌少症(sarcopenia)的肌肉量分析,需要計算在脊柱旁肌群(paraspinal muscles )中的實質肌肉量有多少,但需要排除在肌群內的脂肪量才能計算

運用方式就跟之前協助指導的一些案例相同,請見「imagej分析影像面積-活用ROI Manager

過程中會用到ROI Manager的AND和XOR運算



圖片來源:Imagej的說明文件
(用瀏覽器的搜尋功能進入此頁後,找"ROI Manager"就可以找到那一段落)

詳細的作法說明如影片所示




2017年8月14日

用定點攝影加上OpenCV看英仙座流星雨


2017英仙座流星雨疊圖

2016/8/12晚上有英仙座流星雨,不過我當天晚上沒看。隔天看資料的時候,看到它的輻射點似乎和我定點攝影拍的方位一致,心想自己持續架在窗邊的定點攝影機是不是有拍到。昨天就檢視那些影片,果然看到了一些流星還有火流星呢。

不過自己用眼睛看啊看,實在是很累的事情。因為是快轉看的,甚至還會因此而錯失某些路徑短的流星。所以就想應該來寫一個python script來自動搜夜空的流星才是。

分析流程如下:
1.把夜空畫面切出來轉成灰階
2.偵測畫面的灰階值是否有大於某個閾值,如果有代表天空有亮點
3.把偵測到亮點的畫面資料存出來,包括亮點的灰階值、位置、檔案名稱(代表時間),還有把具有亮點的影格也存出來。


最後用眼睛確認那個亮點到底是飛機還是流星,其實這個用程式也能判斷,就是看亮點的移動速度就可以。過程中還發生一個插曲,我的程式分析的影片到凌晨三點多就開始偵測到持續的亮點,以至於資料量爆增,事後去看,原來是那個時間點月亮出來了。


最後我再把影格用imagej處理,匯出影片還有疊圖。影片濃縮了七八個小時的流星片段,要許願就看這片就行了。疊圖(最上面的圖片)則是可以看出輻射點的位置,就在畫面上方。



 我想未來可以做一個「流星自動許願機」,就只要在程式裡輸入願望,然後把攝影機對準夜空,就可以去睡覺了,不用熬夜看流星。機器偵測到流星之後,就會自動語音播報願望,保證不會錯失流星,這樣真是太偉大了。 

以下就是流星雨的出現資料,打星號為明顯而持續的流星,可能是火流星。
2017/08/12 19:10:37
2017/08/12 20:28:52
2017/08/12 21:30:14
2017/08/12 21:38:19
2017/08/12 21:59:43
2017/08/12 22:06:33 *
2017/08/12 22:37:14
2017/08/12 23:08:32
2017/08/12 23:09:11
2017/08/13 00:12:54
2017/08/13 00:44:56 *
2017/08/13 01:05:42
2017/08/13 01:09:20 *
2017/08/13 01:34:5
2017/08/13 01:39:34
2017/08/13 01:40:24
2017/08/13 01:50:19
2017/08/13 01:50:40
2017/08/13 01:54:35
2017/08/13 02:35:11
2017/08/13 02:38:31 *
2017/08/13 02:46:35
2017/08/13 03:05:29
2017/08/13 03:10:16
2017/08/13 03:12:36










****以下為程式的部份***************************************
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import numpy as np
import cv2
import os
import math
from collections import deque
from operator import itemgetter


def meterFinding(file,video_index):

    frameNum = 0
    cap = cv2.VideoCapture(file)

    #開始處理影格
    while(cap.isOpened()):
        #現在處理到哪個檔案
        print(videofiles[video_index])
        ret, frame = cap.read()


        #獲知每秒多少影格frame per second
        fps = cap.get(cv2.CAP_PROP_FPS)
       
        #影格播完了,就播放下一個,直到video_index到達影片檔案的數量,就停止
        if frame is None:

            video_index += 1
            if video_index >= len(videofiles):
                break
            cap = cv2.VideoCapture(videofiles[ video_index ])
            ret, frame = cap.read()
            frameNum=0
        #把天空從影格中裁切出來[y1:y2,x1,x2]
        sky=frame[0:202,271:1270]

        #天空轉換成灰階
        gray_sky = cv2.cvtColor(sky, cv2.COLOR_BGR2GRAY)



        #找黑天空上的最大灰階值
        max_value = max(max(l) for l in gray_sky)
        #print(max_value)





        #如果最大灰階值大於120,代表有流星,就把檔案路徑印出
        if max_value >120:
            print(videofiles[video_index])

            with open("output.txt", "a") as text_file:

                #輸出檔案名稱
                text_file.write(videofiles[video_index])
                text_file.write("\t")

                #輸出秒數
                text_file.write(str(int(frameNum/fps)))
                text_file.write("\t")

                #輸出最大值
                text_file.write(str(max_value))
                text_file.write("\t")

                #輸出流星的位置
                ar = np.array(gray_sky)
                max_index = np.where(ar == max_value)



                #y的位置
                text_file.write(str(max_index[0]))

                text_file.write("\t")

                #X的位置(越大,越靠右,500多在山邊,900多就是在山上)
                text_file.write(str(max_index[1]))



                text_file.write("\n")


                #把畫面存起來

                pngName = videofiles[video_index]
                pngName = pngName.lstrip("/home/pancala/Desktop/video/test/")
                pngName = pngName.rstrip(".mp4")
                pngName = pngName.replace('/', '')
                pngName = pngName + "_" + str(int(frameNum/fps)) + "_" + str(frameNum)
                pngName = pngName + ".png"
               
                cv2.imwrite(pngName,frame)

        #if max(gray_sky,key=itemgetter(1))[0] >30:
            #print(max(gray_sky,key=itemgetter(1))[0])

        #呈現夜空
        #cv2.imshow('sky',gray_sky)

        frameNum = frameNum +1
        #調整waitkey 控制播放速度
        k = cv2.waitKey(5) & 0xff
        if k == 27:
            break



    cap.release()
    cv2.destroyAllWindows()


video_index = 0
videofiles = []
for dirPath, dirNames, fileNames in sorted(os.walk("/home/pancala/Desktop/video/test")):
    for f in sorted(fileNames):
        inputFile=os.path.join(dirPath, f)
        lastFile=os.path.splitext(f)[-1]
        if lastFile==".mp4":
            #file='output.mp4'
            #把檔案路徑都放進videofiles的list
            videofiles.append(inputFile)

#videofiles = [n for n in os.listdir('.') if n[0]=='c' and n[-4:]=='.mp4']
#videofiles = sorted(videofiles, key=lambda item: int( item.partition('.')[0][3:]))

meterFinding(videofiles[0],video_index)

2017年8月12日

Moodle帶著隨身走-魔豆盒(moodleBox)

想像一些情境,帶學生在校園活動,需要用到行動學習的教學平台,但是根本就沒有網路訊號?或是在無法建置網路的學校或教室,想要有行動學習的平台,那該怎麼做?或是像我一個同事的需求,想要讓學生用Moodle做測驗,但是不希望學生連到網際網路。

這要怎麼做到呢?簡單,一塊樹莓派就可以辦到,讓Moodle平台帶著隨身走耶!











昨天前往新竹縣網中心學到了這個東西,叫做魔豆盒(MoodleBox),是把Moodle架在樹莓派3上,可以同時提供wifi熱點和moodle平台。由於moodle平台是直接架在樹莓派上,所以不需要網際網路也可以,而如果真的需要連線,也只要用網路線接上樹莓派就可以。

安裝很難嗎?超簡單的,不用管什麼網路設定、伺服器設定的。你所要做的就是買一塊讀寫速度快的記憶卡,把moodleBox的的img映像檔燒錄進去,插上電源後,一切就自動搞定了,剩下就是老師建課程了。
有興趣建制的,可以看看我的建置筆記
https://docs.google.com/document/d/1q3REWSHKbuhhoR4jXm0y14Qiq55_lS1jXi6Gynv0nDA/edit


德文老師和士玉老師也寫了建置的筆記
https://docs.google.com/document/d/1VcD3TFByOcfoKzqycGLcHm0yTg3VuhC40DQB8RVEN6Y/mobilebasic



想起以前出去演講行動學習的時候,有老師問起moodle,也想要擁有一個,但是苦於學校沒站,或是網路環境受限,我想這魔豆盒就是一個很棒的解決方案。

而如果想要架在網際網路上,現在也可以直接到教育雲的「合作備課」平台,申請開課。你就不用考慮架站或是站台管理的問題,學生也可以用Google帳號或是使用教育雲的單一帳號登入你的Moodle課程。

用GoogleEarth Engine看台灣的滄海蒼田變化

最近看公視在播高公局的紀錄片「重返里山」(可以在youtube看到喔),片中幾個點還蠻熟悉的,像那個跨越高速公路的大橋就是兩年前特地去看的西湖段大跨距拱橋,然後中二高苗栗通霄段也是常常會經過的地方。

道路開發帶來的是棲地的切割,高速公路就像一道城牆在土地上畫出界線,兩側的動物交流變成十分困難,這是開在高速公路上的我們很難想像的一件事。

在高速公路還沒建成前,這裡長什麼模樣,動物怎麼樣在這塊土地上自由來回穿梭?這是我在車上經常的疑問。

在Google Earth Engine的網站(https://earthengine.google.com/timelapse/)上有一個Timelapse功能,蒐集了1984年以來32年的影像資料,可以讓我們看到這些年來大地的改變。

我把畫面移動到苗栗通霄的位置,畫面中出現的兩條線, 一個是二高,另一個是高鐵。二高各段的建成時間不相同,北二高是1993-1997,中二高是1998左右,高鐵則是2007。




我把畫面再往南移動,到了外傘頂洲,看到的是外傘頂洲越來越小,看起來現在已經比五年前我去的時候小更多了。




還有哪些地方可以看看呢?

  • 基隆河可以看到截彎取直那段,現在是摩天輪
  • 新莊五股二重疏洪道那一帶,1984年還可以看到一大片溼地
  • 屏東那的山區,在2002-2003年開始,就山上大禿
  • 萬大水庫在最近幾年,北面的淤塞都沒消失

另外,最前面提到的重返里山紀錄片
有興趣多了解的,這個blog有介紹

田鱉埤塘谷津田
http://giantwaterbug.blogspot.tw/

這塊田的地點,可以用GoogleMap搜尋:24.518813, 120.724761

LASS年會與Hack4U Live 空氣盒子工作坊

上個月底(7/29)第二屆LASS年會在交大舉辦,因為地利之便就報名參加了。

LASS是Location Aware Sensing System的簡寫,公民透過開源軟體、硬體、韌體進行在地環境感測,並將這些環境資料整合在一起成為環境感測的網路,目前最主要進行的就是空污指標之一的 pm 2.5的感測。

當天的演講投影片都在此連結

其中最讓我眼睛一亮的是這個專案超酷的-「紫豹在哪裡?」



作者將各個測站的的歷史資料、風向...等整合在一起做視覺化呈現,可以用在追蹤空汙的動向,甚至可以推測汙染是境外移入還是境內產生。

以下這個連結是作者的簡報,也都能連結到各個案例的視覺化呈現的頁面https://docs.google.com/presentation/d/17d_l0R2q03712SDd8CCWDOqNF7-2oJBlvWoYvV8a-U8/edit#slide=id.g23cdeac48e_0_400


下午的課程中有一個是「HACK4U」空污監測設備的自作課程,製作的成品如下


可以偵測 pm2.5濃度、溫度、濕度,並將這些資訊傳到LASS和Blynk的伺服器。傳到LASS的伺服器之後,可以在gov零時空污觀測網看到你提供的資料。而傳到Blynk的部份,則是可以結合手機APP看到連續性的歷史資料。


設計者的巧思讓這個Hack4U也能夠進行移動偵測,只要讓Hack4U連上手機熱點,然後你可以帶著裝置四處移動,它會自動抓取手機的GPS位置還有所在地的環境資料。隨後你可以用Blynk的APP把這些感測資料下載成csv檔,再做後續分析。


Hack4U的硬體主要是RealtekAmeba 8195開發版,溫濕度感測器是SHT31,pm2.5感測器則是PlenTower PMS3003 (G3) 。有興趣取得的話,在iCshop可以購得套件,但是組裝和程式安裝要自己來。另外,Hack4U的臉書社團是這個「Hack 4Ü : Arduino生活改造計劃」,有相關的文件如此連結

其實除了這個以外,去年我還做了一些其他的空氣監測的專案,像是「使用Arduino動手監測空氣懸浮微粒」、「迷你空氣盒子」,還有一個是沒寫出來是LASS Field Try的套件(安裝的說明文件可以看這個這個



你可能對這有興趣

Related Posts Plugin for WordPress, Blogger...