Skip to content

Instantly share code, notes, and snippets.

@kmsquire
Last active August 29, 2015 14:06
Show Gist options
  • Save kmsquire/23b7d1c2a0ebb70ff125 to your computer and use it in GitHub Desktop.
Save kmsquire/23b7d1c2a0ebb70ff125 to your computer and use it in GitHub Desktop.
// g++-4.9 local_hist.cpp -g -I ../include -L ../bin -lHalide `libpng-config --cflags --ldflags` -lpthread -ldl -o local_hist
// LD_LIBRARY_PATH=../bin ./local_hist
#include <Halide.h>
#include <stdio.h>
using namespace Halide;
#include "image_io.h"
#include "clock.h"
int main(int argc, char **argv) {
Image<uint8_t> img = load<uint8_t>("images/gray.png");
const int bins = 32;
const int shift = int(log2f(256/bins));
const int height = img.height();
const int width = img.width();
// const int height = 10;
// const int width = 10;
const int hist_sz = 5;
const int half_hist_sz = 2;
//////////////////
Var x,y,v,xo,xi,yo,yi,vo,vi;
Expr clamped_x = clamp(x, 0, width-1);
Expr clamped_y = clamp(y, 0, height-1);
// Quantize the image
// The clamp is so halide will know the maximum number of histogram
// bins needed below. Without it, 256 bins will be created. (Or so it seems.)
Func quantized;
quantized(x,y) = clamp(img(clamped_x,clamped_y)>>shift, 0, bins-1);
// Create a level image
Func level_image("level_image");
level_image(v,x,y) = cast<uint8_t>(0);
level_image(quantized(x,y),x,y) = cast<uint8_t>(1);
// "Smart" histogram (vertical slice)
Func hist_v("hist_v");
RDom r(-half_hist_sz,hist_sz);
RDom ry(1, height-1);
hist_v(v,x,y) = cast<uint8_t>(0);
hist_v(v,x,0) = sum(level_image(v,x,r));
hist_v(v,x,ry) = hist_v(v,x,ry-1) + level_image(v,x,ry+half_hist_sz) - level_image(v,x,ry-1-half_hist_sz);
Func clamped_hist_v;
clamped_hist_v(v,x,y) = hist_v(v,clamped_x,clamped_y);
// Histogram: horizontal bin summing
Func hist("hist");
RDom rx(1,width-1);
hist(v,x,y) = cast<uint8_t>(0);
hist(v,0,y) = sum(clamped_hist_v(v,r,y));
hist(v,rx,y) = hist(v,rx-1,y) + clamped_hist_v(v,rx+half_hist_sz,y) - clamped_hist_v(v,rx-1-half_hist_sz,y);
// Schedule
// Target target = get_target_from_environment();
// if (target.has_gpu_feature()) {
// hist.compute_root().gpu_tile(x,y,64,64, GPU_Default);
// hist_v.compute_root().gpu_tile(x,y,64,64, GPU_Default);
// level_image.compute_at(hist_v, x).vectorize(v,4);
// }
// else {
hist.vectorize(v,4);
hist_v.compute_root().vectorize(v,4);
level_image.compute_at(hist_v, x).vectorize(v,4);
//quantized.vectorize(x,4);
// }
// quantized.trace_stores();
// level_image.trace_stores();
// hist_v.trace_stores();
// hist.trace_stores();
fprintf(stderr, "Start...");
double t1 = current_time();
Image<uint8_t> out(bins, width, height);
hist.realize(out);
double t2 = current_time();
printf("Time: %f\n", t2/1000);
fprintf(stderr, "done.\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment