在處理一些需要映像相加運算的操作時,通常定義
IplImage* dst = cvCreateImage(cvGetSize(img),IPL_DEPTH_64F,img->nChannels);
當處理完成後,需要對原這個IPL_DEPTH_64F深度的映像進行顯示的時候,就需要做一些轉換。可以用cvScale()這個函數,這個函數主要是對映像做線性變換。如果不轉換的話,可以發現顯示的映像是全白的。這是由於IPL_DEPTH_64F類型的圖片顯示範圍為[0,1]。
cvMinMaxLoc(dst, &m, &M, NULL, NULL, NULL);
cvScale(dst, dst, 1.0/(M-m), 1.0*(-m)/(M-m));//映像資料轉換到[0,1]區間
這個時候就可以正常的顯示映像了。當需要在不同深度的映像之間轉換時,也可以用cvScale()這個函數。這個時候的轉換,中間有個截斷處理過程。比如IPL_DEPTH_64F到IPL_DEPTH_8U,就會把300轉換到255。下面轉一段別人總結的深度顯示範圍。
測試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
這個時候如果需要儲存映像,請記住要先轉換到IPL_DEPTH_8U的深度。因為只有8位單通道或者3通道(通道順序為'BGR' )才可以使用cvSaveImage儲存。下面貼一段自己測試用的代碼:
int main(int argc, char ** argv)<br />{<br />IplImage* img = cvLoadImage("lena.bmp",CV_LOAD_IMAGE_GRAYSCALE);<br />IplImage* tmp = cvCloneImage(img);<br />IplImage* dst = cvCreateImage(cvGetSize(img),IPL_DEPTH_64F,img->nChannels);<br />double M,m;<br />cvScale(img,dst,1.0,0.0);<br />cvAdd(dst,dst,dst);<br />cvMinMaxLoc(dst, &m, &M, NULL, NULL, NULL);<br />cout<<"M="<<M<<endl<<"m="<<m<<endl;</p><p>cvScale(dst,tmp,1.0,0.0);</p><p>cvScale(dst, dst, 1.0/(M-m), 1.0*(-m)/(M-m));//映像資料轉換到[0,1]區間</p><p>cvMinMaxLoc(dst, &m, &M, NULL, NULL, NULL);<br />cout<<"M="<<M<<endl<<"m="<<m<<endl;</p><p>cvNamedWindow("img",CV_WINDOW_AUTOSIZE);<br />cvShowImage("img",img);</p><p>cvNamedWindow("tmp",CV_WINDOW_AUTOSIZE);<br />cvShowImage("tmp",tmp);</p><p>cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);<br />cvShowImage("dst",dst);</p><p>cvWaitKey(-1);<br />cvDestroyAllWindows();<br />cvReleaseImage(&dst);<br />return 0;<br />}