affine.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Gxsm Plugin Name: affine.C
00006  * ========================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* Please do not change the Begin/End lines of this comment section!
00029  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00030  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00031  * All "% PlugInXXX" commentary tags are mandatory
00032  * All "% OptPlugInXXX" tags are optional
00033  * --------------------------------------------------------------------------------
00034 % BeginPlugInDocuSection
00035 % PlugInDocuCaption: Affine Transformation
00036 % PlugInName: affine
00037 % PlugInAuthor: Percy Zahl
00038 % PlugInAuthorEmail: zahl@users.sf.net
00039 % PlugInMenuPath: Math/Transformation/Affine
00040 
00041 % PlugInDescription
00042 In case you want to undo a linear distorsion of an image (e.g. slow
00043 and contineous drift/creep) this transformation helps. It applies a
00044 affine transformation to the image, e.g. two arbitrary oriented
00045 vectors (and the image) are transformed to be a orthogonal system
00046 afterwards.
00047 
00048 % PlugInUsage
00049 Use a \GxsmEmph{Ksys} to set the vectors. The relative lenght between
00050 both is ignored, they are normalized before.
00051 
00052 % OptPlugInSources
00053 The active channel is used as data source.
00054 
00055 % OptPlugInObjects
00056 A Ksys object is used for setting the two vectors.
00057 
00058 % OptPlugInDest
00059 The computation result is placed into an existing math channel, else into a new created math channel.
00060 
00061 %% OptPlugInConfig
00062 %
00063 
00064 %% OptPlugInFiles
00065 %Does it uses, needs, creates any files? Put info here!
00066 
00067 %% OptPlugInKnownBugs
00068 %
00069 
00070 % OptPlugInNotes
00071 If the image is rotated or flipped more than expected, try flipping the Ksys!
00072 I know it's a bit tricky, good ideas to fix this are welcome!
00073 
00074 %% OptPlugInHints
00075 %
00076 
00077 % EndPlugInDocuSection
00078  * -------------------------------------------------------------------------------- 
00079  */
00080 
00081 #include <gtk/gtk.h>
00082 #include "config.h"
00083 #include "gxsm/plugin.h"
00084 
00085 static void affine_init( void );
00086 static void affine_about( void );
00087 static void affine_configure( void );
00088 static void affine_cleanup( void );
00089 static gboolean affine_run( Scan *Src, Scan *Dest );
00090 
00091 GxsmPlugin affine_pi = {
00092   NULL,
00093   NULL,
00094   0,
00095   NULL,
00096   "Affine-M1S-TR",
00097   NULL,
00098   NULL,
00099   "Percy Zahl",
00100   "_Math/_Transformations/",
00101   N_("Affine"),
00102   N_("Sorry, no help for affine filter!"),
00103   "no more info",
00104   NULL,
00105   NULL,
00106   affine_init,
00107   NULL,
00108   affine_about,
00109   affine_configure,
00110   NULL,
00111   affine_cleanup
00112 };
00113 
00114 GxsmMathOneSrcPlugin affine_m1s_pi = {
00115   affine_run
00116 };
00117 
00118 static const char *about_text = N_("Gxsm Affine Plugin\n\n"
00119                                    "affine trafo.");
00120 
00121 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00122   affine_pi.description = g_strdup_printf(N_("Gxsm MathOneArg affine plugin %s"), VERSION);
00123   return &affine_pi; 
00124 }
00125 
00126 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) { 
00127   return &affine_m1s_pi; 
00128 }
00129 
00130 static void affine_init(void)
00131 {
00132   PI_DEBUG (DBG_L2, "Affine Plugin Init");
00133 }
00134 
00135 static void affine_about(void)
00136 {
00137   const gchar *authors[] = { affine_pi.authors, NULL};
00138   gtk_widget_show(gnome_about_new ( affine_pi.name,
00139                                     VERSION,
00140                                     N_("(C) 2000 the Free Software Foundation"),
00141                                     about_text,
00142                                     authors,
00143                                     NULL, NULL, NULL
00144                                     ));
00145 }
00146 
00147 static void affine_configure(void)
00148 {
00149   if(affine_pi.app)
00150     affine_pi.app->message("Affine Plugin Configuration");
00151 }
00152 
00153 static void affine_cleanup(void)
00154 {
00155   PI_DEBUG (DBG_L2, "Affine Plugin Cleanup");
00156 }
00157 
00158 static gboolean affine_run(Scan *Src, Scan *Dest)
00159 {
00160   int line, col;
00161   double trcol, trline;
00162   double f11,f12,f21,f22,n1,n2,n;
00163   double t11,t12,t21,t22,det;
00164   PI_DEBUG (DBG_L2, "Affine Transformation");
00165 
00166   if(Src->PktVal < 3){
00167     affine_pi.app->message("Please use object \"Ksys\" to define transformation!");
00168     return MATH_OK;
00169   }
00170 
00171   // Matrix F: Src --> Dest
00172   f11 = Src->Pkt2d[0].x-Src->Pkt2d[1].x;
00173   f12 = Src->Pkt2d[0].y-Src->Pkt2d[1].y;
00174   f21 = Src->Pkt2d[2].x-Src->Pkt2d[1].x;
00175   f22 = Src->Pkt2d[2].y-Src->Pkt2d[1].y;
00176 
00177   n1  = sqrt(f11*f11+f12*f12);
00178   n2  = sqrt(f21*f21+f22*f22);
00179   n   = (n1+n2)/2;
00180 
00181   f11 /= n1; f12 /= n1; f21 /= n2; f22 /= n2; // ohne "Aspekt"
00182   //f11 /= n; f12 /= n; f21 /= n; f22 /= n; // mit "Aspekt"
00183 
00184   det = f11*f22-f12*f21;
00185 
00186   if(fabs(det)>1e-5){
00187     // Matrix T: Dest --> Src
00188     t11 = f22/det; t12 = -f12/det; t21 = -f21/det; t22 = f11/det;
00189 
00190     std::cout << f11 << " " << f21 << " | " << t11  << " " << t21 << std::endl
00191          << f12 << " " << f22 << " | " << t12  << " " << t22 << std::endl
00192          << "det = " << det << std::endl;
00193 
00194     // Dest Bounds:
00195     int x00,y00,x01,y01,x10,y10,x11,y11,xmi,ymi,xmx,ymx;
00196     col=0; line=0;
00197     x00 = (int)rint((double)col*f11 + (double)line*f21);
00198     y00 = (int)rint((double)col*f12 + (double)line*f22);
00199     col=0; line=Src->mem2d->GetNy();
00200     x01 = (int)rint((double)col*f11 + (double)line*f21);
00201     y01 = (int)rint((double)col*f12 + (double)line*f22);
00202     col=Src->mem2d->GetNx(); line=0;
00203     x10 = (int)rint((double)col*f11 + (double)line*f21);
00204     y10 = (int)rint((double)col*f12 + (double)line*f22);
00205     col=Src->mem2d->GetNx(); line=Src->mem2d->GetNy();
00206     x11 = (int)rint((double)col*f11 + (double)line*f21);
00207     y11 = (int)rint((double)col*f12 + (double)line*f22);
00208 
00209     PI_DEBUG (DBG_L2, "00: " << x00 << "," << y00 << "; "
00210          << "01: " << x01 << "," << y01 << "; "
00211          << "10: " << x10 << "," << y10 << "; "
00212          << "11: " << x11 << "," << y11);
00213 
00214     xmi = MIN(MIN(MIN(x00,x01),x10),x11);
00215     xmx = MAX(MAX(MAX(x00,x01),x10),x11);
00216     ymi = MIN(MIN(MIN(y00,y01),y10),y11);
00217     ymx = MAX(MAX(MAX(y00,y01),y10),y11);
00218 
00219     // new Dest size
00220     Dest->data.s.nx = xmx-xmi+1;
00221     Dest->data.s.ny = ymx-ymi+1;
00222     Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny);
00223     
00224     // Anpassen an nächstmöglichen Wert  
00225     Dest->data.s.rx = Dest->data.s.nx*Dest->data.s.dx;
00226     Dest->data.s.ry = Dest->data.s.ny*Dest->data.s.dy;
00227 
00228     // calc SrcPkte from Dest Pos.:
00229     for(col = 0; col < Dest->data.s.nx; col++)
00230       for(line = 0; line < Dest->data.s.ny; line++){
00231         trcol  = (double)(col+xmi)*t11 + (double)(line+ymi)*t21;
00232         trline = (double)(col+xmi)*t12 + (double)(line+ymi)*t22;
00233         if(trcol >=  Src->data.s.nx)
00234           trcol= Src->data.s.nx-1;
00235         if(trcol <  0) 
00236           trcol=0;
00237         if(trline >=  Src->data.s.ny) 
00238           trline= Src->data.s.ny-1;
00239         if(trline <  0) 
00240           trline=0;
00241         Dest->mem2d->PutDataPkt(Src->mem2d->GetDataPktInterpol(trcol, trline), col, line);
00242       }
00243     return MATH_OK;
00244   }else
00245     return MATH_DIVZERO;
00246 }

Generated on Sat Apr 1 09:04:23 2006 for GXSM by  doxygen 1.4.6