My Project
image_processing/morphing.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;
array morphopen(const array& img, const array& mask)
{
return dilate(erode(img, mask), mask);
}
array morphclose(const array& img, const array& mask)
{
return erode(dilate(img, mask), mask);
}
array morphgrad(const array& img, const array& mask)
{
return (dilate(img, mask) - erode(img, mask));
}
array tophat(const array& img, const array& mask)
{
return (img - morphopen(img, mask));
}
array bottomhat(const array& img, const array& mask)
{
return (morphclose(img, mask) - img);
}
array border(const array& img, const int left, const int right,
const int top, const int bottom,
const float value = 0.0)
{
if((int)img.dims(0) < (top + bottom))
std::cerr << "input does not have enough rows" << std::endl;
if((int)img.dims(1) < (left + right))
std::cerr << "input does not have enough columns" << std::endl;
dim4 imgDims = img.dims();
array ret = constant(value, imgDims);
ret(seq(top, imgDims[0]-bottom), seq(left, imgDims[1]-right), span, span) =
img(seq(top, imgDims[0]-bottom), seq(left, imgDims[1]-right), span, span);
return ret;
}
array border(const array& img, const int w, const int h,
const float value = 0.0)
{
return border(img, w, w, h, h, value);
}
array border(const array& img, const int size, const float value = 0.0)
{
return border(img, size, size, size, size, value);
}
array blur(const array& img, const array mask = gaussianKernel(3,3))
{
array blurred = array(img.dims(), img.type());
for(int i = 0; i < (int)blurred.dims(2); i++)
blurred(span, span, i) = convolve(img(span, span, i), mask);
return blurred;
}
// Demonstrates various image morphing manipulations.
static void morphing_demo()
{
af::Window wnd(1280, 720, "Morphological Operations");
// load images
array img_rgb = loadImage(ASSETS_DIR "/examples/images/man.jpg", true) / 255.f; // 3 channel RGB [0-1]
array mask = constant(1, 5, 5);
array er = erode(img_rgb, mask);
array di = dilate(img_rgb, mask);
array op = morphopen(img_rgb, mask);
array cl = morphclose(img_rgb, mask);
array gr = morphgrad(img_rgb, mask);
array th = tophat(img_rgb, mask);
array bh = bottomhat(img_rgb, mask);
array bl = blur(img_rgb, gaussianKernel(5,5));
array bp = border(img_rgb, 20, 30, 40, 50, 0.5);
array bo = border(img_rgb, 20);
while (!wnd.close()) {
wnd.grid(3, 4);
wnd(0, 0).image(img_rgb, "Input" );
wnd(1, 0).image(er , "Erosion" );
wnd(2, 0).image(di , "Dilation" );
wnd(0, 1).image(op , "Opening" );
wnd(1, 1).image(cl , "Closing" );
wnd(2, 1).image(gr , "Gradient" );
wnd(0, 2).image(th , "TopHat" );
wnd(1, 2).image(bh , "BottomHat" );
wnd(2, 2).image(bl , "Blur" );
wnd(0, 3).image(bp , "Border to Gray" );
wnd(1, 3).image(bo , "Border to black");
wnd.show();
}
}
int main(int argc, char** argv)
{
int device = argc > 1 ? atoi(argv[1]) : 0;
try {
af::setDevice(device);
printf("** ArrayFire Image Morphing Demo **\n\n");
morphing_demo();
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
throw;
}
return 0;
}
af::dim4
Definition: dim4.hpp:31
af::seq
seq is used to create seq for indexing af::array
Definition: seq.h:44
util.h
af::info
AFAPI void info()
af::constant
array constant(T val, const dim4 &dims, const dtype ty=(af_dtype) dtype_traits< T >::ctype)
af::setDevice
AFAPI void setDevice(const int device)
Sets the current device.
af::array
A multi dimensional data container.
Definition: array.h:32
af
Definition: algorithm.h:13
af::gaussianKernel
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.
af::array::dims
dim4 dims() const
Get dimensions of the array.
af::exception
Definition: exception.h:24
af::erode
AFAPI array erode(const array &in, const array &mask)
C++ Interface for image erosion (min filter)
af::span
AFAPI seq span
af::loadImage
AFAPI array loadImage(const char *filename, const bool is_color=false)
C++ Interface for loading an image.
afcl::array
static af::array array(af::dim4 idims, cl_mem buf, af::dtype type, bool retain=false)
Create an af::array object from an OpenCL cl_mem buffer.
Definition: opencl.h:328
arrayfire.h
af::dilate
AFAPI array dilate(const array &in, const array &mask)
C++ Interface for image dilation (max filter)
af::exception::what
virtual const char * what() const
Definition: exception.h:45
af::convolve
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.
af::Window
Window object to render af::arrays.
Definition: graphics.h:36
af::array::type
dtype type() const
Get array data type.