-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Wrong implementation of balanceWhiteSimple #2260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Could you please inject some debug printing after problematic code blocks to verify that histogram is wrong for some simple synthetic images? Probably we should add more synthetic tests for several different image types and corner cases instead of "comparison with gold" test case. |
// simple_color_balance.cpp: line 67
int nElements = int(pow((float)bins, (float)depth));
// simple_color_balance.cpp: line 72
std::vector<int> hist(nElements, 0); Actually from the code above we know that the number of nodes of the tree is less than what we expect (the tree should be of (bins^(depth+1)-bins)/(bins-1) nodes)... So we could not even give a ground truth for If we correct Mat test = Mat::zeros(4,1,CV_8UC1);
test.at<uchar>(0, 0) = 0;
test.at<uchar>(1, 0) = 1;
test.at<uchar>(2, 0) = 16;
test.at<uchar>(3, 0) = 255;
cv::Ptr<cv::xphoto::SimpleWB> wb = cv::xphoto::createSimpleWB();
wb->setInputMin(0);
wb->setInputMax(255);
wb->setOutputMin(0);
wb->setOutputMax(255);
wb->balanceWhite(test, test);
/*
output hist (16 items per line):
3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
expected hist:
2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
*/ BTW, the debug printing is inserted to simple_color_balance.cpp: line 100 printf("hist:\n");
for (int j = 0; j < nElements; j++)
{
printf("%d ", hist[j]);
if((j + 1) % 16 == 0) printf("\n");
} |
We should try an fix it then. I think problematic test should be replaced with several synthetic tests verifying algorithm behavior. If you're going to create a pull request, please target it to branch 3.4, we will merge it to master by ourselves. BTW, can we use |
A pull request has been created as #2263 . |
Related file
On master branch of opencv_contrib (20190912):
opencv_contrib/modules/xphoto/src/simple_color_balance.cpp
Description
The algorithm uses a histogram tree to accelerate calculation. However, it seems that there is something wrong with it.
Take a tree of depth = 2 and bins = 16 for example. We number the nodes on the 1st level 0~15, and nodes on the 2nd level 16~(16+255). The nodes on the 1st level of the tree should store the partial sum of values of nodes on the 2nd level. e.g. node 0 contains the sum of values of node 16~31, and node 1 contains the sum of values of node 32~47.
But in this implementation I found mistakes. For example, let pos = 0 and currentBin = 0(i.e. val == minValue), we can see that hist[0] will increase by 1 twice no matter j = 0 or j = 1, which is obviously not what we expected. We expect it to update level 1 when j = 0, and update level 2 when j = 1.
There is the same mistake in the code below.
Question
I'm working to fix it, but I found that the fixed code won't pass the tests. Would you kindly tell me whether the ground truth is generated by the current implementation? If that's true, may I replace it with a new one generated by my fixed implementation?
The text was updated successfully, but these errors were encountered: