1. 實(shí)驗(yàn)室中CCD的實(shí)際色階為14位,獲取的原始圖像數(shù)據(jù)的每個(gè)值都存儲(chǔ)在一個(gè)字中,即存儲(chǔ)色階16位,也就是說最高兩位的數(shù)據(jù)一直為0,同時(shí)獲取的圖片信息僅僅是16色階的灰度圖,而采用wxWidget沒有辦法直接將16位的數(shù)值串保存為圖片格式,如tiff格式,那么如何將16位的數(shù)值串以圖片的形式進(jìn)行保存呢?
經(jīng)過這么幾天的折騰總算是找到了一條解決的途徑,就是將16位的數(shù)值串轉(zhuǎn)化為8為的數(shù)值串,也許你會(huì)很快的想到這么一個(gè)方法,nValue*max(uint8)/max(uint16);用來表示轉(zhuǎn)化后的數(shù)值,不夠還是得考慮一下CCD的實(shí)際色階,由于是14位,因此可以采用這樣的方式nValue*max(uint8)/max(uint14);不過由于我們對于圖片的處理是直接對圖片的原始數(shù)據(jù)進(jìn)行處理,而轉(zhuǎn)化只是圖片在顯示屏上顯示的前提步驟,采用上述的方式雖然能夠相對很準(zhǔn)確的進(jìn)行轉(zhuǎn)化,但是需要花費(fèi)一定的計(jì)算量,而通過近似的轉(zhuǎn)化能夠更快的進(jìn)行這個(gè)轉(zhuǎn)化過程,同時(shí)獲取得到的圖片依然具有較好的清晰度,下面細(xì)說一下我采用的方法:
1: unsigned short nPicData16 = new unsigned short[nBufSize]; // nBufSize is the size to store pic
2:
3: // to get the nPicData16
4: // ..................
5: // get the nPicData16
6:
7: char *pcPicData8 = new char[nBufSize];
8: for (size_t i = 0; i < nBufSize; ++i) {
9: pcPicData8[i] = (char)(nPicData16>>6);
10: }
11:
12:
由于2^6在2^14中所占的比例較小因此可以采用這樣的近似的方法。(這種方法具體有什么作用或是缺陷還沒有細(xì)究,請各位看官給點(diǎn)看法)
2. 順利將14位數(shù)值串轉(zhuǎn)化成為8為數(shù)值串后,嘗試的使用下列方式進(jìn)行圖片保存,發(fā)現(xiàn)結(jié)果一片黑,數(shù)值都為0了:
1: // 結(jié)果發(fā)現(xiàn)存儲(chǔ)得到的save.bmp圖是24b的
2: wxBitmap bitmap(pcPicData8,1392,1040,8);
3: bitmap.SaveFile(wxT("save.bmp"),wxBITMAP_TYPE_BMP);
4:
因此猜想wxWidget對直接獲取的數(shù)據(jù)串進(jìn)行保存時(shí)采用的rgb的模式進(jìn)行保存,可能只會(huì)保存為24字節(jié)格式的圖片,也就是想要將圖片顯示到屏幕上時(shí),也應(yīng)該采用24b的圖片。不過wxWidget對于圖片數(shù)據(jù)卻能夠讀取8位的圖片,但是再次采用上述的方式進(jìn)行存儲(chǔ)時(shí),變成了32字節(jié)的了,(各位大蝦知不知道有沒有方法能夠直接保存8位圖的呢)。
于是采用了將這個(gè)8位的數(shù)值串分別賦值給R,G,B,用這種方式實(shí)現(xiàn)灰度圖的創(chuàng)建,然后再進(jìn)行保存,最終解決了問題。
1: unsigned char *rgbData = new unsigned char[1392*1040*3];
2: unsigned char *ptr1 = (unsigned char*) pcPicData8;
3: unsigned char *ptr2 = rgbData;
4: for (int i = 0; i < 1392*1040; ++i) {
5: *ptr2++ = *ptr1;
6: *ptr2++ = *ptr1;
7: *ptr2++ = *ptr1++;
8: }
9: wxImage myImage(1392,1040,rgbData);
10: myImage.SaveFile(wxT("save.bmp"),wxBITMAP_TYPE_BMP);