Commit 1c4b8b2f authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #1613 from alalek:issue_1610

parents 253e1fc3 3059b16a
...@@ -55,51 +55,64 @@ using namespace cv::ximgproc; ...@@ -55,51 +55,64 @@ using namespace cv::ximgproc;
void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping) void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping)
{ {
int rows = img.rows, cols = img.cols; int rows = img.rows, cols = img.cols;
int alls = rows * cols; size_t alls = (size_t)rows * cols;
CV_Assert(img.isContinuous());
float *imgPtr = img.ptr<float>(); float *imgPtr = img.ptr<float>();
typedef pair<float,int> pairFI; typedef pair<float,int> pairFI;
pairFI *data = (pairFI *)malloc(alls*sizeof(pairFI)); std::vector<pairFI> data(alls);
// Sort all pixels of the image by ascending order of pixel value // Sort all pixels of the image by ascending order of pixel value
for(int i=0;i<alls;i++){ for (size_t i = 0; i < alls; i++)
data[i].second = i; {
data[i].first = imgPtr[i]; pairFI& d = data[i];
d.second = i;
d.first = imgPtr[i];
} }
sort(data,data+alls);
struct PixelValueOrder {
static bool compare(const pairFI &a, const pairFI &b) {
return a.first < b.first;
}
};
sort(data.begin(), data.end(), PixelValueOrder::compare);
// Find lower bound and upper bound of the pixel values // Find lower bound and upper bound of the pixel values
double maxVal,minVal; double maxVal = data[alls - 1].first, minVal = data[0].first;
minMaxLoc(img,&minVal,&maxVal);
float maxRange = (float)(maxVal - minVal); const float maxRange = (float)(maxVal - minVal);
float th = 1e-5f;
float l = 0, r = maxRange*2.0f/nI; float l = 0, r = maxRange*2.0f/nI;
// Perform binary search on error bound // Perform binary search on error bound
while(r-l > th) while (r > l)
{ {
float m = (r+l)*0.5f; float m = (r + l) * 0.5f;
if (m == r || m == l)
break; // bailout on numeric accuracy limit
bool suc = true; bool suc = true;
float base = (float)minVal; float base = (float)minVal;
int cnt=0; int cnt = 0;
for(int i=0;i<alls;i++) for (size_t i = 0; i < alls; i++)
{ {
if(data[i].first>base+m) if (data[i].first > base + m)
{ {
cnt++; cnt++;
base = data[i].first; base = data[i].first;
if(cnt==nI) if (cnt == nI)
{ {
suc = false; suc = false;
break; break;
} }
} }
} }
if(suc)r=m; if (suc)
else l=m; r = m;
else
l = m;
} }
Mat retImg(img.size(),CV_32SC1); Mat retImg(img.size(),CV_32SC1);
CV_Assert(retImg.isContinuous());
int *retImgPtr = retImg.ptr<int>(); int *retImgPtr = retImg.ptr<int>();
// In the sorted list, divide pixel values into clusters according to the minimum error bound // In the sorted list, divide pixel values into clusters according to the minimum error bound
...@@ -108,23 +121,22 @@ void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping) ...@@ -108,23 +121,22 @@ void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping)
float base = (float)minVal; float base = (float)minVal;
int baseI = 0; int baseI = 0;
int cnt = 0; int cnt = 0;
for(int i=0;i<=alls;i++) for (size_t i = 0; i < alls; i++)
{ {
if(i==alls || data[i].first>base+r) if (data[i].first > base + r)
{ {
mapping[cnt] = data[(baseI+i-1)>>1].first; //median mapping[cnt] = data[(baseI+i-1)>>1].first; //median
if(i==alls)break;
cnt++; cnt++;
base = data[i].first; base = data[i].first;
baseI = i; baseI = i;
} }
retImgPtr[data[i].second] = cnt; retImgPtr[data[i].second] = cnt;
} }
// tail: i == alls
free(data); mapping[cnt] = data[(baseI+alls-1)>>1].first; // median
//end of the function //end of the function
outImg = retImg; swap(outImg, retImg);
} }
/***************************************************************/ /***************************************************************/
...@@ -134,6 +146,8 @@ void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping) ...@@ -134,6 +146,8 @@ void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping)
void from32STo32F(Mat &img, Mat &outImg, float *mapping) void from32STo32F(Mat &img, Mat &outImg, float *mapping)
{ {
Mat retImg(img.size(),CV_32F); Mat retImg(img.size(),CV_32F);
CV_Assert(img.isContinuous());
CV_Assert(retImg.isContinuous());
int rows = img.rows, cols = img.cols, alls = rows*cols; int rows = img.rows, cols = img.cols, alls = rows*cols;
float *retImgPtr = retImg.ptr<float>(); float *retImgPtr = retImg.ptr<float>();
int *imgPtr = img.ptr<int>(); int *imgPtr = img.ptr<int>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment