@@ -55,51 +55,64 @@ using namespace cv::ximgproc;
55
55
void from32FTo32S (Mat &img, Mat &outImg, int nI, float *mapping)
56
56
{
57
57
int rows = img.rows , cols = img.cols ;
58
- int alls = rows * cols;
58
+ size_t alls = ( size_t ) rows * cols;
59
59
60
+ CV_Assert (img.isContinuous ());
60
61
float *imgPtr = img.ptr <float >();
61
62
typedef pair<float ,int > pairFI;
62
- pairFI * data = (pairFI *) malloc ( alls* sizeof (pairFI) );
63
+ std::vector< pairFI> data ( alls);
63
64
64
65
// 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];
68
71
}
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);
70
79
71
80
// 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);
76
84
77
85
float l = 0 , r = maxRange*2 .0f /nI;
78
86
// Perform binary search on error bound
79
- while (r-l > th )
87
+ while (r > l )
80
88
{
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
82
92
bool suc = true ;
83
93
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++)
86
96
{
87
- if (data[i].first > base+ m)
97
+ if (data[i].first > base + m)
88
98
{
89
99
cnt++;
90
100
base = data[i].first ;
91
- if (cnt== nI)
101
+ if (cnt == nI)
92
102
{
93
103
suc = false ;
94
104
break ;
95
105
}
96
106
}
97
107
}
98
- if (suc)r=m;
99
- else l=m;
108
+ if (suc)
109
+ r = m;
110
+ else
111
+ l = m;
100
112
}
101
113
102
114
Mat retImg (img.size (),CV_32SC1);
115
+ CV_Assert (retImg.isContinuous ());
103
116
int *retImgPtr = retImg.ptr <int >();
104
117
105
118
// 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
121
float base = (float )minVal;
109
122
int baseI = 0 ;
110
123
int cnt = 0 ;
111
- for ( int i= 0 ;i<= alls;i++)
124
+ for ( size_t i = 0 ; i < alls; i++)
112
125
{
113
- if (i==alls || data[i].first > base+ r)
126
+ if ( data[i].first > base + r)
114
127
{
115
128
mapping[cnt] = data[(baseI+i-1 )>>1 ].first ; // median
116
- if (i==alls)break ;
117
129
cnt++;
118
130
base = data[i].first ;
119
131
baseI = i;
120
132
}
121
133
retImgPtr[data[i].second ] = cnt;
122
134
}
123
-
124
- free ( data);
135
+ // tail: i == alls
136
+ mapping[cnt] = data[(baseI+alls- 1 )>> 1 ]. first ; // median
125
137
126
138
// end of the function
127
- outImg = retImg;
139
+ swap ( outImg, retImg) ;
128
140
}
129
141
130
142
/* **************************************************************/
@@ -134,6 +146,8 @@ void from32FTo32S(Mat &img, Mat &outImg, int nI, float *mapping)
134
146
void from32STo32F (Mat &img, Mat &outImg, float *mapping)
135
147
{
136
148
Mat retImg (img.size (),CV_32F);
149
+ CV_Assert (img.isContinuous ());
150
+ CV_Assert (retImg.isContinuous ());
137
151
int rows = img.rows , cols = img.cols , alls = rows*cols;
138
152
float *retImgPtr = retImg.ptr <float >();
139
153
int *imgPtr = img.ptr <int >();
0 commit comments