My Project
image_processing/edge.cpp
/*******************************************************
* Copyright (c) 2014, 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 <stdio.h>
#include <arrayfire.h>
#include <af/util.h>
#include <cstdlib>
using namespace af;
void prewitt(array &mag, array &dir, const array &in)
{
static float h1[] = { 1, 1, 1};
static float h2[] = {-1, 0, 1};
static array colf(3, 1, h1);
static array rowf(3, 1, h2);
// Find the gradients
array Gy = convolve(rowf, colf, in);
array Gx = convolve(colf, rowf, in);
// Find magnitude and direction
mag = hypot(Gx, Gy);
dir = atan2(Gy, Gx);
}
void sobelFilter(array &mag, array &dir, const array &in)
{
array Gx, Gy;
sobel(Gx, Gy, in, 3);
// Find magnitude and direction
mag = hypot(Gx, Gy);
dir = atan2(Gy, Gx);
}
array normalize(const array &in)
{
float mx = max<float>(in);
float mn = min<float>(in);
return (in-mn)/(mx-mn);
}
array edge(const array &in, int method = 0)
{
int w = 5;
if (in.dims(0) < 512) w = 3;
if (in.dims(0) > 2048) w = 7;
int h = 5;
if (in.dims(0) < 512) h = 3;
if (in.dims(0) > 2048) h = 7;
array ker = gaussianKernel(w, h);
array smooth = convolve(in, ker);
array mag, dir;
switch(method) {
case 1: prewitt(mag, dir, smooth); break;
case 2: sobelFilter(mag, dir, smooth); break;
default: throw af::exception("Unsupported type");
}
return normalize(mag);
}
void edge()
{
af::Window myWindow("Edge Dectectors");
af::Window myWindow2(512, 512, "Histogram");
array in = loadImage(ASSETS_DIR "/examples/images/trees_ctm.jpg", false);
array prewitt = edge(in, 1);
array sobelFilter = edge(in, 2);
array hst = histogram(in, 256, 0, 255);
while(!myWindow.close() && !myWindow2.close()) {
/* show input, prewitt and sobel edge detectors in a grid */
myWindow.grid(2, 2);
myWindow(0,0).image(in/255 , "Input Image");
myWindow(0,1).image(prewitt , "Prewitt" );
myWindow(1,0).image(sobelFilter, "Sobel" );
myWindow.show();
/* show histogram on input in separate window */
myWindow2.hist(hst, 0, 255);
}
}
int main(int argc, char* argv[])
{
int device = argc > 1 ? atoi(argv[1]) : 0;
try {
af::setDevice(device);
printf("** ArrayFire Edge Detection Demo **\n");
edge();
} catch (af::exception &e) {
fprintf(stderr, "%s\n", e.what());
throw;
}
return 0;
}
Window object to render af::arrays.
Definition: graphics.h:37
A multi dimensional data container.
Definition: array.h:27
Definition: exception.h:20
virtual const char * what() const
Definition: exception.h:34
AFAPI array atan2(const array &lhs, const array &rhs)
C++ Interface for arc tan of two arrays.
AFAPI array hypot(const array &lhs, const array &rhs)
C++ Interface for getting length of hypotenuse of two inputs.
AFAPI void info()
AFAPI void setDevice(const int device)
Sets the current device.
AFAPI array gaussianKernel(const int rows, const int cols, const double sig_r=0, const double sig_c=0)
C++ Interface for generating gausian kernels.
AFAPI array histogram(const array &in, const unsigned nbins, const double minval, const double maxval)
C++ Interface for histogram.
AFAPI void sobel(array &dx, array &dy, const array &img, const unsigned ker_size=3)
C++ Interface for extracting sobel gradients.
AFAPI array loadImage(const char *filename, const bool is_color=false)
C++ Interface for loading an image.
dim4 dims() const
Get dimensions of the array.
AFAPI array convolve(const array &signal, const array &filter, const convMode mode=AF_CONV_DEFAULT, const convDomain domain=AF_CONV_AUTO)
C++ Interface for convolution any(one through three) dimensional signals.
Definition: algorithm.h:15