1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*******************************************************
* 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 <string.h>
#include <stdio.h>
#include <math.h>
#include <arrayfire.h>
#include "../common/progress.h"
using namespace af;
const float h_sx_kernel[] = { 1, 2, 1,
0, 0, 0,
-1, -2, -1
};
const float h_sy_kernel[] = { -1, 0, 1,
-2, 0, 2,
-1, 0, 1
};
// Unused
//const float h_lp_kernel[] = { -0.5f, -1.0f, -0.5f,
// -1.0f, 6.0f, -1.0f,
// -0.5f, -1.0f, -0.5f
//};
array edges_slice(array x)
{
array ret;
static array kernelx = array(dim4(3, 3), h_sx_kernel);
static array kernely = array(dim4(3, 3), h_sy_kernel);
ret = convolve(x, kernelx) + convolve(x, kernely);
return abs(ret);
}
array gauss(array x, float u, float s)
{
double f = 1 / sqrt(2 * af::Pi * s * s);
array e = exp(-pow((x - u), 2) / (2 * s * s));
return f * e;
}
array segment_volume(array A, int k)
{
array I1 = A(span, span, k);
float mx = max<float>(I1);
float mn = min<float>(I1);
float u0 = 0.9 * mx;
float s0 = (mx - mn) / 2;
float u1 = 1.1 * mn;
float s1 = (mx - mn) / 2;
array L0 = gauss(I1, u0, s0);
array L11 = gauss(I1, u1, s1);
array L10;
array L12;
static array kernel = constant(1, 3, 3) / 9;
static array L11_old;
static array L12_old;
if (k == 0) {
L11 = convolve(L11, kernel);
L10 = L11;
} else {
L10 = L11_old;
L11 = L12_old;
}
if (k < A.dims(2) - 1) {
L12 = gauss(A(span, span, k + 1), u1, s1);
L12 = convolve(L12, kernel);
} else {
L12 = L11;
}
L11_old = L11;
L12_old = L12;
array L1 = (L10 + L11 + L12) / 3;
array S = (L0 > L1);
return S.as(A.type());
}
void brain_seg(bool console)
{
af::Window wnd("Brain Segmentation Demo");
wnd.setColorMap(AF_COLORMAP_HEAT);
double time_total = 30; // run for N seconds
array B = loadImage(ASSETS_DIR "/examples/images/brain.png");
int slices = 256;
B = moddims(B, dim4(B.dims(0), B.dims(1)/slices, slices));
af::sync();
int N = 2 * slices - 1;
timer t = timer::start();
int iter = 0;
/* loop forward and backward for 100 frames
* exit if the user presses escape or the animation
* ends
*/
for (int i = 0; !wnd.close(); i++) {
iter++;
int j = i % N;
int k = std::min(j, N - j);
array Bi = B(span, span, k);
/* process */
array Si = segment_volume(B, k);
array Ei = edges_slice(Si);
array Mi = meanShift(Bi, 10, 10, 5);
/* visualization */
if (!console) {
wnd.grid(2, 2);
wnd(0, 0).image(Bi/255.f, "Input");
wnd(1, 0).image(Ei, "Edges");
wnd(0, 1).image(Mi/255.f, "Meanshift");
wnd(1, 1).image(Si, "Segmented");
wnd.show();
} else {
/* sync the operations so that current
* iteration comptation finishes
* */
af::sync();
}
/* we have had ran throuh simlation results
* exit the rendering loop */
if (!progress(iter, t, time_total))
break;
if (!(i<100*N))
break;
}
}
int main(int argc, char* argv[])
{
int device = argc > 1 ? atoi(argv[1]) : 0;
bool console = argc > 2 ? argv[2][0] == '-' : false;
try {
af::setDevice(device);
af::info();
printf("Brain segmentation example\n");
brain_seg(console);
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
return 0;
}
|