cv_hal_convertScale in not accurate in current main branch
- Hardware: Jetson ORIN (fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp uscat ilrcpc flagm)
- Compiler: gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
- KleidiCV: main (68ff8aa2)
- OpenCV: 4.x (344f8c640034cb509930d1c92ff1a73a04101ebc)
The OpenCV function is pretty simple:
// Normalizes histogram (make sum of the histogram bins == factor)
CV_IMPL void
cvNormalizeHist( CvHistogram* hist, double factor )
{
double sum = 0;
if( !CV_IS_HIST(hist) )
CV_Error( cv::Error::StsBadArg, "Invalid histogram header" );
if( !CV_IS_SPARSE_HIST(hist) )
{
CvMat mat;
cvGetMat( hist->bins, &mat, 0, 1 );
sum = cvSum( &mat ).val[0];
std::cout << "sym: " << sum << std::endl;
if( fabs(sum) < DBL_EPSILON )
sum = 1;
std::cout << "scale: " << factor/sum << std::endl;
cvScale( &mat, &mat, factor/sum, 0 );
}
else
{
CvSparseMat* mat = (CvSparseMat*)hist->bins;
CvSparseMatIterator iterator;
CvSparseNode *node;
float scale;
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
sum += *(float*)CV_NODE_VAL(mat,node);
}
std::cout << "sym: " << sum << std::endl;
if( fabs(sum) < DBL_EPSILON )
sum = 1;
scale = (float)(factor/sum);
std::cout << "scale: " << scale << std::endl;
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
*(float*)CV_NODE_VAL(mat,node) *= scale;
}
}
}
Scales computed with and without KleidiCV are the same, but result of cv_hal_convertScale is different and test fails:
[ RUN ] Imgproc_Hist_Normalize.accuracy
cvNormalizeHist call
sym: 3915.2
scale: 0.00198016
HAL convert scale call
cvNormalizeHist call
sym: 509755
scale: 1.03786e-05
HAL convert scale call
/mnt/flashdrive/opencv/modules/ts/src/ts.cpp:612: Failure
Failed
failure reason: Bad accuracy
test case #1
seed: 00000000000c5a5d
-----------------------------------
LOG:
The normalized histogram has incorrect sum =5.28961, while it should be =5.29054
test_case_idx = 1
-----------------------------------
CONSOLE: .
-----------------------------------
[ FAILED ] Imgproc_Hist_Normalize.accuracy (1 ms)
Steps to build and reproduce:
$ cmake -DWITH_KLEIDICV=ON -DKLEIDICV_SOURCE_PATH=/mnt/flashdrive/kleidicv/ ../opencv
$ make -j4 opencv_test_imgproc
$ ./bin/opencv_test_imgproc --gtest_filter=Imgproc_Hist_Normalize.accuracy
Edited by Alexander Smorkalov