1 // Copyright 2006 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * d3/focus.h: Implementation of defocusing logic.
35 double vertical_gradient
;
36 double horizontal_gradient
;
44 unsigned int sample_count
;
45 unsigned int focal_statistic
;
46 unsigned int sample_randomization
;
49 static unsigned int _uses_medians
;
50 static unsigned int _max_samples
;
51 static unsigned int camera_index
;
52 static std::vector
<std::vector
<entry
> > focus_list
;
57 double focal_distance
;
59 unsigned int sample_count
;
60 unsigned int statistic
;
61 unsigned int randomization
;
64 static void add_region(unsigned int type
, double distance
, double px
, double py
,
65 unsigned int ci
, double fr
, double ht
, double vt
, double sd
, double ed
,
66 double sx
, double ex
, double sy
, double ey
, double ap
, unsigned int sc
, unsigned int fs
,
72 if (sc
> _max_samples
)
75 if (focus_list
.size() <= ci
)
76 focus_list
.resize(ci
+ 1);
78 entry e
= { type
, distance
, px
, py
, fr
, vt
, ht
, sd
, ed
, sx
, ex
, sy
, ey
, ap
, sc
, fs
, sr
};
80 focus_list
[ci
].push_back(e
);
83 static int is_trivial() {
84 return (focus_list
.size() == 0);
87 static int uses_medians() {
91 static unsigned int max_samples() {
95 static result
get(const d2::image
*depth
, int i
, int j
) {
97 ale_pos d
= (double) depth
->get_pixel(i
, j
)[0];
99 std::vector
<entry
> *l
= &(focus_list
[camera_index
]);
102 * Initialize default focus result.
105 result r
= { d
, 0, 1, 0, 0 };
108 * Check for relevant focus regions.
111 for (unsigned int n
= 0; n
< l
->size(); n
++) {
112 entry
*e
= &((*l
)[n
]);
118 && ((d
>= -e
->end_depth
119 && d
<= -e
->start_depth
)
120 || (isnan(d
) && (isnan(e
->end_depth
)
121 || isnan(e
->start_depth
))))) {
122 d2::point focus_origin
;
123 ale_pos distance_at_focus_origin
;
127 * Distance at frame center.
129 focus_origin
= d2::point(depth
->height() / 2, depth
->width() / 2);
130 distance_at_focus_origin
= -e
->distance
;
131 } else if (e
->type
== 1) {
133 * Distance at a given point.
135 focus_origin
= d2::point(e
->py
, e
->px
);
136 distance_at_focus_origin
= (double) depth
->get_bl(d2::point(e
->py
, e
->px
))[0];
138 fprintf(stderr
, "Bad entry type.\n");
143 r
.focal_distance
= distance_at_focus_origin
+ (d2::point(i
, j
) - focus_origin
)
144 .dproduct(d2::point(-e
->vertical_gradient
,
145 -e
->horizontal_gradient
));
148 * Adjust according to focal_range.
151 ale_pos rel_dist
= (double) d
- r
.focal_distance
;
153 if (fabs(rel_dist
) < e
->focal_range
/ 2) {
154 r
.focal_distance
= d
;
155 } else if (rel_dist
> 0) {
156 r
.focal_distance
+= e
->focal_range
/ 2;
157 } else if (rel_dist
< 0) {
158 r
.focal_distance
-= e
->focal_range
/ 2;
161 r
.aperture
= e
->aperture
;
162 r
.sample_count
= e
->sample_count
;
163 r
.statistic
= e
->focal_statistic
;
164 r
.randomization
= e
->sample_randomization
;
173 static void set_camera(unsigned int c
) {