⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ami_snake.h

📁 ami_snake算法源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
	     l2=uy2+uy2-ux2+uxuy;	     l2+=l2;	     l3=uxuy+ux2;	     l4=ux2-uxuy-uxuy-uxuy;	   }       }       /* CALCULAMOS EL INCREMENTO PARA PASAR DE UNA ITERACION A LA SIGUIENTE */       paso=l0*imagen_level_set[m] + 0.25*((imagen_level_set[m+width2]+imagen_level_set[m-width2])*l1 +             (imagen_level_set[m+1]+imagen_level_set[m-1])*l2 + (imagen_level_set[m+width2+1]+imagen_level_set[m-width2-1])*l3 +             (imagen_level_set[m+width2-1]+imagen_level_set[m-width2+1])*l4);       paso/=(ux2+uy2);      /* DISCRETIZAMOS EL TERMINO DE REACCION. TOMAMOS EL GRADIENTE DE u SIGUIENDO LA         DIRECCION DEL FLUJO */      if(imagen_g_x[m]<0) uxg=imagen_level_set[m+1]-imagen_level_set[m];      else uxg=imagen_level_set[m]-imagen_level_set[m-1];      if(imagen_g_y[m]>0) uyg=imagen_level_set[m+width2]-imagen_level_set[m];      else uyg=imagen_level_set[m]-imagen_level_set[m-width2];      /* ACTUALIZAMOS EL VALOR DEL PIXEL */      paso=imagen_g[m]*paso-lambda*(imagen_g_x[m]*uxg-imagen_g_y[m]*uyg);      imagen_paso[m]=imagen_level_set[m]+paso*dt;      /* ACTUALIZAMOS EL ERROR */      if(ami_abs(paso)>error_max) error_max=ami_abs(paso);     }   }  }  /* ASIGNAMOS EL ERROR ANTES DE SALIR */  *error=error_max;  /* ACTUALIZAMOS LA IMAGEN DEL CONJUNTO DE NIVEL */  for(m=0;m<size2;m++) imagen_level_set[m]=imagen_paso[m];  /* LIBERAMOS MEMORIA Y SALIMOS */  free(imagen_paso);}/*********************************************************************//* FUNCION QUE CALCULA LOS SNAKES GEODESICOS A PARTIR DE UN POLIGONO *//*********************************************************************/int ami_snake(  unsigned char *imagen, /* IMAGEN DONDE SE ENCUENTRA EL SNAKE */  int width,int height,  /* DIMENSIONES DE LA IMAGEN */  int *x,int *y,         /* COORDENADAS DEL POLIGONO */  int Np,                /* NUMERO DE PUNTOS DEL POLIGONO */  int borde,             /* BORDE DE SEPARACION DEL POLIGONO PARA CONSTRUIR LA IMAGEN DE CONJUNTO DE NIVEL */  int *xd,int *yd,       /* DESPLAZAMIENTO DE LAS COORDENADAS DEL POLIGONO EN LA IMAGEN CONJUNTO DE NIVEL */  float alfa,            /* PARAMETRO FUNCION g = 1/sqrt(1+alfa*grad(I)^2) */  float lambda,          /* PARAMETRO DE BALANCE ENTRE TERMINOS DE REGULARIDAD Y ATRACCION */  float sigma,           /* DESVIACION ESTANDARD DE LA GAUSSIANA PARA CALCULAR IMAGEN g */  int Nescalas,          /* NUMERO DE ESCALAS DIFERENTES UTILIZADAS EN TODO EL PROCESO */  float **imagen_level_set_r, /* IMAGEN DE CONJUNTO DE NIVEL RESULTADO (SU FRONTERA CORRESPONDE AL SNAKE) */  int *width_g,int *height_g, /* DIMENSIONES IMAGEN CONJUNTO DE NIVEL */  int Niter)                 /* NUMERO DE ITERACIONES MAXIMO EN CADA ESCALA */{  int i,j,k,width2,height2,xd2,yd2,iter;  long m,size2;  float *imagen_zoom,*imagen_level_set,*imagen_zoom_x,*imagen_zoom_y,*imagen_level_set_x,*imagen_level_set_y;  float *imagen_g,*imagen_g_x,*imagen_g_y,**imagen_zoom2;  float nivel1=200.; /* NIVEL EXTERIOR PARA LA IMAGEN DE LEVEL SET */  float nivel2=50.; /* NIVEL INTERIOR PARA LA IMAGEN DE LEVEL SET */  int cont1,cont2;  float error,max_grad_g,sigma_0=sigma;  if (Np<2){    printf("ERROR funcion ami_snake: No puntos del poligono = %d muy bajo\n",Np);    return(-1);  }  if (borde<2){    printf("ERROR funcion ami_snake: Borde exterior de la imagen= %d muy bajo\n",borde);    return(-1);  }  /* CREAMOS UNA NUEVA IMAGEN DONDE INCLUIR EL POLIGONO */  if(ami_rellenar_poligono(&imagen_level_set,x,y,Np,nivel1,nivel2,borde,&width2,&height2,&xd2,&yd2)!=0)   return(-1);  size2=width2*height2; *xd=xd2; *yd=yd2;  /* COMPROBAMOS QUE LA IMAGEN DEL POLIGONO NO SE SALE DE LA IMAGEN ORIGINAL */  if ((xd2+width2)>width || xd2<0 || (yd2+height2)>height || yd2<0 ){    printf("ERROR funcion ami_snake: La subventana del poligono se sale de la imagen\n");    return(-1);  }  /* COGEMOS MEMORIA PARA EL RESTO DE IMAGENES INVOLUCRADAS */  ami_malloc1d(imagen_zoom,float,size2); ami_malloc1d(imagen_zoom_x,float,size2);  ami_malloc1d(imagen_zoom_y,float,size2);  ami_malloc1d(imagen_level_set_x,float,size2); ami_malloc1d(imagen_level_set_y,float,size2);  ami_malloc1d(imagen_g,float,size2); ami_malloc1d(imagen_g_x,float,size2);  ami_malloc1d(imagen_g_y,float,size2);  ami_malloc2d(imagen_zoom2,float,width2,height2);  /* RELLENAMOS LA IMAGEN imagen_zoom */  for(i=0;i<height2;i++)    for(j=0;j<width2;j++)      imagen_zoom[i*width2+j]=imagen[(i+yd2)*width+xd2+j];/* INICIO CODIGO XMW *//*  level_set=CreateImage("level_set_image",RIM,width2,height2,"");  zoom=CreateImage("snake_image",RIM,width2,height2,"");  zoom_2=CreateImage("Gaussian_Image_convolution",RIM,width2,height2,"");  g=CreateImage("image_g",RIM,width2,height2,"");  for(m=0;m<size2;m++){     level_set->RIMdata[m]=imagen_level_set[m];     zoom->RIMdata[m]=imagen_zoom[m];   }   ShowImage(level_set);   ShowImage(zoom); *//* FIN CODIGO XMW */  /* INICIAMOS EL PROCESO DE EVOLUCION DEL CONJUNTO DE NIVEL */  for(k=0;k<Nescalas;k++){    /* AJUSTAMOS DESVIACION TIPICA DE LA GAUSSIANA */    sigma=sigma_0*(Nescalas-k);    for(m=0;m<size2;m++) imagen_zoom2[0][m]=imagen_zoom[m];/* INICIO CODIGO XMW */ //  for(m=0;m<size2;m++){zoom_2->RIMdata[m]=imagen_zoom2[0][m];} //  ShowImage(zoom_2);/* FIN CODIGO XMW */    /* APLICAMOS LA CONVOLUCION CON UNA GAUSSIANA Y CALCULAMOS imagen_g*/    ami_gauss_conv_alma(imagen_zoom2[0],sigma,sigma,10.,width2,height2);    ami_grad(imagen_zoom2[0],width2,height2,imagen_zoom_x,imagen_zoom_y);    for(m=0;m<size2;m++){      double paso;      paso=imagen_zoom_x[m]*imagen_zoom_x[m]+imagen_zoom_y[m]*imagen_zoom_y[m];      imagen_g[m]=1./sqrt((double) 1. +alfa*paso);    }/* INICIO CODIGO XMW */   /*for(m=0;m<size2;m++){g->RIMdata[m]=255*imagen_g[m];}   ShowImage(g);   for(m=0;m<size2;m++){zoom_2->RIMdata[m]=imagen_zoom2[0][m];}   ShowImage(zoom_2); *//* FIN CODIGO XMW */    /* CALCULAMOS EL GRADIENTE DE g */    ami_grad(imagen_g,width2,height2,imagen_g_x,imagen_g_y);    /* CALCULAMOS EL MAXIMO DEL GRADIENTE DE g PARA LUEGO AJUSTAR el dt */    for(m=0;m<size2;m++) imagen_level_set_x[m]=imagen_g_x[m]*imagen_g_x[m]+imagen_g_y[m]*imagen_g_y[m];    ami_max_vector(imagen_level_set_x,m,max_grad_g,size2);    max_grad_g=sqrt(max_grad_g);    /* INICIALIZAMOS EL ERROR Y COMENZAMOS ITERACIONES */    error=ami_snake_tol_error+1; iter=0;    while(error>ami_snake_tol_error && Niter > iter){      iter++;      printf("iter=%d\n",iter);      ami_snake_iteracion(imagen_level_set,imagen_level_set_x,imagen_level_set_y,                          imagen_g,imagen_g_x,imagen_g_y,width2,height2,lambda,&error,max_grad_g);/* INICIO CODIGO XMW */ /*  for(m=0;m<size2;m++){level_set->RIMdata[m]=imagen_level_set[m];}   ShowImage(level_set);   for(m=0;m<size2;m++) zoom->RIMdata[m]=imagen_zoom[m];   for(i=1;i<(height2-1);i++){     for(j=1;j<(width2-1);j++){       m=i*width2+j;       if(imagen_level_set[m]<125.){         cont1=cont2=0;         if(imagen_level_set[m+1]>125.) cont1++;	 else cont2++;	 if(imagen_level_set[m-1]>125.) cont1++;	 else cont2++;	 if(imagen_level_set[m+width2]>125.) cont1++;	 else cont2++;	 if(imagen_level_set[m-width2]>125.) cont1++;	 else cont2++;	 if(cont1>0 && cont2>0) zoom->RIMdata[m]=255.;      }    }  }   ShowImage(zoom); *//* FIN CODIGO XMW */    }  }  /* AJUSTAMOS LA IMAGEN Y LAS DIMENSIONES DE LA IMAGEN DE CONJUNTO DE NIVEL */  *width_g=width2; *height_g=height2;  *imagen_level_set_r=imagen_level_set;  /* LIBERAMOS MEMORIA */  free(imagen_zoom); free(imagen_zoom_x); free(imagen_zoom_y); ami_free2d(imagen_zoom2);  free(imagen_level_set_x); free(imagen_level_set_y);  free(imagen_g); free(imagen_g_x); free(imagen_g_y);  return(0);}/*******************************************************//* FUNCION CONSTRUYE UNA IMAGEN RELLENANDO UN POLIGONO *//*******************************************************//* DEVUELVE -1 SI ALGO VA MAL y 0 SI TERMINA BIEN */int ami_rellenar_poligono(   float **imagen,  /* IMAGEN QUE SE VA A RELLENAR */   int *x,int *y,   /* COORDENADAS POLIGONO */   int Np,          /* NUMERO DE PUNTOS DEL POLIGONO */   float nivel1,     /* NIVEL EXTERIOR CON EL QUE SE RELLENA */   float nivel2,    /* NIVEL INTERIOR CON EL QUE SE RELLENA */   int borde,       /* MARGEN QUE SE DEJA DE LA IMAGEN AL POLIGONO */   int *width,int *height, /* DIMENSIONES DE LA IMAGEN CREADA */   int *xd,int *yd)  /* DESPLAZAMIENTO REALIZADO DE LAS COORDENADAS DE LOS POLIGONOS */{  int i,j,xmin,xmax,ymin,ymax,width2,height2,xd2,yd2;  long m,size;  float *imagen2;  if (Np<2){    printf("ERROR funcion ami_rellenar_poligono: No puntos del poligono = %d muy bajo\n",Np);    return(-1);  }  if (borde<2){    printf("ERROR funcion ami_rellenar_poligono: Borde exterior de la imagen= %d muy bajo\n",borde);    return(-1);  }  /* CALCULAMOS LOS MAXIMOS Y MINIMOS DE LAS COORDENADAS DE LOS POLIGONOS */  ami_max_vector(x,i,xmax,Np); ami_max_vector(y,i,ymax,Np);  ami_min_vector(x,i,xmin,Np); ami_min_vector(y,i,ymin,Np);  /* DEFINIMOS DIMENSIONES DE LA IMAGEN A CREAR */  *width=width2=xmax-xmin+2*borde+1; *height=height2=ymax-ymin+2*borde+1; size=width2*height2;  /* DEFINIMOS DESPLAZAMIENTOS A REALIZAR EN LAS COORDENADAS DE LOS POLIGONOS */  *yd=yd2=ymin-borde; *xd=xd2=xmin-borde;  if(yd2<0 || xd2<0){   printf("ERROR funcion ami_rellenar_poligono: Borde exterior de la imagen= %d muy alto\n",borde);   printf("La imagen del poligono + el borde se salen de la imagen \n",borde);   return(-1);  }  /* RESERVAMOS MEMORIA PARA LA IMAGEN Y LA RELLENAMOS CON EL NIVEL INTERIOR */  ami_malloc1d(imagen2,float,size); *imagen=imagen2;  for(m=0;m<size;m++) imagen2[m]=nivel1;  /* DIBUJAMOS EL POLIGONO EN LA IMAGEN */  for(i=0;i<(Np-1);i++){    /* DIBUJAR SEGMENTO COLOR nivel1 (x[i]-xd2,y[i]-yd2) - (x[i+1]-xd2,y[i+1]-yd2) */    ami_dibujar_segmento(imagen2,width2,height2,x[i]-xd2,y[i]-yd2,x[i+1]-xd2,y[i+1]-yd2,nivel2);  }  /* DIBUJAR SEGMENTO COLOR nivel1 (x[Np-1]-xd2,y[Np-1]-yd2) - (x[0]-xd2,y[0]-yd2) */  ami_dibujar_segmento(imagen2,width2,height2,x[Np-1]-xd2,y[Np-1]-yd2,x[0]-xd2,y[0]-yd2,nivel2);  /* RELLENAMOS EL EXTERIOR DEL POLIGONO CON EL NIVEL EXTERIOR nivel1 */  ami_semilla((long) 0,imagen2,(unsigned short) width2,size,nivel1,nivel2);  return(0);}/************************************************************************************//* ALGORITMO DE SEMILLA PARA RELLENAR LA IMAGEN A PARTIR DE UN NIVEL CON OTRO NIVEL *//************************************************************************************/void ami_semilla(   long m /* POSICION DEL PUNTO ACTUAL */,   float *imagen /* IMAGEN DE ENTRADA */ ,   unsigned short width /* ANCHO DE LA IMAGEN*/ ,   long size/* TAMANO DE LA IMAGEN */ ,   float nivel1 /* NIVEL QUE SE VA MODIFICAR */,   float nivel2 /* NIVEL CON EL QUE SE RELLENA*/){   imagen[m]=nivel2;   if((m-1)>=0){   	if(imagen[m-1]==nivel1 )   	    ami_semilla(m-1,imagen,width,size,nivel1,nivel2);   }   if((m+1)<size){   	if(imagen[m+1]==nivel1)   	    ami_semilla(m+1,imagen,width,size,nivel1,nivel2);   }   if((m-width)>=0){   	if(imagen[m-width]==nivel1)   	    ami_semilla(m-width,imagen,width,size,nivel1,nivel2);   }   if((m+width)<size){   	if(imagen[m+width]==nivel1)   	    ami_semilla(m+width,imagen,width,size,nivel1,nivel2);   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -