/*--------------------------------------------------------------------------*/ 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; }
//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; }
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"); }