/*--------------------------------------------------------------------------*/
ntuple_list gaussian_convol_on_curve(double unit_sigma, double Nsigma, bool resampling, bool eliminate_border, double up_factor, double down_factor, ntuple_list orig_edges)
{
  double x1, y1, x2, y2, sumx, sumy, d, norm, w;
  int j, k;
  
  double line_length, sample_step = 0.0;
  ntuple_list upsampled_edges, convolved_upsampled_edges, each_seg_length, output_pts;
  each_seg_length = new_ntuple_list(1);

  double residual_d = 0.0, lambda;
  int low_bound, high_bound;
  int size_lambda, begin_lambda;
  double small_seg_x, small_seg_y;
  double sigma;
  int flag, nb_sigma, not_border_flag;
  double real_down_factor;
  unsigned int nb_pts;

  nb_pts = orig_edges->size;

  upsampled_edges = new_ntuple_list(2);

  /*length of the whole line*/
  line_length = 0.0;

  /*the total length of the line and the lenth of each segment*/
  for(j = 0; j < (int)nb_pts-1; j++) {
    x1 = orig_edges->values[j*orig_edges->dim + 0];
    y1 = orig_edges->values[j*orig_edges->dim + 1];
    x2 = orig_edges->values[(j+1)*orig_edges->dim + 0];
    y2 = orig_edges->values[(j+1)*orig_edges->dim + 1];
    d = dist(x1, y1, x2, y2);
    
    add_1tuple(each_seg_length, d);
    line_length += d;
  }

  /*the average distance between two points for a line (original line)*/
  sample_step = line_length / (nb_pts-1);


  if (resampling) {
    /*TANG: the edge points are not regularly sampled, so first do an interpolation to get regularly sampled points*/
    if (up_factor < 1.0)
      error("up_factor must be greater than 1!\n");

    /*the line is upsampled, the average distance becomes smaller*/
    sample_step /= up_factor;

    /* Resampling */
    for(j = 0; j < (int)nb_pts-1; j++) {
      flag = 0;

      x1 = orig_edges->values[j*orig_edges->dim + 0];
      y1 = orig_edges->values[j*orig_edges->dim + 1];
      x2 = orig_edges->values[(j+1)*orig_edges->dim + 0];
      y2 = orig_edges->values[(j+1)*orig_edges->dim + 1];

      if (j == 0)
	residual_d = 0.0;

      size_lambda = (int)floor((each_seg_length->values[j]+residual_d)/sample_step);
      
      begin_lambda = 0;
      if (j != 0)
	begin_lambda = 1;

      for(k = begin_lambda; k <= size_lambda; k++) {
	lambda = (-residual_d + k*sample_step) / each_seg_length->values[j];
	small_seg_x = (1-lambda)*x1 + lambda*x2;
	small_seg_y = (1-lambda)*y1 + lambda*y2;

	add_2tuple(upsampled_edges, small_seg_x, small_seg_y);
	
	flag = 1;
      }
      
      if(flag == 1)
	residual_d = dist(x2, y2, small_seg_x, small_seg_y);
      else
	residual_d += each_seg_length->values[j];
    }

  }
  else /* no resampling, copy 'orig_edges' to 'upsampled_edges' */
    copy_ntuple(orig_edges, upsampled_edges);
  

  /* convolution */
  convolved_upsampled_edges = new_ntuple_list(2);

  for(j=0; j<(int)upsampled_edges->size; j++)
  {
    norm = 0.0; sumx = 0.0; sumy = 0.0;

    sigma = unit_sigma * sqrt(down_factor*down_factor - 1.0);
    nb_sigma = (int)floor( Nsigma * sigma / sample_step );

    low_bound = j - nb_sigma;
    if(low_bound < 0)
      low_bound = 0;
    high_bound = j + nb_sigma;
    if(high_bound > (int)upsampled_edges->size-1)
      high_bound = upsampled_edges->size-1;

    if(eliminate_border) {
      if(high_bound - low_bound == 2*nb_sigma) 
	not_border_flag = 1;
      else
	not_border_flag = 0;
    }
    else
      not_border_flag = 1;

    if(not_border_flag == 1) {
      for (k = low_bound; k <= high_bound; k++) {
	/*x1 = upsampled_edges->list[i]->values[upsampled_edges->list[i]->dim*j];
	y1 = upsampled_edges->list[i]->values[upsampled_edges->list[i]->dim*j+1];
	x2 = upsampled_edges->list[i]->values[upsampled_edges->list[i]->dim*k];
	y2 = upsampled_edges->list[i]->values[upsampled_edges->list[i]->dim*k+1];
	d = dist(x1, y1, x2, y2);*/
	x2 = upsampled_edges->values[upsampled_edges->dim*k];
	y2 = upsampled_edges->values[upsampled_edges->dim*k+1];
	d = sample_step * (k-j);
	w = exp( -d*d / 2.0 / sigma / sigma );
	sumx += w*x2;
	sumy += w*y2;
	norm += w;
      }
  
      sumx /= norm;
      sumy /= norm;

      add_2tuple(convolved_upsampled_edges, sumx, sumy);
    }
  }

  /* if resampling is enabled */
  /*
  output_pts = new_ntuple_list(2);
  if(resampling)
  {
    real_down_factor = (int)(down_factor * up_factor);
    
    nb = convolved_upsampled_edges->size / real_down_factor + 1;
    for(j = 0; j < nb; j++)
      add_2tuple(output_pts, convolved_upsampled_edges->values[j*real_down_factor*convolved_upsampled_edges->dim], convolved_upsampled_edges->values[j*real_down_factor*convolved_upsampled_edges->dim+1]);
  }
  else 
    copy_ntuple(upsampled_edges, output_pts);
  */

  output_pts = new_ntuple_list(2);
  if(resampling)
    real_down_factor = down_factor * up_factor;
  else
    real_down_factor = down_factor;
  
  /*
  nb = (int)((double)convolved_upsampled_edges->size / real_down_factor);
  
  for(j = 0; j < nb; j++)
    add_2tuple(output_pts, convolved_upsampled_edges->values[(int)(j*real_down_factor*convolved_upsampled_edges->dim)], convolved_upsampled_edges->values[(int)(j*real_down_factor*convolved_upsampled_edges->dim)+1]);
  */

  j = 0;
  while(j < (int)convolved_upsampled_edges->size) 
  { 
    add_2tuple(output_pts, convolved_upsampled_edges->values[(int)(j*convolved_upsampled_edges->dim)], convolved_upsampled_edges->values[(int)(j*convolved_upsampled_edges->dim)+1]);
    j = floor(j + real_down_factor);
  }

  free_ntuple_list(upsampled_edges);
  free_ntuple_list(convolved_upsampled_edges);
  free_ntuple_list(each_seg_length);

  return output_pts;
}
Ejemplo n.º 2
0
//static image_float gaussian_sampler( float* in, int width,int height, int d, float scale,
//float sigma_scale )
image_float gaussian_sampler( image_float in, float scale, float sigma_scale )
{
    image_float aux,out;
    ntuple_list kernel;
    unsigned int N,M,h,n,x,y,i;
    int xc,yc,j,float_x_size,float_y_size;
    float sigma,xx,yy,sum,prec;
      
    /* compute new image size and get memory for images */
    if( in->xsize * scale > (float) UINT_MAX ||
       in->ysize * scale > (float) UINT_MAX )
        
        error("gaussian_sampler: the output image size exceeds the handled size.");
    N = (unsigned int) ceil( in->xsize * scale );
    M = (unsigned int) ceil( in->ysize * scale );

    aux = new_image_float(N,in->ysize);
    out = new_image_float(N,M);
    
    /* sigma, kernel size and memory for the kernel */
    sigma = scale < 1.0 ? sigma_scale / scale : sigma_scale;
    /*Como para ingresar a este codigo scale <1 (se evalua en la funcion LineSegmentDetection),
     siempre se va a cumplir que sigma = sigma_scale / scale */
    /*
     The size of the kernel is selected to guarantee that the
     the first discarded term is at least 10^prec times smaller
     than the central value. For that, h should be larger than x, with
     e^(-x^2/2sigma^2) = 1/10^prec.
     Then,
     x = sigma * sqrt( 2 * prec * ln(10) ).
     */
    prec = 3.0;
    h = (unsigned int) ceil( sigma * sqrt( 2.0 * prec * log(10.0) ) );
    /*La funcion log() corresponde al logaritmo neperiano*/
    n = 1+2*h; /* kernel size */
    kernel = new_ntuple_list(n);
    
    /* auxiliary float image size variables */
    float_x_size = (int) (2 * in->xsize);
    float_y_size = (int) (2 * in->ysize);
    
    gaussian_kernel( kernel, sigma, (float) h );
    float scale_inv=1/scale;
    
    /* First subsampling: x axis */
    for(x=3;x<aux->xsize-2;x++)
    {
        /*
         x   is the coordinate in the new image.
         xx  is the corresponding x-value in the original size image.
         xc  is the integer value, the pixel coordinate of xx.
         */
        xx = (float) x * scale_inv; /*Esto es para recorrer toda la imagen porque aux-> size = width*scale*/
        /* coordinate (0.0,0.0) is in the center of pixel (0,0),
         so the pixel with xc=0 get the values of xx from -0.5 to 0.5 */
        xc = (int) floor( xx + 0.5 ); /*Aca redondeamos el valor. Seria lo mismo que hacer round(xx)*/
        
        //        gaussian_kernel( kernel, sigma, (float) h + xx - (float) xc );
        
        /* the kernel must be computed for each x because the fine
         offset xx-xc is different in each case */
        
        for(y=0;y<aux->ysize;y++)
        {
            sum = 0.0;
            for(i=0;i<kernel->dim;i++)
            {
                j = xc - h + i;
                sum += in->data[ j + y * in->xsize ] * kernel->values[i];
            }
            aux->data[ x + y * aux->xsize ] = sum;
        }
    }
    
    /* Second subsampling: y axis */
    for(y=3;y<out->ysize-2;y++)
    {
        /*
         y   is the coordinate in the new image.
         yy  is the corresponding x-value in the original size image.
         yc  is the integer value, the pixel coordinate of xx.
         */
        yy = (float) y * scale_inv;
        /* coordinate (0.0,0.0) is in the center of pixel (0,0),
         so the pixel with yc=0 get the values of yy from -0.5 to 0.5 */
        yc = (int) floor( yy + 0.5 );
        //gaussian_kernel( kernel, sigma, (float) h + yy - (float) yc );
        /* the kernel must be computed for each y because the fine
         offset yy-yc is different in each case */
        
        for(x=0;x<out->xsize;x++)
        {
            sum = 0.0;
            for(i=0;i<kernel->dim;i++)
            {
                j = yc - h + i;
                sum += aux->data[ x + j * aux->xsize ] * kernel->values[i];
            }
            out->data[ x + y * out->xsize ] = sum;
        }
    }
    
    /* free memory */
    free_ntuple_list(kernel);
    free_image_float(aux);
    
    return out;
}
Ejemplo n.º 3
0
int main( int argc, char** argv){
	
	/*colors*/
	CvScalar green = CV_RGB(0,255,0);
	CvScalar white = CV_RGB(255,255,255);
	CvScalar black = CV_RGB(0,0,0);
	CvScalar red = CV_RGB(255,0,0);
	CvScalar blue = CV_RGB(0,0,255);


	cvNamedWindow( "opencv on acid",CV_WINDOW_AUTOSIZE);
	cvNamedWindow( "lsd",CV_WINDOW_AUTOSIZE);
	
	CvCapture* capture;
	
	if ( argc == 1 ) {
	 	capture = cvCreateCameraCapture (0);
	} else {
	 	capture = cvCreateFileCapture (argv[1]);
	}
	assert( capture != NULL );
	
	IplImage* frame;
	image_double image;
	int width, height, i, j;
	
	while (1) {
		frame = cvQueryFrame( capture );
		if( !frame ) break;

		/* get image properties */
		width  = frame->width;
		height = frame->height;

		/* create new image for the grayscale version */
		IplImage* frameBW = cvCreateImage( cvSize( width, height ), IPL_DEPTH_8U, 1 );

		/*convert to grayscale*/ 
		cvCvtColor( frame , frameBW, CV_RGB2GRAY);
		
		/*cast into lsd image struct*/
		image = new_image_double(width, height);
		uchar* data = (uchar*)frameBW->imageData;
		for (i=0;i<height;i++){
			for(j=0;j<width;j++){
				image->data[ j + i * width ] = data[j + i*width];
			};
		};
		
		/*run lsd*/
		ntuple_list ntl;
		ntl = lsd(image);
		free_image_double(image);
		
		/*filter lsd segments*/		
		int degrees_thr = 20;	// degrees of threshold
		int distance_thr = 49;	// 7 pixels
		ntuple_list ntlFilt = new_ntuple_list(5);
		filterSegments( ntl, ntlFilt , distance_thr);
		/********************/
		
		//printf("A ver: %3.2f\n",ntl->values[1]);
		
		/*draw segments on frame and frameLsd*/
		IplImage* frameLsd = cvCreateImage( cvSize( width, height ), IPL_DEPTH_8U, 3 );
		cvSet(frameLsd, black, 0);
		for (j=0; j<ntl->size ; j++){		
			//define segment end-points
			CvPoint pt1 = cvPoint(ntl->values[ 0 + j * ntl->dim ],ntl->values[ 1 + j * ntl->dim ]);
			CvPoint pt2 = cvPoint(ntl->values[ 2 + j * ntl->dim ],ntl->values[ 3 + j * ntl->dim ]);
	
			// draw line on frame
			cvLine(frame,pt1,pt2,white,1.5,8,0);
			
			// draw line on frameLsd
			cvLine(frameLsd,pt1,pt2,white,1.5,8,0);
		}
		
		
		/*draw segments on actual frameLsdFilt*/
		IplImage* frameLsdFilt = cvCreateImage( cvSize( width, height ), IPL_DEPTH_8U, 3 );
		cvSet(frameLsdFilt, black, 0);	
		j = 0;
		for (j=0; j<ntlFilt->size ; j++){		
			//define segment end-points
			CvPoint pt1 = cvPoint(ntlFilt->values[ 0 + j * ntlFilt->dim ],ntlFilt->values[ 1 + j * ntlFilt->dim ]);
			CvPoint pt2 = cvPoint(ntlFilt->values[ 2 + j * ntlFilt->dim ],ntlFilt->values[ 3 + j * ntlFilt->dim ]);
			
			// draw line on frameLsd
			cvLine(frameLsdFilt,pt1,pt2,white,1.5,8,0);
		}		
					
		
		cvShowImage("opencv on acid",frame);
		cvShowImage("lsd",frameLsd);
		cvShowImage("lsd filtrado",frameLsdFilt);
		char c = cvWaitKey(25);
		if( c == 27 ) break;
	}
	cvReleaseCapture( &capture );
	cvDestroyWindow( "opencv on acid");
	cvDestroyWindow( "lsd");
	cvDestroyWindow( "lsd filtrado");
}