Re: [問題] PyQT GUI Line CCD抓data問題

作者: KSJ (阿真)   2013-12-22 04:44:39
※ 引述《captdavince (走自己的路)》之銘言:
: 各位好
: 此文文長含程式碼
: 小弟我是新手,因為目前實驗上的需求急於生出一個可以收data做數據處理的GUI
: 所以就使用PyQT跟matplotlib, numpy, scipy來做
: 我自認自己邏輯、coding什麼都不好,需要的功能多少借網路上的一些範例兜起來了
: 描述一下我的實驗系統
: 我是用Mightex 的線性CCD module TCN1034-U,原廠有附SDK(dll)..但是我不知道要怎
: 麼使用DLL..但是它另外也可以有USB protocol去做data的傳輸
: 因為看到Github上國外有人已經把它的USB protocol寫好一個script來call..
: 所以這個方式我權衡一下是對我比較簡單的..只是目前看起來只能在linux上才順利的
: 抓到這個CCD
: http://www.mightexsystems.com/images/File/ccd_line_camera_software_package.zip
: 這個是原廠的程式
: 包含一個稍完整的控制程式,但是不夠我的實驗使用
: 另外SDK中有各式的dll與examples和SDK的說明文件
: https://github.com/bgamari/mightex-line-ccd
: 這個是國外的先進在Github上面寫好的script,camera.py
: 我先描述一下我的問題.
: 是利用一個read_frame()去讀取CCD的data(會是3648的1D array)
: 後面再做後續的
: 目前的read_frame()是如下
: def read_frame(self):
: try: frame = self.ccd.get_frame() #self.ccd是前面initialize過的camera.py
: except: return None
: if frame is not None:
: return frame.image - np.mean(frame.dark)
: else:
: return None
這個read_frame函式 的回傳值
可以是 None 或是 "有用的值"
但是下面的函式在使用時 並沒有做判斷
: 這個部份的live數據的讀取會是 (我是用一個100ms的counter,到時後就call下面)
: def updateposition(self):
: self.ccd.set_exposure_time(self.ui.ExpSlide.value()) #把快門設成使用者所要的
: self.data = self.read_frame() #讀取data
: x = np.arange(len(self.data)) #取得data長度
讀取後就直接用了?? 是None怎麼辨??
: self.currentview.plot(x, self.data) #用matplotlib widget plot出來
: self.currentcanvas.draw()
: 不過後面還有單次讀取data的時候用的也是類似的方式
: 設快門後,用read_frame()讀data
: 我利用print(frame)的方式來看讀取得順不順利
: 目前看起來是使用者的快門設超過300ms之後就可能會拿到None..
另外還有一個問題是 這個None是從哪來的??
是從try來 還是後面的if判斷式??
雖然結果不影響 但是無法判定程式出錯的地方在哪裡
觀念上還蠻可怕的
: read_frame()不會等到取得ccd的data就會先feed None
: 在後面需要單次讀取data的時候就會造成
: File "project.py", line 206, in acqpos
: a = np.arange(len(self.posframe))
: TypeError: object of type 'NoneType' has no len()
: 的錯誤
這是因為你每100ms 就去抓一次frame
可是exposure time (似乎是指多久會產生一張frame??)
在大於100ms時 理論上是抓不到frame的(還沒產生
(當然還要加上一點其它程式碼運行的時間)
: 這個部份是我真的一點頭緒都沒有不知道該怎麼解決的部份
: 希望各位先進可以幫幫我是不是有簡單的fix,像是改寫read_frame()裡try的判斷
: 式內容,還是難道要連原本國外的那個script裡都需要改寫呢?
原則上你可以更改counter的更新時間
跟exposure time相同即可
不過我看了一下github的if __name__ == __main_:底下的程式碼
while True:
time.sleep(1e-2)
count = c.get_buffered_frames_count()
if count == 0: continue
c._prepare_frames(1)
frame = c._read_frames(1)
print frame.timestamp, frame.dark
似乎有 get_buffered_frames_count() 這個方法去看frame產生了沒
你也可以直接看看ccd的get_frame 它是怎麼實作的
也有用到get_buffered_frames_count哦~
: 是不是應該要寫得讓他會等CCD的方式,因為CCD的exposure是0.1ms~6500ms
: 我會希望可以取得6500ms的data
能是最好 不過用while ccd.get_frame()也不為過
不過因為你是用ui
while ccd.get_frame 在 exposure time 較大時
可能造成你ui畫面的freeze哦~(像當機一樣)
但先別急 把問題一個一個解決吧
: 因為後面的function有部份是希望依使用者設定取得x次特定快門時間的data把它加起來
: (這個部份我還有點問題就是用
: for i in range(1, step+1):
: self.ccd.set_exposure_time(self.ui.ExpSpin.value())
: self.postframe = self.read_frame()
: self.accum += self.posframe
: 其實在這個step>100的時候很容易當掉..改用while loop會比較不容易當掉嗎?
可否說明何為當掉?? (是加到None嗎??)
另外 你的x是指step嗎?? (在程式裡很怕看到不知從何而來的變數)
改用while loop 會不會比較不容易當掉 這個你應該可以自己先試試的說 :)
小建議 set_exposure_time 如果沒有即時隨ui裡的值變動的話
可以不用放進for裡 以減少程式的負擔
: 感謝各位看完這麼長的內容
: 希望我有把我的問題描述清楚
: 謝謝各位大德
加油
本人不是很懂ccd 有什麼誤解還是方向錯誤
還請一拼指正

Links booklink

Contact Us: admin [ a t ] ucptt.com