影象處理 離散haar小波變換
阿新 • • 發佈:2019-02-16
程式設計環境:windows下結合opencv庫
//離散Haar小波變換
/*
dst深度為IPL_DEPTH_32F
nLayer為變換尺度
*/
void HaarWavelet(IplImage* src, IplImage* dst, int nLayer);
//離散Haar小波變換 /* dst深度為IPL_DEPTH_32F nLayer為變換尺度 */ void HaarWavelet(IplImage* src, IplImage* dst, int nLayer) { if (!dst) { return; } if (((dst->width >> nLayer) << nLayer != dst->width) || ((dst->height >> nLayer) << nLayer != dst->height) || (dst->depth != IPL_DEPTH_32F) || (src->nChannels != 1) || (dst->nChannels != 1) || (nLayer <= 0)) { return; } int x, y; int nWidth = dst->width; int nHeight = dst->height; int nHalfWidth = nWidth / 2; int nHalfHeight = nHeight / 2; //影象資料的起始地址 float* *pfData = (float**)(malloc(sizeof(float*) * nHeight)); //儲存計算過程中用到的行列資料 float* pfRow = (float*)(malloc(sizeof(float) * nWidth)); float* pfColumn = (float*)(malloc(sizeof(float) * nHeight)); CvMat tmp; //預先填充dst cvZero(dst); cvGetSubRect(dst, &tmp, cvRect(0, 0, src->width, src->height)); cvScale(src, &tmp, 1.0, 0); //儲存影象資料每行的起始地址 for (y = 0; y < nHeight; y++) { pfData[y] = (float*)(dst->imageData + y * dst->widthStep); } while (nLayer > 0) { //行變換 for (y = 0; y < nHeight; y++) { for (x = 0; x < nHalfWidth; x++) { pfRow[x] = (pfData[y][2 * x] + pfData[y][2 * x + 1]) / 2.0; pfRow[x + nHalfWidth] = (pfData[y][2 * x] - pfData[y][2 * x + 1]) / 2.0; } for (x = 0; x < nWidth; x++) { pfData[y][x] = pfRow[x]; } } //列變換 for (x = 0; x < nWidth; x++) { for (y = 0; y < nHalfHeight; y++) { pfColumn[y] = (pfData[2 * y][x] + pfData[2 * y + 1][x]) / 2; pfColumn[y + nHalfHeight] = (pfData[2 * y][x] - pfData[2 * y + 1][x]) / 2; } for (y = 0; y < nHeight; y++) { pfData[y][x] = pfColumn[y]; } } //一層變換後尺度的縮小 nLayer--; nWidth = nHalfWidth; nHeight = nHalfHeight; nHalfWidth = nHalfWidth / 2; nHalfHeight = nHalfHeight / 2; } //結果縮放以便與顯示 double min,max; cvMinMaxLoc(dst, &min, &max, NULL, NULL, NULL); cvScale(dst, dst, 1.0/(max-min), 1.0*(-min)/(max-min)); }