1 // Copyright 2004 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 * sf.h: A video stabilizer that uses a single frame's transformation.
33 * Stabilize to the viewpoint of a single frame.
36 class sf
: public vise
{
39 sf(render
*r
, unsigned int frame
, const char *prefix
, const char *suffix
,
40 ale_real scale_factor
) : vise(r
, prefix
, suffix
, scale_factor
) {
42 fprintf(stderr
, "\n\n*** Warning: large values <x> for VISE sf:<x> are not recommended ***\n\n");
44 r
->extend_queue(frame
);
49 * Accept an image for rendering.
52 void render_frame(unsigned int frame_number
) {
54 const image
*im
= r
->get_image(frame_number
);
55 int replace
= 0; // Are image regions being replaced?
56 int replace_ex
= 0; // If image regions are being replaced, are we honoring exclusion regions?
57 unsigned int rx_count
= render::get_rx_count();
58 const filter::scaled_filter
*scf
= NULL
;
59 const exclusion
*rx_parameters
= render::get_rx_parameters();
60 int rx_show
= render::is_rx_show();
63 * Determine, for single-invariant chains, whether replacement
64 * is occurring, and, if so, determine whether we are honoring
67 if (typeid(*r
) == typeid(incremental
)
68 && ((incremental
*)r
)->get_invariant()->is_last()) {
69 scf
= ((incremental
*)r
)->get_invariant()->ssfe()->get_scaled_filter();
71 if (scf
->is_coarse() && scf
->get_filter()->support() >= 1) {
73 replace_ex
= ((incremental
*)r
)->get_invariant()->ssfe()->ex_is_honored();
78 * Generate the desired transformation.
80 transformation t
= align::of(frame_number
);
81 transformation s
= align::of(frame
);
82 unsigned int new_height
= (unsigned int)
83 floor(s
.unscaled_height() * scale_factor
);
84 unsigned int new_width
= (unsigned int)
85 floor(s
.unscaled_width() * scale_factor
);
86 s
.set_domain(new_height
, new_width
);
88 image
*rendered
= new image_ale_real(new_height
, new_width
, 3);
90 const image
*replace_image
= NULL
;
93 replace_image
= image_rw::open(frame_number
);
94 scf
->set_parameters(t
, s
, replace_image
);
97 for (unsigned int i
= 0; i
< rendered
->height(); i
++)
98 for (unsigned int j
= 0; j
< rendered
->width(); j
++) {
99 point unoffset_p
= s
.transform_scaled(point(i
, j
));
100 point p
= unoffset_p
- im
->offset();
103 if (rx_show
|| (replace
&& replace_ex
))
104 for (unsigned int param
= 0; param
< rx_count
; param
++) {
105 if (rx_parameters
[param
].type
== exclusion::RENDER
106 && unoffset_p
[0] >= rx_parameters
[param
].x
[0]
107 && unoffset_p
[0] <= rx_parameters
[param
].x
[1]
108 && unoffset_p
[1] >= rx_parameters
[param
].x
[2]
109 && unoffset_p
[1] <= rx_parameters
[param
].x
[3]
110 && frame_number
>= (unsigned) rx_parameters
[param
].x
[4]
111 && frame_number
<= (unsigned) rx_parameters
[param
].x
[5])
114 if (rx_parameters
[param
].type
== exclusion::FRAME
115 && i
>= rx_parameters
[param
].x
[0] * scale_factor
116 && i
<= rx_parameters
[param
].x
[1] * scale_factor
117 && j
>= rx_parameters
[param
].x
[2] * scale_factor
118 && j
<= rx_parameters
[param
].x
[3] * scale_factor
119 && frame_number
>= (unsigned) rx_parameters
[param
].x
[4]
120 && frame_number
<= (unsigned) rx_parameters
[param
].x
[5])
124 if (shading
< 1 && !rx_show
&& replace
&& replace_ex
)
130 scf
->filtered(i
, j
, &value
, &weight
, replace_ex
, frame_number
);
132 if (weight
.min_norm() > 0) {
133 rendered
->set_pixel(i
, j
, shading
* value
);
139 && p
[0] <= im
->height() - 1
141 && p
[1] <= im
->width() - 1)
142 rendered
->set_pixel(i
, j
, shading
* im
->get_bl(p
));
144 rendered
->set_pixel(i
, j
, pixel(0, 0, 0));
148 image_rw::close(frame_number
);
150 write_frame(rendered
, frame_number
);
156 * Report the frame lag for this stabilizer.