vspline 1.1.0
Generic C++11 Code for Uniform B-Splines
channels.cc
Go to the documentation of this file.
1/************************************************************************/
2/* */
3/* vspline - a set of generic tools for creation and evaluation */
4/* of uniform b-splines */
5/* */
6/* Copyright 2016 - 2023 by Kay F. Jahnke */
7/* */
8/* Permission is hereby granted, free of charge, to any person */
9/* obtaining a copy of this software and associated documentation */
10/* files (the "Software"), to deal in the Software without */
11/* restriction, including without limitation the rights to use, */
12/* copy, modify, merge, publish, distribute, sublicense, and/or */
13/* sell copies of the Software, and to permit persons to whom the */
14/* Software is furnished to do so, subject to the following */
15/* conditions: */
16/* */
17/* The above copyright notice and this permission notice shall be */
18/* included in all copies or substantial portions of the */
19/* Software. */
20/* */
21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
23/* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
24/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
25/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
26/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
27/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
28/* OTHER DEALINGS IN THE SOFTWARE. */
29/* */
30/************************************************************************/
31
32/// \file channels.cc
33///
34/// \brief demonstrates the use of 'channel views'
35///
36/// This example is derived from 'slice.cc', we use the same volume
37/// as source data. But instead of producing an image output, we create
38/// three separate colour channels of the bspline object and assert that
39/// the evaluation of the channel views is identical with the evaluation
40/// of the 'mother' spline.
41/// For a more involved example using channel views, see ca_correct.cc
42///
43/// compile with:
44/// clang++ -std=c++11 -march=native -o channels -O3 -pthread -DUSE_VC channels.cc -lvigraimpex -lVc
45///
46/// If you don't have Vc on your system, use
47///
48/// clang++ -std=c++11 -march=native -o channels -O3 -pthread channels.cc -lvigraimpex
49/// note that the assertion at the end fails if the program is compiled
50/// with -Ofast - then the result is only near equal.
51
52#include <iostream>
53
54#include <vspline/vspline.h>
55
56#include <vigra/stdimage.hxx>
57#include <vigra/imageinfo.hxx>
58#include <vigra/impex.hxx>
59
60int main ( int argc , char * argv[] )
61{
62 // pixel_type is the result type, an RGB float pixel
63 typedef vigra::TinyVector < float , 3 > pixel_type ;
64
65 // voxel_type is the source data type
66 typedef vigra::TinyVector < float , 3 > voxel_type ;
67
68 // coordinate_type has a 3D coordinate
69 typedef vigra::TinyVector < float , 3 > coordinate_type ;
70
71 // warp_type is a 2D array of coordinates
72 typedef vigra::MultiArray < 2 , coordinate_type > warp_type ;
73
74 // target_type is a 2D array of pixels
75 typedef vigra::MultiArray < 2 , pixel_type > target_type ;
76
77 // we want a b-spline with natural boundary conditions
78 vigra::TinyVector < vspline::bc_code , 3 > bcv ( vspline::NATURAL ) ;
79
80 // create quintic 3D b-spline object containing voxels
82 space ( vigra::Shape3 ( 10 , 10 , 10 ) , 5 , bcv ) ;
83
84 // here we create the channel views. Since these are merely views
85 // to the same data, no data will be copied, and it doesn't matter
86 // whether we create these views before or after prefiltering.
87
88 auto red_channel = space.get_channel_view ( 0 ) ;
89 auto green_channel = space.get_channel_view ( 1 ) ;
90 auto blue_channel = space.get_channel_view ( 2 ) ;
91
92 // fill the b-spline's core with a three-way gradient
93
94 for ( int z = 0 ; z < 10 ; z++ )
95 {
96 for ( int y = 0 ; y < 10 ; y++ )
97 {
98 for ( int x = 0 ; x < 10 ; x++ )
99 {
100 voxel_type & c ( space.core [ vigra::Shape3 ( x , y , z ) ] ) ;
101 c[0] = 25.5 * x ;
102 c[1] = 25.5 * y ;
103 c[2] = 25.5 * z ;
104 }
105 }
106 }
107
108 // prefilter the b-spline
109 space.prefilter() ;
110
111 // now make a warp array with 1920X1080 3D coordinates
112 warp_type warp ( vigra::Shape2 ( 1920 , 1080 ) ) ;
113
114 // we want the coordinates to follow this scheme:
115 // warp(x,y) = (x,1-x,y)
116 // scaled appropriately
117
118 for ( int y = 0 ; y < 1080 ; y++ )
119 {
120 for ( int x = 0 ; x < 1920 ; x++ )
121 {
122 coordinate_type & c ( warp [ vigra::Shape2 ( x , y ) ] ) ;
123 c[0] = float ( x ) / 192.0 ;
124 c[1] = 10.0 - c[0] ;
125 c[2] = float ( y ) / 108.0 ;
126 }
127 }
128
129 // get an evaluator for the b-spline
130
132 ev_type ev ( space ) ;
133
134 // the evaluators of the channel views have their own type:
135
137
138 // we create the three evaluators for the three channel views
139
140 ch_ev_type red_ev ( red_channel ) ;
141 ch_ev_type green_ev ( green_channel ) ;
142 ch_ev_type blue_ev ( blue_channel ) ;
143
144 // and make sure the evaluation results match
145
146 // TODO: compiling with clang++, the two results are actually equal,
147 // but not with g++ - there, the results differ slightly.
148
149 for ( int y = 0 ; y < 1080 ; y++ )
150 {
151 for ( int x = 0 ; x < 1920 ; x++ )
152 {
153 coordinate_type & c ( warp [ vigra::Shape2 ( x , y ) ] ) ;
154
155 auto diff = fabs ( ev ( c ) [ 0 ] - red_ev ( c ) ) ;
156 if ( diff > 1e-4 )
157 {
158 std::cerr << "red result differs at c " << c << " "
159 << ev ( c ) [ 0 ] << " != " << red_ev ( c )
160 << std::endl ;
161 }
162 diff = fabs ( ev ( c ) [ 1 ] - green_ev ( c ) ) ;
163 if ( diff > 1e-4 )
164 {
165 std::cerr << "green result differs at c " << c << " "
166 << ev ( c ) [ 1 ] << " != " << green_ev ( c )
167 << std::endl ;
168 }
169 diff = fabs ( ev ( c ) [ 2 ] - blue_ev ( c ) ) ;
170 if ( diff > 1e-4 )
171 {
172 std::cerr << "blue result differs at c " << c << " "
173 << ev ( c ) [ 2 ] << " != " << blue_ev ( c )
174 << std::endl ;
175 }
176 }
177 }
178
179 std::cout << "success" << std::endl ;
180 exit ( 0 ) ;
181}
vigra::RGBValue< float, 0, 1, 2 > pixel_type
Definition: ca_correct.cc:103
vigra::TinyVector< float, 2 > coordinate_type
Definition: ca_correct.cc:107
vspline::evaluator< coordinate_type, float > ev_type
Definition: ca_correct.cc:121
vigra::MultiArray< 2, pixel_type > target_type
Definition: ca_correct.cc:115
int main(int argc, char *argv[])
Definition: channels.cc:60
class evaluator encodes evaluation of a spline-like object. This is a generalization of b-spline eval...
Definition: eval.h:1718
@ NATURAL
Definition: common.h:75
vigra::TinyVector< double, 3 > voxel_type
Definition: slice2.cc:62
class bspline now builds on class bspline_base, adding coefficient storage, while bspline_base provid...
Definition: bspline.h:499
view_type core
Definition: bspline.h:566
void prefilter(vspline::xlf_type boost=vspline::xlf_type(1), int njobs=vspline::default_njobs)
prefilter converts the knot point data in the 'core' area into b-spline coefficients....
Definition: bspline.h:815
channel_view_type get_channel_view(const int &channel)
get a bspline object for a single channel of the data. This is lightweight and requires the viewed da...
Definition: bspline.h:730
includes all headers from vspline (most of them indirectly)