1. 程式人生 > >16位深度圖片顯示並儲存

16位深度圖片顯示並儲存

Opencv 16位深度圖片顯示並儲存

專案需要,要將cmos相機的資料讀出來,並顯示出圖片來。同事已經通過FPGA+USB的方式,把相機並行資料轉成序列,我需要做的就是上位機,找到frame valid和line valid有位,讀取一個frame的資料後,顯示出來。

設計思路: 三個thread,第一個從usb讀資料,第二個處理usb資料包,找frame valid 和 line valid, 第三個負責顯示;顯示部分通過定義IplImage指標,分配空間,然後通過給imdata賦值,來實現顯示。

因為相機是黑白相機,處理難度不大。之前的每個pixel都是8個bits,所以opencv顯示起來很容易。但是後來,上級要求每個pixel要有10個bits來表示,本以為很容易實現,後來搞了2天才搞定,決定總結一下經驗,供需要的朋友參考一下。

 

1. opencv 影象深度

影象深度是指儲存每個畫素所用的位數,也用於量度影象的色彩解析度.影象深度確定彩色影象的每個畫素可能有的顏色數,或者確定灰度影象的每個畫素可能有的灰度級數.它決定了彩色影象中可出現的最多顏色數,或灰度影象中的最大灰度等級.比如一幅單色影象,若每個象素有8位,則最大灰度數目為2的8次方,即256.一幅彩色影象RGB3個分量的象素位數分別為4,4,2,則最大顏色數目為2的4+4+2次方,即1024,就是說畫素的深度為10位,每個畫素可以是1024種顏色中的一種.

 

opencv 深度顯示範圍:(也就是說當定義瞭如下不同深度的時候,畫素的灰度值要處於顯示範圍之中才可以顯示出來。否則要進行轉換)

     測試double型:0.0--1.0之間                              IPL_DEPTH_64F

      測試float型:0.0--1.0之間                                  IPL_DEPTH_32F

      測試long型:0--65535之間                                IPL_DEPTH_32S        

      測試short int型:-32768--32767之間                 IPL_DEPTH_16S        

      測試unsigned short int型:0--65535之間           IPL_DEPTH_16U

      測試char型:-128--127之間                               IPL_DEPTH_8S          

      測試unsigned char型:0--255之間                     IPL_DEPTH_8U

參考連結:

http://blog.csdn.net/wode0239/article/details/8294906

2. 影象深度轉換

當定義瞭如下的深度為16的IplImage

IplImage* dst = cvCreateImage(cvGetSize(img),IPL_DEPTH_16U,img->nChannels);

對其進行賦值,先把imdata強制轉換成unsigned short型

 

 
  1. <span style="font-size:18px;">unsigned short* data = (unsigned short *)(pImg->imageData)

  2. for ( i=0;i<HEIGH;i++)

  3. for( j=0;j<WIDTH;j++)

  4. {

  5. data[j+i*(WIDTH)] = array[j+i*(WIDTH)];

  6. }</span>

處理完後要對其進行顯示。直接使用cvShowImage顯示是有問題的。要進行深度轉換

 

 
  1. cvMinMaxLoc(dst , &m, &M, NULL, NULL, NULL); // 找出dst中,所有資料的最大值和最小值

  2. cvScale(dst , dst , 65535/(M-m), 65535*(-(m+1))/(M-m)); //把dst中的資料對映到0-65535的範圍中

  3. cvShowImage( "source image", pImg ); //完成了上述深度轉換,接下來才能用cvshowImage來顯示

參考連結:

http://blog.csdn.net/xiaowei_cqu/article/details/7557063

http://blog.csdn.net/loop_k/article/details/5401342

http://blog.163.com/gz_ricky/blog/static/18204911820115203045235/

http://blog.csdn.net/z397164725/article/details/7245328

3. 影象儲存

最後就是要儲存圖片了,但是對於深度位16的圖片,用cvSaveImage是不能夠儲存的,因為cvSaveImage只能儲存深度為8的圖片。這裡,用imwrite來儲存,無壓縮,png格式。

 

 
  1. <span style="font-size:18px;"> vector<int> compression_params;

  2. compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);

  3. compression_params.push_back(0); // 無壓縮png.

  4. sprintf(fileName, "Picture %d.png", ++countCamera); //生成檔名

  5. cv::Mat pImgMat(pImg,0); //把IplImage轉換為Mat

  6. imwrite(fileName,pImgMat,compression_params); //儲存圖片</span>

轉載:https://blog.csdn.net/yangcong1234/article/details/47950597