• API Main Page
  • Documentation
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

src/imageproc.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2010 by Matthias Ihrke   *
00003  *   ihrke@nld.ds.mpg.de
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "imageproc.h"
00022 #include "linalg.h"
00023 
00051 Array*  disttransform_deadreckoning( const Array *in, Array *dt ){ 
00052   int x, y;
00053   int X, Y;
00054   double d1=1;
00055   double d2=sqrt(2);
00056  
00057   if( in->dtype!=INT || in->ndim!=2 ){
00058      errprintf("Need a 2-dim INT array as input\n");
00059      return NULL;
00060   }
00061   X = in->size[0];
00062   Y = in->size[1];
00063   dprintf("X,Y=%i,%i\n",X,Y);
00064   if( !dt ){
00065      dt=array_new( DOUBLE, 2, in->size );
00066   }
00067 
00068   /* tmp arrays */
00069   Array *P1 = array_new( DOUBLE, 2, in->size );
00070   Array *P2 = array_new( DOUBLE, 2, in->size );
00071 
00072   /* init */
00073   for(y=0; y<Y; y++){
00074      for(x=0; x<X; x++){
00075         mat_IDX(dt,x,y) = DBL_MAX;
00076         mat_IDX(P1,x,y)=-1;
00077         mat_IDX(P2,x,y)=-1;
00078         if(x>0 && y>0 && y<Y-1 && x<X-1){
00079           if( array_INDEX2(in,int,x-1,y)!=array_INDEX2(in,int,x,y) || 
00080                 array_INDEX2(in,int,x+1,y)!=array_INDEX2(in,int,x,y) ||
00081                 array_INDEX2(in,int,x,y-1)!=array_INDEX2(in,int,x,y) || 
00082                 array_INDEX2(in,int,x,y+1)!=array_INDEX2(in,int,x,y) ){
00083              mat_IDX(dt,x,y)=0;
00084              mat_IDX(P1,x,y)=x;
00085              mat_IDX(P2,x,y)=y;
00086           }
00087         }            
00088      }
00089   }
00090   /*-------------------- computation -----------------------*/
00091   /* first pass */
00092   for(y=1; y<Y-1; y++){
00093      for(x=1; x<X-1; x++){
00094         if( mat_IDX(dt,x-1,y-1)+d2 < mat_IDX(dt,x,y) ){
00095           mat_IDX(P1,x,y) = mat_IDX(P1,x-1,y-1);
00096           mat_IDX(P2,x,y) = mat_IDX(P2,x-1,y-1);
00097           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00098                                           SQR( y-mat_IDX(P2,x,y) ) );
00099         }
00100         if( mat_IDX(dt,x,y-1)+d1 < mat_IDX(dt,x,y) ) {
00101           mat_IDX(P1,x,y) = mat_IDX(P1,x,y-1);
00102           mat_IDX(P2,x,y) = mat_IDX(P2,x,y-1);
00103           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00104                                           SQR( y-mat_IDX(P2,x,y) ) );        
00105         }    
00106         if( mat_IDX(dt,x+1,y-1)+d2 < mat_IDX(dt,x,y) ) {
00107           mat_IDX(P1,x,y) = mat_IDX(P1,x+1,y-1);
00108           mat_IDX(P2,x,y) = mat_IDX(P2,x+1,y-1);
00109           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00110                                           SQR( y-mat_IDX(P2,x,y) ) );        
00111         }    
00112         if( mat_IDX(dt,x-1,y)+d1 < mat_IDX(dt,x,y) ) {
00113           mat_IDX(P1,x,y) = mat_IDX(P1,x-1,y);
00114           mat_IDX(P2,x,y) = mat_IDX(P2,x-1,y);
00115           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00116                                           SQR( y-mat_IDX(P2,x,y) ) );        
00117         }    
00118      }
00119   }
00120   
00121   
00122   /* final pass */
00123   for(y=Y-2; y>0; y--){
00124      for(x=X-2; x>0; x--){
00125         if( mat_IDX(dt,x+1,y)+d1 < mat_IDX(dt,x,y) ){
00126           mat_IDX(P1,x,y) = mat_IDX(P1,x+1,y);
00127           mat_IDX(P2,x,y) = mat_IDX(P2,x+1,y);
00128           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00129                                           SQR( y-mat_IDX(P2,x,y) ) );
00130         }
00131         if( mat_IDX(dt,x-1,y+1)+d2 < mat_IDX(dt,x,y) ){
00132           mat_IDX(P1,x,y) = mat_IDX(P1,x-1,y+1);
00133           mat_IDX(P2,x,y) = mat_IDX(P2,x-1,y+1);
00134           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00135                                           SQR( y-mat_IDX(P2,x,y) ) );
00136         }
00137         if( mat_IDX(dt,x,y+1)+d1 < mat_IDX(dt,x,y) ){
00138           mat_IDX(P1,x,y) = mat_IDX(P1,x,y+1);
00139           mat_IDX(P2,x,y) = mat_IDX(P2,x,y+1);
00140           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00141                                           SQR( y-mat_IDX(P2,x,y) ) );
00142         }
00143         if( mat_IDX(dt,x+1,y+1)+d2 < mat_IDX(dt,x,y) ){
00144           mat_IDX(P1,x,y) = mat_IDX(P1,x+1,y+1);
00145           mat_IDX(P2,x,y) = mat_IDX(P2,x+1,y+1);
00146           mat_IDX(dt,x,y) = sqrt( SQR( x-mat_IDX(P1,x,y) ) + 
00147                                           SQR( y-mat_IDX(P2,x,y) ) );
00148         }
00149      }
00150   }
00151   
00152 
00153   /* indicate in- and outside */
00154   for(y=Y-2; y>0; y--){
00155      for(x=X-2; x>0; x--){
00156         if( array_INDEX2(in,int,x,y)>0 ) {
00157           mat_IDX(dt,x,y) = -1*mat_IDX(dt,x,y);
00158         }
00159      }
00160   }  
00161 
00162   /* corners */
00163   mat_IDX(dt,0,  0  )=mat_IDX(dt,1,  1);
00164   mat_IDX(dt,0,  Y-1)=mat_IDX(dt,1,  Y-2);
00165   mat_IDX(dt,X-1,Y-1)=mat_IDX(dt,X-2,Y-2);
00166   mat_IDX(dt,X-1,0  )=mat_IDX(dt,X-2,1);
00167 
00168   /* borders */
00169   for(x=1; x<X-1; x++){
00170      mat_IDX(dt,x,0)   = mat_IDX(dt,x,1);
00171      mat_IDX(dt,x,Y-1) = mat_IDX(dt,x,Y-2);
00172   }
00173   for(y=1; y<Y-1; y++){
00174      mat_IDX(dt,0,y)   = mat_IDX(dt,1,y);
00175      mat_IDX(dt,X-1,y) = mat_IDX(dt,X-2,y);
00176   }
00177   /*-------------------- /computation -----------------------*/
00178 
00179   array_free( P1 );
00180   array_free( P2 );
00181 
00182   return dt;
00183 }
00184 
00197 Array*  bresenham_linesegments( const Array *points ){
00198   if( points->dtype!=INT ){
00199      errprintf("Need INT-array for coordinates\n"); return NULL;
00200   }
00201   if( points->ndim!=2 ){
00202      errprintf("Need 2D-array for coordinates\n"); return NULL;
00203   }
00204   if( points->size[1]<2 ){
00205      errprintf("Need 2 coordinates per point\n"); return NULL;
00206   }
00207 
00208   int start[2], end[2];
00209   Array *bres=NULL, *line, *tmp;
00210   int i;
00211   for( i=0; i<points->size[1]-1; i++ ){
00212      start[0]=array_INDEX2( points,int,0,i );
00213      start[1]=array_INDEX2( points,int,1,i );
00214      end[0]=array_INDEX2( points,int,0,i+1 );
00215      end[1]=array_INDEX2( points,int,1,i+1 );
00216 
00217      dprintf("(%i,%i)->(%i,%i)\n",
00218                 start[0],start[1],end[0],end[1]);
00219      line=bresenham_line( start, end );
00220      tmp=bres;
00221      bres=array_concatenate( tmp, line, DIM_COLS );
00222      array_free( tmp );
00223      array_free( line );
00224   }
00225 
00226   return bres;
00227 }
00228 
00237 Array*  bresenham_line( int start[2], int end[2] ){
00238   int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
00239 
00240   /* Entfernung in beiden Dimensionen berechnen */
00241   dx = end[0] - start[0];
00242   dy = end[1] - start[1];
00243   
00244   /* Vorzeichen des Inkrements bestimmen */
00245   incx = sgn(dx);
00246   incy = sgn(dy);
00247   if(dx<0) dx = -dx;
00248   if(dy<0) dy = -dy;
00249 
00250    /* feststellen, welche Entfernung größer ist */
00251   if (dx>dy)
00252      {
00253       /* x ist schnelle Richtung */
00254       pdx=incx; pdy=0;    /* pd. ist Parallelschritt */
00255       ddx=incx; ddy=incy; /* dd. ist Diagonalschritt */
00256       es =dy;   el =dx;   /* Fehlerschritte schnell, langsam */
00257      } else
00258      {
00259       /* y ist schnelle Richtung */
00260       pdx=0;    pdy=incy; /* pd. ist Parallelschritt */
00261       ddx=incx; ddy=incy; /* dd. ist Diagonalschritt */
00262       es =dx;   el =dy;   /* Fehlerschritte schnell, langsam */
00263      }
00264  
00265   /* Initialisierungen vor Schleifenbeginn */
00266   x = start[0];
00267   y = start[1];
00268   err = el/2;
00269 
00270   Array *out = array_new2( INT, 2, 2, el+1 );
00271 
00272   array_INDEX2(out,int,0,0)=x;
00273   array_INDEX2(out,int,1,0)=y;
00274   /*------------------ computation -------------------------*/
00275   for(t=1; t<=el; t++) {
00276      /* Aktualisierung Fehlerterm */
00277      err -= es; 
00278      if(err<0) {
00279         /* Fehlerterm wieder positiv (>=0) machen */
00280         err += el;
00281         /* Schritt in langsame Richtung, Diagonalschritt */
00282         x += ddx;
00283         y += ddy;
00284      } else  {
00285         /* Schritt in schnelle Richtung, Parallelschritt */
00286         x += pdx;
00287         y += pdy;
00288      }
00289      array_INDEX2(out,int,0,t)=x;
00290      array_INDEX2(out,int,1,t)=y;
00291   }
00292 
00293   /*------------------ /computation -------------------------*/
00294 
00295   return out;
00296 }

Generated on Fri Jun 25 2010 14:10:18 for libeegtools by  doxygen 1.7.0