Skip to content

Commit 1c4b8b2

Browse files
committed
Merge pull request #1613 from alalek:issue_1610
2 parents 253e1fc + 3059b16 commit 1c4b8b2

File tree

1 file changed

+38
-24
lines changed

1 file changed

+38
-24
lines changed

modules/ximgproc/src/weighted_median_filter.cpp

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,51 +55,64 @@ using namespace cv::ximgproc;
5555
void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping)
5656
{
5757
int rows = img.rows, cols = img.cols;
58-
int alls = rows * cols;
58+
size_t alls = (size_t)rows * cols;
5959

60+
CV_Assert(img.isContinuous());
6061
float *imgPtr = img.ptr<float>();
6162
typedef pair<float,int> pairFI;
62-
pairFI *data = (pairFI *)malloc(alls*sizeof(pairFI));
63+
std::vector<pairFI> data(alls);
6364

6465
// Sort all pixels of the image by ascending order of pixel value
65-
for(int i=0;i<alls;i++){
66-
data[i].second = i;
67-
data[i].first = imgPtr[i];
66+
for (size_t i = 0; i < alls; i++)
67+
{
68+
pairFI& d = data[i];
69+
d.second = i;
70+
d.first = imgPtr[i];
6871
}
69-
sort(data,data+alls);
72+
73+
struct PixelValueOrder {
74+
static bool compare(const pairFI &a, const pairFI &b) {
75+
return a.first < b.first;
76+
}
77+
};
78+
sort(data.begin(), data.end(), PixelValueOrder::compare);
7079

7180
// Find lower bound and upper bound of the pixel values
72-
double maxVal,minVal;
73-
minMaxLoc(img,&minVal,&maxVal);
74-
float maxRange = (float)(maxVal - minVal);
75-
float th = 1e-5f;
81+
double maxVal = data[alls - 1].first, minVal = data[0].first;
82+
83+
const float maxRange = (float)(maxVal - minVal);
7684

7785
float l = 0, r = maxRange*2.0f/nI;
7886
// Perform binary search on error bound
79-
while(r-l > th)
87+
while (r > l)
8088
{
81-
float m = (r+l)*0.5f;
89+
float m = (r + l) * 0.5f;
90+
if (m == r || m == l)
91+
break; // bailout on numeric accuracy limit
8292
bool suc = true;
8393
float base = (float)minVal;
84-
int cnt=0;
85-
for(int i=0;i<alls;i++)
94+
int cnt = 0;
95+
for (size_t i = 0; i < alls; i++)
8696
{
87-
if(data[i].first>base+m)
97+
if (data[i].first > base + m)
8898
{
8999
cnt++;
90100
base = data[i].first;
91-
if(cnt==nI)
101+
if (cnt == nI)
92102
{
93103
suc = false;
94104
break;
95105
}
96106
}
97107
}
98-
if(suc)r=m;
99-
else l=m;
108+
if (suc)
109+
r = m;
110+
else
111+
l = m;
100112
}
101113

102114
Mat retImg(img.size(),CV_32SC1);
115+
CV_Assert(retImg.isContinuous());
103116
int *retImgPtr = retImg.ptr<int>();
104117

105118
// 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)
108121
float base = (float)minVal;
109122
int baseI = 0;
110123
int cnt = 0;
111-
for(int i=0;i<=alls;i++)
124+
for (size_t i = 0; i < alls; i++)
112125
{
113-
if(i==alls || data[i].first>base+r)
126+
if (data[i].first > base + r)
114127
{
115128
mapping[cnt] = data[(baseI+i-1)>>1].first; //median
116-
if(i==alls)break;
117129
cnt++;
118130
base = data[i].first;
119131
baseI = i;
120132
}
121133
retImgPtr[data[i].second] = cnt;
122134
}
123-
124-
free(data);
135+
// tail: i == alls
136+
mapping[cnt] = data[(baseI+alls-1)>>1].first; // median
125137

126138
//end of the function
127-
outImg = retImg;
139+
swap(outImg, retImg);
128140
}
129141

130142
/***************************************************************/
@@ -134,6 +146,8 @@ void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping)
134146
void from32STo32F(Mat &img, Mat &outImg, float *mapping)
135147
{
136148
Mat retImg(img.size(),CV_32F);
149+
CV_Assert(img.isContinuous());
150+
CV_Assert(retImg.isContinuous());
137151
int rows = img.rows, cols = img.cols, alls = rows*cols;
138152
float *retImgPtr = retImg.ptr<float>();
139153
int *imgPtr = img.ptr<int>();

0 commit comments

Comments
 (0)