※ 引述《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 有什么误解还是方向错误
还请一拼指正