Skip to content

Commit ffc4786

Browse files
author
Pradeep
committed
FEATURE: histogram equalization for images
1 parent 35f1cb2 commit ffc4786

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

include/af/image.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ AFAPI array rgb2gray(const array& in, const float rPercent=0.2126f, const float
7272

7373
AFAPI array gray2rgb(const array& in, const float rFactor=1.0, const float gFactor=1.0, const float bFactor=1.0);
7474

75+
AFAPI array histequal(const array& in, const array& hist);
76+
7577
}
7678
#endif
7779

@@ -151,6 +153,8 @@ extern "C" {
151153

152154
AFAPI af_err af_gray2rgb(af_array* out, const af_array in, const float rFactor, const float gFactor, const float bFactor);
153155

156+
AFAPI af_err af_histequal(af_array *out, const af_array in, const af_array hist);
157+
154158
#ifdef __cplusplus
155159
}
156160
#endif

src/api/c/histeq.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*******************************************************
2+
* Copyright (c) 2014, ArrayFire
3+
* All rights reserved.
4+
*
5+
* This file is distributed under 3-clause BSD license.
6+
* The complete license agreement can be obtained at:
7+
* http://arrayfire.com/licenses/BSD-3-Clause
8+
********************************************************/
9+
10+
#include <af/image.h>
11+
#include <af/index.h>
12+
#include <af/defines.h>
13+
#include <err_common.hpp>
14+
#include <handle.hpp>
15+
#include <backend.hpp>
16+
#include <cast.hpp>
17+
#include <scan.hpp>
18+
#include <arith.hpp>
19+
#include <reduce.hpp>
20+
#include <ArrayIndex.hpp>
21+
22+
using namespace detail;
23+
24+
template<typename T, typename hType>
25+
static af_array histequal(const af_array& in, const af_array& hist)
26+
{
27+
const Array<T> input = getArray<T>(in);
28+
29+
af_array vInput = 0;
30+
AF_CHECK(af_flat(&vInput, in));
31+
32+
Array<float>* fHist = cast<float>(getArray<hType>(hist));
33+
34+
dim4 hDims = fHist->dims();
35+
dim_type grayLevels = fHist->elements();
36+
37+
Array<float>* cdf = detail::scan<af_add_t, float, float>(*fHist, 0);
38+
39+
float minCdf = detail::reduce_all<af_min_t, float, float>(*cdf);
40+
float maxCdf = detail::reduce_all<af_max_t, float, float>(*cdf);
41+
float factor = (float)(grayLevels-1)/(maxCdf - minCdf);
42+
43+
// constant array of min value from cdf
44+
Array<float>* minCnst = createValueArray<float>(hDims, minCdf);
45+
// constant array of factor variable
46+
Array<float>* facCnst = createValueArray<float>(hDims, factor);
47+
// cdf(i) - min for all elements
48+
Array<float>* diff = detail::arithOp<float, af_sub_t>(*cdf, *minCnst, hDims);
49+
// multiply factor with difference
50+
Array<float>* normCdf = detail::arithOp<float, af_mul_t>(*diff, *facCnst, hDims);
51+
// index input array with normalized cdf array
52+
Array<float>* idxArr = detail::arrayIndex<float, T>(*normCdf, getArray<T>(vInput), 0);
53+
54+
Array<T>* result = cast<T>(*idxArr);
55+
56+
destroyArray<float>(*idxArr);
57+
destroyArray<float>(*normCdf);
58+
destroyArray<float>(*diff);
59+
destroyArray<float>(*facCnst);
60+
destroyArray<float>(*minCnst);
61+
destroyArray<float>(*cdf);
62+
destroyArray<float>(*fHist);
63+
AF_CHECK(af_destroy_array(vInput));
64+
65+
return getHandle<T>(*result);
66+
}
67+
68+
af_err af_histequal(af_array *out, const af_array in, const af_array hist)
69+
{
70+
try {
71+
ArrayInfo dataInfo = getInfo(in);
72+
ArrayInfo histInfo = getInfo(hist);
73+
74+
af_dtype dataType = dataInfo.getType();
75+
af::dim4 histDims = histInfo.dims();
76+
77+
ARG_ASSERT(2, (histDims.ndims()==1));
78+
79+
af_array output = 0;
80+
switch(dataType) {
81+
case f64: output = histequal<double, uint>(in, hist); break;
82+
case f32: output = histequal<float , uint>(in, hist); break;
83+
case s32: output = histequal<int , uint>(in, hist); break;
84+
case u32: output = histequal<uint , uint>(in, hist); break;
85+
case u8 : output = histequal<uchar , uint>(in, hist); break;
86+
default : TYPE_ERROR(1, dataType);
87+
}
88+
std::swap(*out,output);
89+
}
90+
CATCHALL;
91+
92+
return AF_SUCCESS;
93+
}

src/api/cpp/histogram.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,11 @@ array histogram(const array &in, const unsigned nbins)
2828
return array(out);
2929
}
3030

31+
array histequal(const array& in, const array& hist)
32+
{
33+
af_array temp = 0;
34+
AF_THROW(af_histequal(&temp, in.get(), hist.get()));
35+
return array(temp);
36+
}
37+
3138
}

0 commit comments

Comments
 (0)