需要自己寫顏色空間轉換的小程序,其中涉及到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);