Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_image_defo.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2002-2011 Pierre SMARS (smars@yuntech.edu.tw)
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 2 of the License, or
6  (at your option) any later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 #include "a_image_defo.h"
17 
18 #include "vtkImageCanvasSource2D.h"
19 #include "vtkImageReader2.h"
20 #include "vtkJPEGReader.h"
21 #include "vtkTIFFReader.h"
22 #include "vtkPNGReader.h"
23 #include "vtkImageWriter.h"
24 #include "vtkJPEGWriter.h"
25 #include "vtkTIFFWriter.h"
26 #include "vtkPNGWriter.h"
27 #include "vtkPointData.h"
28 #include "vtkUnsignedCharArray.h"
29 
30 //--------------Stroustroup, p.591
31 //comparisons without case
32 int cmp_nocase(const std::string& s, const std::string& s2)
33 {
34  std::string::const_iterator p = s.begin();
35  std::string::const_iterator p2 = s2.begin();
36  while (p != s.end() && p2 != s2.end())
37  {
38  if (toupper(*p) != toupper(*p2))
39  return (toupper(*p) < toupper(*p2)) ? -1 : 1;
40  ++p;
41  ++p2;
42  }
43  return (s2.size() == s.size()) ? 0 : (s.size() < s2.size()) ? -1 : 1; //size is unsigned
44 }
45 //---------------------------------------------------------------------------------
46 void a_image_defo::read(const std::string& name)
47 {
48  std::string ext = name.substr(name.find_last_of('.')+1,name.size());
49  vtkImageReader2 * in;
50  if ((cmp_nocase(ext,"tif")==0)||(cmp_nocase(ext,"tiff")==0))
51  in = (vtkImageReader2 *)vtkTIFFReader::New();
52  else if ((cmp_nocase(ext,"jpg")==0)||(cmp_nocase(ext,"jpeg")==0))
53  in = (vtkImageReader2 *)vtkJPEGReader::New();
54  else if ((cmp_nocase(ext,"png")==0)||(cmp_nocase(ext,"png")==0))
55  in = (vtkImageReader2 *)vtkPNGReader::New();
56  else return exit(-3);
57  in->SetFileName(name.c_str());
58  in->Update();
59  in_ = in->GetOutput();
60  //compute the bounding box of input and output images
61  in_->GetExtent(box_in_);
62  this->box_out_reset();
63 }
64 //---------------------------------------------------------------------------------
65 void a_image_defo::write(const std::string& name)
66 {
67  std::string ext = name.substr(name.find_last_of('.')+1,name.size());
68  vtkImageWriter * writer;
69  if ((cmp_nocase(ext,"tif")==0)||(cmp_nocase(ext,"tiff")==0))
70  writer = vtkTIFFWriter::New();
71  else if ((cmp_nocase(ext,"jpg")==0)||(cmp_nocase(ext,"jpeg")==0))
72  writer = vtkJPEGWriter::New();
73  else
74  writer = vtkPNGWriter::New();
75  writer->SetFileName(name.c_str());
76  writer->SetInputData(out_);
77  writer->Write();
78  out_->Delete();
79 }
80 //---------------------------------------------------------------------------------
82 {
83  box_out_[0] = box_out_[2] = 1000000;
84  box_out_[1] = box_out_[3] = -1000000;
85 }
86 //---------------------------------------------------------------------------------
88 {
89  int xm0 = box_out_[0];
90  int xM0 = box_out_[1];
91  int ym0 = box_out_[2];
92  int yM0 = box_out_[3];
93  this->box_out_reset();
94  //find the images of all the border points and compute the extreme values
95  int xm = box_in_[0];
96  int xM = box_in_[1];
97  int ym = box_in_[2];
98  int yM = box_in_[3];
99  for (int x=box_in_[0]; x<box_in_[1]; x++)
100  {
101  double xn0,yn0;
102  this->new_coordinates(x,ym,xn0,yn0);
103  int xn = int(round(xn0));
104  int yn = int(round(yn0));
105  if (xn<box_out_[0]) box_out_[0] = xn;
106  if (xn>box_out_[1]) box_out_[1] = xn;
107  if (yn<box_out_[2]) box_out_[2] = yn;
108  if (yn>box_out_[3]) box_out_[3] = yn;
109  this->new_coordinates(x,yM,xn0,yn0);
110  xn = int(round(xn0));
111  yn = int(round(yn0));
112  if (xn<box_out_[0]) box_out_[0] = xn;
113  if (xn>box_out_[1]) box_out_[1] = xn;
114  if (yn<box_out_[2]) box_out_[2] = yn;
115  if (yn>box_out_[3]) box_out_[3] = yn;
116  }
117  for (int y=box_in_[2]; y<box_in_[3]; y++)
118  {
119  double xn0,yn0;
120  this->new_coordinates(xm,y,xn0,yn0);
121  int xn = int(round(xn0));
122  int yn = int(round(yn0));
123  if (xn<box_out_[0]) box_out_[0] = xn;
124  if (xn>box_out_[1]) box_out_[1] = xn;
125  if (yn<box_out_[2]) box_out_[2] = yn;
126  if (yn>box_out_[3]) box_out_[3] = yn;
127  this->new_coordinates(xM,y,xn0,yn0);
128  xn = int(round(xn0));
129  yn = int(round(yn0));
130  if (xn<box_out_[0]) box_out_[0] = xn;
131  if (xn>box_out_[1]) box_out_[1] = xn;
132  if (yn<box_out_[2]) box_out_[2] = yn;
133  if (yn>box_out_[3]) box_out_[3] = yn;
134  }
135  if ((xm0!=1000000)&&(box_out_[0]<xm0)) box_out_[0] = xm0;
136  if ((xM0!=-1000000)&&(box_out_[1]>xM0)) box_out_[1] = xM0;
137  if ((ym0!=1000000)&&(box_out_[2]<ym0)) box_out_[2] = ym0;
138  if ((yM0!=-1000000)&&(box_out_[3]>yM0)) box_out_[3] = yM0;
139  double maxx = box_out_[1]-box_out_[0];
140  double maxy = box_out_[3]-box_out_[2];
141  vtkImageCanvasSource2D * out = vtkImageCanvasSource2D::New();
142  out->SetScalarTypeToUnsignedChar();
143  out->SetNumberOfScalarComponents(3);
144  out->SetExtent(0,maxx,0,maxy,0,0); // dimension of the output
145  out->SetDrawColor(0,0,0);
146  out->FillBox(0,(int)maxx,0,(int)maxy);
147  out_ = out->GetOutput();
148  out->Update();
149 }
150 //---------------------------------------------------------------------------------
152 {
153  int xm = box_out_[0];
154  int xM = box_out_[1];
155  int ym = box_out_[2];
156  int yM = box_out_[3];
157  double maxx = xM-xm;
158  double maxy = yM-ym;
159  vtkUnsignedCharArray * scal_in = (vtkUnsignedCharArray *)(in_->GetPointData()->GetScalars());
160  vtkUnsignedCharArray * scal_out = (vtkUnsignedCharArray *)(out_->GetPointData()->GetScalars());
161  double tx, ty;
162  for (int c = 0; c < 3; c++)
163  {
164  for (int y = box_out_[2]; y < box_out_[3]; y++)
165  {
166  for (int x = box_out_[0]; x < box_out_[1]; x++)
167  {
168  if (this->old_coordinates(x, y, tx, ty))
169  {
170  int tix = (int)tx;
171  int tiy = (int)ty;
172  double dx=tx-tix;
173  double dy=ty-tiy;
174  int v1 = (int)scal_in->GetComponent(tix+tiy*(box_in_[1]+1),c);
175  int v2 = (int)scal_in->GetComponent(tix+1+tiy*(box_in_[1]+1),c);
176  int v3 = (int)scal_in->GetComponent(tix+(tiy+1)*(box_in_[1]+1),c);
177  int v4 = (int)scal_in->GetComponent(tix+1+(tiy+1)*(box_in_[1]+1),c);
178  double val0 = v1+(v2-v1)*dx+(v3-v1)*dy+(v1+v4-v2-v3)*dx*dy;
179  int val= int(val0+.5);
180  int ref = (int)(x-xm)+((int)(y-ym))*((int)maxx+1);
181  scal_out->InsertComponent(ref,c,(unsigned char)val);
182  }
183  }
184  }
185  }
186 }
int cmp_nocase(const std::string &s, const std::string &s2)
void box_out_reset()
reset the value of the bounding box
virtual bool old_coordinates(double xn, double yn, double &xo, double &yo)=0
gives the pixel coordinates in the input image in function of the pixel coordinates in the output ima...
void yM(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:51
void xm(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:45
void write(const std::string &name)
write the processed image to a file
void deform()
deform the image
void xM(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:47
virtual void new_coordinates(double xo, double yo, double &xn, double &yn)=0
gives the pixel coordinates in the output image in function of the pixel coordinates in the input ima...
virtual void read(const std::string &name)
read the image to be processed
vtkImageData * out_
Definition: a_image_defo.h:60
virtual void box_out()
compute the bounding box of the new image
vtkImageData * in_
Definition: a_image_defo.h:59
void ym(const int val)
impose the size of the output bounding box
Definition: a_image_defo.h:49
int box_out_[6]
Definition: a_image_defo.h:62
int box_in_[6]
Definition: a_image_defo.h:61
double round(double val)
Definition: im2li.cxx:76
std::string name
Definition: pixelpos.cxx:77
std::istringstream in
Definition: ply2tri.cxx:32