97void clipHistogram(
const std::vector<int> &hist, std::vector<int> &clippedHist,
int limit)
100 int clippedEntries = 0, clippedEntriesBefore = 0;
101 int histlength =
static_cast<int>(hist.size());
104 clippedEntriesBefore = clippedEntries;
106 for (
int i = 0; i < histlength; ++i) {
107 int d = clippedHist[i] - limit;
110 clippedHist[i] = limit;
114 int d = clippedEntries / histlength;
115 int m = clippedEntries % histlength;
116 for (
int i = 0; i < histlength; ++i) {
121 int s = (histlength - 1) / m;
122 for (
int i = s / 2; i < histlength; i += s) {
126 }
while (clippedEntries != clippedEntriesBefore);
130 std::vector<int> &hist)
132 std::fill(hist.begin(), hist.end(), 0);
134 int xMin = std::max<int>(0, blockXCenter - blockRadius);
135 int yMin = std::max<int>(0, blockYCenter - blockRadius);
136 int xMax = std::min<int>(
static_cast<int>(I.getWidth()), blockXCenter + blockRadius + 1);
137 int yMax = std::min<int>(
static_cast<int>(I.getHeight()), blockYCenter + blockRadius + 1);
139 for (
int y = yMin; y < yMax; ++y) {
140 for (
int x = xMin; x < xMax; ++x) {
141 ++hist[
fastRound((I[y][x] / 255.0f) * bins)];
146std::vector<float>
createTransfer(
const std::vector<int> &hist,
int limit, std::vector<int> &cdfs)
149 int hMin =
static_cast<int>(hist.size()) - 1;
152 bool hasNotFoundFirstNotZero =
true;
154 while ((i < stopIdx) && hasNotFoundFirstNotZero) {
157 hasNotFoundFirstNotZero =
false;
162 int hist_size =
static_cast<int>(hist.size());
163 for (
int i = hMin; i < hist_size; ++i) {
168 int cdfMin = cdfs[hMin];
169 int cdfMax = cdfs[hist.size() - 1];
171 std::vector<float> transfer(hist.size());
172 int transfer_size =
static_cast<int>(transfer.size());
173 for (
int i = 0; i < transfer_size; ++i) {
174 transfer[i] = (cdfs[i] - cdfMin) /
static_cast<float>(cdfMax - cdfMin);
246 int blockSize = (val_2 * blockRadius) + 1;
247 int limit =
static_cast<int>(((slope * blockSize * blockSize) / bins) + 0.5);
252 int cm = I1.
getWidth() - (nc * blockSize);
257 for (
int i = 0; i < nc; ++i) {
258 cs[i] = (i * blockSize) + blockRadius + 1;
263 for (
int i = 0; i < nc; ++i) {
264 cs[i] = (i * blockSize) + blockRadius + 1;
266 cs[nc] = I1.
getWidth() - blockRadius - 1;
269 cs.resize(nc + val_2);
270 cs[0] = blockRadius + 1;
271 for (
int i = 0; i < nc; ++i) {
272 cs[i + 1] = (i * blockSize) + blockRadius + 1 + (cm / val_2);
274 cs[nc + 1] = I1.
getWidth() - blockRadius - 1;
277 int rm = I1.
getHeight() - (nr * blockSize);
281 rs.resize(
static_cast<size_t>(nr));
282 for (
int i = 0; i < nr; ++i) {
283 rs[i] = (i * blockSize) + blockRadius + 1;
287 rs.resize(
static_cast<size_t>(nr + 1));
288 for (
int i = 0; i < nr; ++i) {
289 rs[i] = (i * blockSize) + blockRadius + 1;
291 rs[nr] = I1.
getHeight() - blockRadius - 1;
294 rs.resize(
static_cast<size_t>(nr + val_2));
295 rs[0] = blockRadius + 1;
296 for (
int i = 0; i < nr; ++i) {
297 rs[i + 1] = (i * blockSize) + blockRadius + 1 + (rm / val_2);
299 rs[nr + 1] = I1.
getHeight() - blockRadius - 1;
302 std::vector<int> hist(
static_cast<size_t>(bins + 1)), cdfs(
static_cast<size_t>(bins + 1));
303 std::vector<float> tl, tr, br, bl;
304 int rs_size =
static_cast<int>(rs.size());
305 for (
int r = 0; r <= rs_size; ++r) {
306 int r0 = std::max<int>(0, r - 1);
307 int r1 = std::min<int>(
static_cast<int>(rs.size()) - 1, r);
308 int dr = rs[r1] - rs[r0];
319 int yMin = (r == 0 ? 0 : rs[r0]);
320 int yMax = (r < static_cast<int>(rs.size()) ? rs[r1] : I1.
getHeight());
321 int cs_size =
static_cast<int>(cs.size());
322 for (
int c = 0; c <= cs_size; ++c) {
323 int c0 = std::max<int>(0, c - 1);
324 int c1 = std::min<int>(
static_cast<int>(cs.size()) - 1, c);
325 int dc = cs[c1] - cs[c0];
340 int xMin = (c == 0 ? 0 : cs[c0]);
341 int xMax = (c < static_cast<int>(cs.size()) ? cs[c1] : I1.
getWidth());
342 for (
int y = yMin; y < yMax; ++y) {
343 float wy =
static_cast<float>(rs[r1] - y) / dr;
344 for (
int x = xMin; x < xMax; ++x) {
345 float wx =
static_cast<float>(cs[c1] - x) / dc;
346 int v =
fastRound((I1[y][x] / 255.0f) * bins);
351 float t0 = (c0 == c1) ? t00 : ((wx * t00) + ((1.0f - wx) * t01));
352 float t1 = (c0 == c1) ? t10 : ((wx * t10) + ((1.0f - wx) * t11));
353 float t = (r0 == r1) ? t0 : ((wy * t0) + ((1.0f - wy) * t1));
354 const int maxPixelIntensity = 255;
355 I2[y][x] = std::max<unsigned char>(0, std::min<unsigned char>(maxPixelIntensity,
fastRound(t * 255.0f)));
362 std::vector<int> hist(bins + 1), prev_hist(bins + 1), clippedHist(bins + 1);
365 int xMax0 = std::min<int>(
static_cast<int>(I1.
getWidth()), blockRadius);
366 int i1_height =
static_cast<int>(I1.
getHeight());
367 for (
int y = 0; y < i1_height; ++y) {
368 int yMin = std::max<int>(0, y -
static_cast<int>(blockRadius));
369 int yMax = std::min<int>(
static_cast<int>(I1.
getHeight()), y + blockRadius + 1);
375 for (
int yi = yMin; yi < yMax; ++yi) {
376 for (
int xi = xMin0; xi < xMax0; ++xi) {
377 ++hist[
fastRound((I1[yi][xi] / 255.0f) * bins)];
385 int yMin1 = yMin - 1;
387 for (
int xi = xMin0; xi < xMax0; ++xi) {
388 --hist[
fastRound((I1[yMin1][xi] / 255.0f) * bins)];
392 if ((y + blockRadius) <
static_cast<int>(I1.
getHeight())) {
393 int yMax1 = yMax - 1;
395 for (
int xi = xMin0; xi < xMax0; ++xi) {
396 ++hist[
fastRound((I1[yMax1][xi] / 255.0f) * bins)];
402 int i1_width =
static_cast<int>(I1.
getWidth());
403 for (
int x = 0; x < i1_width; ++x) {
404 int xMin = std::max<int>(0, x -
static_cast<int>(blockRadius));
405 int xMax = x + blockRadius + 1;
408 int xMin1 = xMin - 1;
410 for (
int yi = yMin; yi < yMax; ++yi) {
411 --hist[
fastRound((I1[yi][xMin1] / 255.0f) * bins)];
415 if (xMax <=
static_cast<int>(I1.
getWidth())) {
416 int xMax1 = xMax - 1;
418 for (
int yi = yMin; yi < yMax; ++yi) {
419 ++hist[
fastRound((I1[yi][xMax1] / 255.0f) * bins)];
423 int v =
fastRound((I1[y][x] / 255.0f) * bins);
424 int w = std::min<int>(
static_cast<int>(I1.
getWidth()), xMax) - xMin;
426 int limit =
static_cast<int>(((slope * n) / bins) + 0.5f);
445 clahe(pR, resR, blockRadius, bins, slope, fast);
446 clahe(pG, resG, blockRadius, bins, slope, fast);
447 clahe(pB, resB, blockRadius, bins, slope, fast);
449 const unsigned int sizeRGBa = 4;
452 unsigned char *ptrStart =
reinterpret_cast<unsigned char *
>(I2.
bitmap);
453 unsigned char *ptrEnd = ptrStart + (size * sizeRGBa);
454 unsigned char *ptrCurrent = ptrStart;
456 unsigned int cpt = 0;
457 while (ptrCurrent != ptrEnd) {
458 *ptrCurrent = resR.
bitmap[cpt];
461 *ptrCurrent = resG.
bitmap[cpt];
464 *ptrCurrent = resB.
bitmap[cpt];
467 *ptrCurrent = pa.
bitmap[cpt];