Open ndujar opened 4 years ago
/cc @krshrimali @clunietp Could you please take a look on this?
Thanks @ndujar for reporting this here. I'll be able to look into this, this weekend. Will update back with my views. Hope it sounds good, @alalek @ndujar. Thanks!
Hi @ndujar
Here is the original author's code, available from https://live.ece.utexas.edu/research/Quality/index_algorithms.htm
//compute mu and mu squared
IplImage* mu = cvCreateImage(cvGetSize(imdist_scaled), IPL_DEPTH_64F, 1);
cvSmooth( imdist_scaled, mu, CV_GAUSSIAN, 7, 7, 1.16666 );
IplImage* mu_sq = cvCreateImage(cvGetSize(imdist_scaled), IPL_DEPTH_64F, 1);
cvMul(mu, mu, mu_sq);
//compute sigma
IplImage* sigma = cvCreateImage(cvGetSize(imdist_scaled), IPL_DEPTH_64F, 1);
cvMul(imdist_scaled, imdist_scaled, sigma);
cvSmooth(sigma, sigma, CV_GAUSSIAN, 7, 7, 1.16666 );
cvSub(sigma, mu_sq, sigma);
cvPow(sigma, sigma, 0.5);
//compute structdis = (x-mu)/sigma
cvAddS(sigma, cvScalar(1.0/255), sigma);
IplImage* structdis = cvCreateImage(cvGetSize(imdist_scaled), IPL_DEPTH_64F, 1);
cvSub(imdist_scaled, mu, structdis);
cvDiv(structdis, sigma, structdis);
Matlab version:
window = fspecial('gaussian',7,7/6);
...
mu = filter2(window, imdist, 'same');
mu_sq = mu.*mu;
sigma = sqrt(abs(filter2(window, imdist.*imdist, 'same') - mu_sq));
structdis = (imdist-mu)./(sigma+1);
Are you suggesting the current OpenCV implementation is wrong, or the original author's implementation is wrong? It is possible we missed something when porting to OpenCV.
Thanks
Hi @clunietp
Indeed, the original implementation seems to be mistaken :/
However, the code says otherwise, as they seem to be applying the Gaussian filter to both the squares of the I and mu separately, then computing the pixelwise squared root. Actually, that explains why they need to use the abs() function, when in reality it shouldn't be needed because quadratic products are always positive.
Interesting. I wonder how your proposed method compares to the original method. From what I remember, the current implementation did not score nearly as well on TID2008 as is documented in the paper, and I wonder if this may be the cause. Ref: Table VIII in https://www.live.ece.utexas.edu/publications/2012/TIP%20BRISQUE.pdf
Are you (or anyone) able to test the current impl vs the proposed changes on TID2008? I'd be interested in the result. Unfortunately I don't really have a lot of time right now. Eval code is here: https://github.com/opencv/opencv_contrib/blob/master/modules/quality/samples/brisque_eval_tid2008.cpp
If the revised method does improve performance on TID2008 and brings it closer to Mittal's original work, then I would agree with changing the current implementation.
System information (version)
Detailed description
I have carefully gone through the transformations implemented in the qualitybrisque.cpp file (lines 147 to 165) to produce the MSCN image (structdis) and I believe there might be a mistake in the way it is conceived, particularly in the obtainment of the denominator.
Steps to reproduce
qualitybrisque.cpp: lines 145-165:
Here the computation of mu_sq leads to the wrong result...
..because it is not the same the square of the difference as the difference of the square
Proposed solution
Issue submission checklist