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:
* https://arrayfire.com/licenses/BSD-3-Clause
********************************************************/
#include <arrayfire.h>
#include <stdio.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))
printf("input does not have enough rows\n");
if ((int)img.dims(1) < (left + right))
fprintf(stderr, "input does not have enough columns\n");
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
Generic object that represents size and shape.
Definition: dim4.hpp:33
af::seq
seq is used to create sequences for indexing af::array
Definition: seq.h:46
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:35
af
Definition: algorithm.h:15
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.
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:327
af::exception
An ArrayFire exception class.
Definition: exception.h:29
af::erode
AFAPI array erode(const array &in, const array &mask)
C++ Interface for image erosion (min filter)
af::span
AFAPI seq span
A special value representing the entire axis of an af::array.
af::array::dims
dim4 dims() const
Get dimensions of the array.
af::loadImage
AFAPI array loadImage(const char *filename, const bool is_color=false)
C++ Interface for loading an image.
arrayfire.h
af::array::type
dtype type() const
Get array data type.
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
Returns an error message for the exception in a string format.
Definition: exception.h:60
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:37