forked from larrylindsey/imageprocessing
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOrientationFilter.cpp
More file actions
97 lines (66 loc) · 2.21 KB
/
Copy pathOrientationFilter.cpp
File metadata and controls
97 lines (66 loc) · 2.21 KB
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
#include <cmath>
#include <vigra/convolution.hxx>
#include <vigra/functorexpression.hxx>
#include <vigra/multi_pointoperators.hxx>
#include "OrientationFilter.h"
logger::LogChannel orientationfilterlog("orientationfilterlog", "[OrientationFilter] ");
OrientationFilter::OrientationFilter(unsigned int numOrientations) :
_numOrientations(numOrientations) {
registerInput(_scale, "scale");
registerInput(_image, "image");
registerOutput(_orientations, "orientations");
}
void
OrientationFilter::updateOutputs() {
LOG_DEBUG(orientationfilterlog)
<< "updating orientations with scale " << (*_scale)
<< " and " << _numOrientations << " orientations"
<< std::endl;
int width = _image->width();
int height = _image->height();
_orientationsData.reshape(vigra::MultiArray<2, float>::size_type(width, height));
_gradX.reshape(vigra::MultiArray<2, float>::size_type(width, height));
_gradY.reshape(vigra::MultiArray<2, float>::size_type(width, height));
vigra::gaussianGradient(
srcImageRange(*_image),
destImage(_gradX),
destImage(_gradY),
*_scale);
DiscretizeOrientation discretizeOrientations(_numOrientations);
vigra::combineTwoMultiArrays(
srcMultiArrayRange(_gradX),
srcMultiArray(_gradY),
destMultiArray(_orientationsData),
discretizeOrientations);
*_orientations = _orientationsData;
}
float
OrientationFilter::DiscretizeOrientation::operator()(float gradX, float gradY) const {
float orientationX = -gradY;
float orientationY = gradX;
float mag = sqrt(orientationX*orientationX + orientationY*orientationY);
float alpha = std::asin(std::abs(orientationX)/mag);
// pointing upwards
if (orientationY < 0) {
// pointing left
if (orientationX < 0)
alpha = 2*M_PI - alpha;
// pointing downwards
} else {
// pointing right
if (orientationX >= 0) {
alpha = M_PI - alpha;
// pointing left
} else {
alpha = M_PI + alpha;
}
}
float segmentAngle = M_PI/_numOrientations;
// relevant half-circle for orientation starts at -segmentAngle/2
alpha = (alpha + segmentAngle/2);
// modulo M_PI
while (alpha > M_PI)
alpha -= M_PI;
int orientation = static_cast<int>(alpha/segmentAngle) % _numOrientations;
return 1.0/(_numOrientations + 1)*(1.0 + orientation);
}