00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00069 Array *P1 = array_new( DOUBLE, 2, in->size );
00070 Array *P2 = array_new( DOUBLE, 2, in->size );
00071
00072
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
00091
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
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
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
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
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
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
00241 dx = end[0] - start[0];
00242 dy = end[1] - start[1];
00243
00244
00245 incx = sgn(dx);
00246 incy = sgn(dy);
00247 if(dx<0) dx = -dx;
00248 if(dy<0) dy = -dy;
00249
00250
00251 if (dx>dy)
00252 {
00253
00254 pdx=incx; pdy=0;
00255 ddx=incx; ddy=incy;
00256 es =dy; el =dx;
00257 } else
00258 {
00259
00260 pdx=0; pdy=incy;
00261 ddx=incx; ddy=incy;
00262 es =dx; el =dy;
00263 }
00264
00265
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
00275 for(t=1; t<=el; t++) {
00276
00277 err -= es;
00278 if(err<0) {
00279
00280 err += el;
00281
00282 x += ddx;
00283 y += ddy;
00284 } else {
00285
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
00294
00295 return out;
00296 }