/******************************************************* * Copyright (c) 2015, ArrayFire * All rights reserved. * * This file is distributed under 3-clause BSD license. * The complete license agreement can be obtained at: * http://arrayfire.com/licenses/BSD-3-Clause ********************************************************/ #include #include #include #include using namespace af; using std::abs; typedef enum { MEAN = 0, MEDIAN, MINMAX_AVG } LocalThresholdType; array threshold(const array &in, float thresholdValue) { int channels = in.dims(2); array ret_val = in.copy(); if (channels>1) ret_val = colorSpace(in, AF_GRAY, AF_RGB); ret_val = (ret_valthresholdValue); return ret_val; } array adaptiveThreshold(const array &in, LocalThresholdType kind, int window_size, int constnt) { int wr = window_size; array ret_val = colorSpace(in, AF_GRAY, AF_RGB); if (kind == MEAN) { array wind = constant(1, wr, wr) / (wr*wr); array mean = convolve(ret_val, wind); array diff = mean - ret_val; ret_val = (diffconstnt); } else if (kind == MEDIAN) { array medf = medfilt(ret_val, wr, wr); array diff = medf - ret_val; ret_val = (diffconstnt); } else if (kind == MINMAX_AVG) { array minf = minfilt(ret_val, wr, wr); array maxf = maxfilt(ret_val, wr, wr); array mean = (minf + maxf) / 2.0f; array diff = mean - ret_val; ret_val = (diffconstnt); } ret_val = 255.f - ret_val; return ret_val; } array iterativeThreshold(const array &in) { array ret_val = colorSpace(in, AF_GRAY, AF_RGB); float T = mean(ret_val); bool isContinue = true; while (isContinue) { array region1 = (ret_val > T)*ret_val; array region2 = (ret_val <= T)*ret_val; float r1_avg = mean(region1); float r2_avg = mean(region2); float tempT = (r1_avg + r2_avg) / 2.0f; if (abs(tempT - T)<0.01f) { break; } T = tempT; } return threshold(ret_val, T); } int main(int argc, char **argv) { try { int device = argc > 1 ? atoi(argv[1]) : 0; af::setDevice(device); af::info(); array sudoku = loadImage(ASSETS_DIR "/examples/images/sudoku.jpg", true); array mnt = adaptiveThreshold(sudoku, MEAN, 37, 10); array mdt = adaptiveThreshold(sudoku, MEDIAN, 7, 4); array mmt = adaptiveThreshold(sudoku, MINMAX_AVG, 11, 4); array itt = 255.0f - iterativeThreshold(sudoku); af::Window wnd("Adaptive Thresholding Algorithms"); std::cout << "Press ESC while the window is in focus to exit" << std::endl; while (!wnd.close()) { wnd.grid(2, 3); wnd(0, 0).image(sudoku / 255, "Input"); wnd(1, 0).image(mnt, "Adap. Threshold(Mean)"); wnd(0, 1).image(mdt, "Adap. Threshold(Median)"); wnd(1, 1).image(mmt, "Adap. Threshold(Avg. Min,Max)"); wnd(0, 2).image(itt, "Iterative Threshold"); wnd.show(); } } catch (af::exception& e) { fprintf(stderr, "%s\n", e.what()); throw; } return 0; }