pierrepaleo / PDWT

A GPU implementation of the Wavelet Transform
Other
69 stars 22 forks source link

The difference between PDWT and Matlab's DWT2 function. #7

Open zhongxiangrong opened 11 months ago

zhongxiangrong commented 11 months ago

I tried to reproduce the 2D discrete wavelet transform in Matlab and PDWT, and then plotted a histogram of the cA parameter. The results are shown in the figure below, with red representing the result from Matlab and blue representing the result from PDWT. I would like to know what could be the possible reasons for this situation? hist This is my C++ code. Wavelets w(img_f,rows,cols,"haar",1,1,1,0,0,2); w.forward(); w.get_coeff(LL, 0); //....change LL(float *) to LL(cv::Mat) cv::Mat hist_cA; const int bin = 256; float range[] = {0,255}; const float* histRange[] = {range}; cv::normalize(LL,LL,0,255,cv::NORM_MINMAX,-1); cv::calcHist(&LL,1,0,cv::Mat(),hist_cA,1,&bin,histRange,true);

This is the Matlab code. [LL,LH,HL,HH] = dwt2(I1,'haar'); hist_cA = imhist(mat2gray(LL));

pierrepaleo commented 11 months ago

Hi @zhongxiangrong

If I remember correctly Matlab uses a different extension mode by default. PDWT always uses the periodic extension mode. Probably that's the cause of the discrepancy.

I just tried with

C = imread('ngc6543a.jpg');
I1 = C(:, :, 1);
imwrite(I1, "ngc6543a_gray.tif")
[LL,LH,HL,HH] = dwt2(I1,'haar', 'mode', 'ppd');
save("LL.mat", LL)

and on the other hand with the python wrapper to PDWT:

from tifffile import imread
from pycudwt import Wavelets
from scipy.io import loadmat
test_img = imread("ngc6543a_gray.tif")
W = Wavelets(test_img, "haar", 1)
W.forward()

LL = loadmat("LL.mat")["LL"] # result from matlab
print(np.max(np.abs(W.coeffs[0] - LL))) # 1e-13

which gives exactly the same result for the approximation coefficient.

zhongxiangrong commented 11 months ago

Hi! @pierrepaleo Thank you very much for your answer. I later found out that the image was subjected to logarithmic operations in the MATLAB code, but not in my C++ code. Referring to your code, I saved the calculated LL component as a tif image in C++, and then used MATLAB to read the LL.tif file. After subtracting it, I found that the maximum error was 5.2871e-08. The wavelet coefficients of PDWT are similar to those of Matlab's wavelet transform.As for the histogram statistics after normalizing the LL, the results are as follows. In fact, the difference in histograms is due to the difference between MATLAB's imhist function and OpenCV's calchist function. hist2

zhongxiangrong commented 11 months ago

I have one more question. I have multiple GPUs. Can PDWT choose which specific GPU to perform cuda computation on? In addition, what do the memisonhost, do_separable, and do_cycle_spinning parameters in the Wavelets constructor represent? I look forward to your reply.

pierrepaleo commented 11 months ago

IIRC there is no explicit GPU choice parameter in the Wavelets() class. Normally Cuda will automatically pick the "best" GPU at run-time. A way to manually pick a device is via the environment variable CUDA_VISIBLE_DEVICES, though admittedly not ideal.

As for parameters:

Hope this helps!