Opencv中位深數據IPL_DEPTH_8U與IPL_DEPTH_64F的圖像像素數據的轉化


需要自己寫顏色空間轉換的小程序,其中涉及到LOG運算及atan運算,所以在運算過程中用到double類型數據,但最后許轉換為IPL_DEPTH_8U類型,故申請了一幅圖像IplImage* hue64f = cvCreateImage( cvGetSize(src),IPL_DEPTH_64F, 1 );來存儲中間變量。但是問題也隨之而來。

問題1:按照公式計算完,然后再應用ConvertScale轉換數據類型,但轉換結果都是0;ConvertScale將IPL_DEPTH_8U轉化為IPL_DEPTH_64F沒有問題,但是將64F轉化為8U就有問題

然后從頭開始查找錯誤

問題二:數據中存在1.#IND,1.#INF類似數據;

原因:1)像素值為0計算LOG值為負無窮;2)在計算除法時注意判斷分母是否為0,如果接近於0也會出現這種情況,所以主要原因就是運算非法,這是在寫程序時常常忽略的地方。

問題三:計算中間變量為DOUBLE的數據存為hue64f的像素點,再次訪問不是原來得到的數據;

原因:之前訪問數據元素都是IPL_DEPTH_8U類型的,而自己習慣采用指針訪問,訪問為

int step=src->widthStep; uchar *srcdata=(uchar*)src->imageData;

循環訪問:srcdata[i*step+j*3]。

但是在double型數據訪問的時候要注意為以下方式,自己就是忽略了這些東西,使自己讀到的像素值總不對。
int hue64fstep=hue64f->widthStep/sizeof(double); double *hue64fdata=(double*)hue64f->imageData;

問題四:由64F轉換到8U,線性映射過程中需要注意范圍。

解決方法找到的有兩種:用兩個函數1)cvNormalize(hue64f,hue64f,1,0,CV_MINMAX);  //hue64f為64F位深,將其歸一化到0-1之間
//src的值為0-1,乘以scale也就是255,則dst的值變為0-255,符合要求
cvConvertScale(hue64f,hue8u,255,0);

2) double minVal;
double maxVal;
cvMinMaxLoc(hue64f, &minVal, &maxVal);
printf("%f ",minVal);
printf("%f",maxVal);
// Normalize image (0 - 255) to be observed as an u8 image
double scale = 255/(maxVal - minVal);
double shift = -minVal * scale;
cvConvertScale(hue64f,hue8u,scale,shift);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM