#include <stdio.h>
#include <string.h>
#include <float.h>
#include <arrayfire.h>
using namespace af;
#include "ppm_utils.h"
int width = 1366, height = 768;
const int padding = 10;
const int window = 32;
const int HISTOGRAM_BINS = 256;
const float sum_thresh = window * window * 0.33;
const float sal_div = 1.5;
array g_src_img, g_sub_imgs, g_out_img;
array g_rowpos, g_colpos;
float* m_rowpos, *m_colpos;
int nwindows;
static void gpu(array& g_chipImg, bool console) {
array gfidx = array(seq(window));
array sums = zeros(HISTOGRAM_BINS, nwindows);
array binSizes = zeros(nwindows);
array mmp = zeros(nwindows, c32);
gfor(array i, nwindows) {
array rr = g_rowpos(i) + gfidx;
array cc = g_colpos(i) + gfidx;
array subwin = g_chipImg(rr, cc);
array hists = histogram(subwin, HISTOGRAM_BINS);
sums(span, i) = accum(hists, 0);
mmp(i) = minmax_packed(flat(subwin));
binSizes(i) = (imag(mmp(i)) - real(mmp(i)) + FLT_MIN) / HISTOGRAM_BINS;
}
array val, idx;
array df = (sums - sum_thresh) < 0;
af::min(val, idx, df);
array wthresh = idx;
gfor(array i, nwindows) {
array rr = g_rowpos(i) + gfidx;
array cc = g_colpos(i) + gfidx;
array oldsub = g_chipImg(rr, cc);
wthresh(i) = mul(wthresh(i) , binSizes(i)) + real(mmp(i));
array newsub = mul((oldsub >= wthresh(i)) , imag(mmp(i))) + real(mmp(i));
g_sub_imgs(span, span, i) = newsub;
}
gfor(array i, nwindows) {
array rr = g_rowpos(i) + gfidx;
array cc = g_colpos(i) + gfidx;
g_out_img(rr, cc) = g_sub_imgs(span, span, i);
}
if (!console) {
subfigure(2, 2, 4); imgplot(g_out_img); title("3. region processed");
}
}
const float h_avg_kernel[] = { 1.0 / 12.0, 2.0 / 12.0, 1.0 / 12.0,
2.0 / 12.0, 0.0 , 2.0 / 12.0,
1.0 / 12.0, 2.0 / 12.0, 1.1 / 12.0
};
array avg_k = array(3, 3, h_avg_kernel);
static void run(bool console)
{
array Ig = 255 * load_gray_ppm("pattern.ppm");
float scale = 1.0;
Ig = resize(Ig, scale);
width *= scale; height *= scale;
printf("%dx%d\n", width, height);
if (!console) {
palette("gray");
subfigure(2, 2, 1); imgplot(Ig); title("1. input");
}
array blur1 = filter(Ig, avg_k);
array blur2 = filter(blur1, avg_k);
array Is = mul((Ig - blur2) , (Ig >= blur2));
Is = filter(Is, avg_k);
if (!console) {
subfigure(2, 2, 2); imgplot(convert(Is, f32)); title("2. blurred diff");
}
float mx = max<float>(flat(Is));
array Ib = (Is >= (mx / sal_div));
if (!console) {
subfigure(2, 2, 3); imgplot(convert(morph(Ib, AF_BW_Dilate), f32)); title("3. salient areas");
}
nwindows = count(flat(Ib));
printf("nwindows: %d\n", nwindows);
m_rowpos = (float*)malloc(nwindows * sizeof(*m_rowpos));
m_colpos = (float*)malloc(nwindows * sizeof(*m_colpos));
bool *h_ib = Ib.host<bool>();
int ii = 0;
for (unsigned x = padding; x < Ib.dims()[1] - padding; ++x) {
for (unsigned y = padding; y < Ib.dims()[0] - padding; ++y) {
if (h_ib[x*height+y]) {
m_rowpos[ii] = y;
m_colpos[ii] = x;
++ii;
}
}
}
nwindows = ii;
printf("nwindows: %d\n", nwindows);
g_sub_imgs = zeros(window, window, nwindows);
g_out_img = zeros(height, width);
g_rowpos = array(nwindows, m_rowpos); free(m_rowpos);
g_colpos = array(nwindows, m_colpos); free(m_colpos);
g_src_img = Ig;
gpu(g_src_img, console);
}
int main(int argc, char **argv)
{
bool console = false;
if ( argc > 2 || (argc == 2 && strcmp(argv[1],"-")) ){
printf("Usage: gfor_hist_demo [-]\n");
return -1;
} else if (argc == 2 && !strcmp(argv[1],"-")) {
console = true;
}
try {
run(console);
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
#ifdef WIN32 // pause in Windows
if (!console) {
printf("hit [enter]...");
getchar();
}
#endif
return 0;
}