Example #1
0
void
TestInterpolation<T>::testLinear()
{
    USING_NK_NS
    USING_NKHIVE_NS
  
    // construct volume 
    T default_val(1); 
    vec3d res(1.0);
    vec3d kernel_offset(0.5);
    typename Volume<T>::shared_ptr volume(
                        new Volume<T>(2, 1, default_val, res, kernel_offset));

    // set some cell values
    volume->set(0, 1, 0, T(2));
    volume->set(0, 1, 1, T(2));
    volume->set(1, 1, 0, T(2));
    volume->set(1, 1, 1, T(2));

    // create interpolation object
    LinearInterpolation<T> linear_interp(volume);
    
    // test interior point
    T result(0);
    linear_interp.interp(1.0, 1.0, 1.0, result);
    CHECK_RESULT(1.5);

    // test boundary point
    linear_interp.interp(1.0, 0.0, 1.0, result);
    CHECK_RESULT(1.0);

    // test boundary point
    linear_interp.interp(1.0, 2.0, 1.0, result);
    CHECK_RESULT(1.5);

    // test interior point
    linear_interp.interp(1.0, 0.75, 1.0, result);
    CHECK_RESULT(1.25);
  
    // test interior point
    linear_interp.interp(1.0, 1.25, 1.0, result);
    CHECK_RESULT(1.75);
    
    // test y axis 
    // destroy and create new one
    // clear would be nice here
    volume = typename Volume<T>::shared_ptr(
                        new Volume<T>(2, 1, default_val, res, kernel_offset));
   
    // set some cell values
    volume->set(1, 0, 0, T(2));
    volume->set(1, 0, 1, T(2));
    volume->set(1, 1, 0, T(2));
    volume->set(1, 1, 1, T(2));
    
    // create interpolation object
    LinearInterpolation<T> linear_interp2(volume);
    
    // test interior point
    linear_interp2.interp(1.0, 1.0, 1.0, result);
    CHECK_RESULT(1.5);

    // test boundary point
    linear_interp2.interp(0.0, 0.75, 1.0, result);
    CHECK_RESULT(1.0);

    // test boundary point
    linear_interp2.interp(2.0, 1.0, 1.0, result);
    CHECK_RESULT(1.5);
   
    // test z axis 
    // destroy and create new one
    // clear would be nice here
    volume = typename Volume<T>::shared_ptr(
                        new Volume<T>(2, 1, default_val, res, kernel_offset)); 
   
    // set some cell values
    volume->set(0, 0, 1, T(2));
    volume->set(1, 0, 1, T(2));
    volume->set(0, 1, 1, T(2));
    volume->set(1, 1, 1, T(2));
    
    // create interpolation object
    LinearInterpolation<T> linear_interp3(volume);
    
    // test interior point
    linear_interp3.interp(1.0, 1.0, 1.0, result);
    CHECK_RESULT(1.5);

    // test boundary point
    linear_interp3.interp(1.0, 1.9, 0.0, result);
    CHECK_RESULT(1.0);

    // test boundary point
    linear_interp3.interp(1.0, 1.0, 2.0, result);
    CHECK_RESULT(1.5);

    // test some more interior points
    volume = typename Volume<T>::shared_ptr(
                        new Volume<T>(2, 1, default_val, res, kernel_offset));

    // set some cell values
    volume->set(0,0,0, T(1));
    volume->set(0,0,1, T(2));
    volume->set(0,1,0, T(3));
    volume->set(0,1,1, T(4));
    volume->set(1,0,0, T(5));
    volume->set(1,0,1, T(6));
    volume->set(1,1,0, T(7));
    volume->set(1,1,1, T(8));

    LinearInterpolation<T> linear_interp4(volume);
    linear_interp4.interp(0.75, 1.15, 0.9, result);
    CHECK_RESULT(3.7);
}
Example #2
0
// Main
int main(int argc, char ** argv) {

	// Choose the best GPU in case there are multiple available
	choose_GPU();

	// Keep track of the start time of the program
	long long program_start_time = get_time();
	
	if (argc !=3){
	fprintf(stderr, "usage: %s <input file> <number of frames to process>", argv[0]);
	exit(1);
	}
	
	// Let the user specify the number of frames to process
	int num_frames = atoi(argv[2]);
	
	// Open video file
	char *video_file_name = argv[1];
	
	avi_t *cell_file = AVI_open_input_file(video_file_name, 1);
	if (cell_file == NULL)	{
		AVI_print_error("Error with AVI_open_input_file");
		return -1;
	}
	
	int i, j, *crow, *ccol, pair_counter = 0, x_result_len = 0, Iter = 20, ns = 4, k_count = 0, n;
	MAT *cellx, *celly, *A;
	double *GICOV_spots, *t, *G, *x_result, *y_result, *V, *QAX_CENTERS, *QAY_CENTERS;
	double threshold = 1.8, radius = 10.0, delta = 3.0, dt = 0.01, b = 5.0;
	
	// Extract a cropped version of the first frame from the video file
	MAT *image_chopped = get_frame(cell_file, 0, 1, 0);
	printf("Detecting cells in frame 0\n");
	
	// Get gradient matrices in x and y directions
	MAT *grad_x = gradient_x(image_chopped);
	MAT *grad_y = gradient_y(image_chopped);
	
	// Allocate for gicov_mem and strel
	gicov_mem = (float*) malloc(sizeof(float) * grad_x->m * grad_y->n);
	strel = (float*) malloc(sizeof(float) * strel_m * strel_n);

	m_free(image_chopped);

	int grad_m = grad_x->m;
	int grad_n = grad_y->n;
	
#pragma acc data create(sin_angle,cos_angle,theta,tX,tY) \
	create(gicov_mem[0:grad_x->m*grad_y->n])
{
	// Precomputed constants on GPU
	compute_constants();

	// Get GICOV matrices corresponding to image gradients
	long long GICOV_start_time = get_time();
	MAT *gicov = GICOV(grad_x, grad_y);
	long long GICOV_end_time = get_time();

	// Dilate the GICOV matrices
	long long dilate_start_time = get_time();
	MAT *img_dilated = dilate(gicov);
	long long dilate_end_time = get_time();
} /* end acc data */
	
	// Find possible matches for cell centers based on GICOV and record the rows/columns in which they are found
	pair_counter = 0;
	crow = (int *) malloc(gicov->m * gicov->n * sizeof(int));
	ccol = (int *) malloc(gicov->m * gicov->n * sizeof(int));
	for(i = 0; i < gicov->m; i++) {
		for(j = 0; j < gicov->n; j++) {
			if(!double_eq(m_get_val(gicov,i,j), 0.0) && double_eq(m_get_val(img_dilated,i,j), m_get_val(gicov,i,j)))
			{
				crow[pair_counter]=i;
				ccol[pair_counter]=j;
				pair_counter++;
			}
		}
	}

	GICOV_spots = (double *) malloc(sizeof(double) * pair_counter);
	for(i = 0; i < pair_counter; i++)
		GICOV_spots[i] = sqrt(m_get_val(gicov, crow[i], ccol[i]));
	
	G = (double *) calloc(pair_counter, sizeof(double));
	x_result = (double *) calloc(pair_counter, sizeof(double));
	y_result = (double *) calloc(pair_counter, sizeof(double));
	
	x_result_len = 0;
	for (i = 0; i < pair_counter; i++) {
		if ((crow[i] > 29) && (crow[i] < BOTTOM - TOP + 39)) {
			x_result[x_result_len] = ccol[i];
			y_result[x_result_len] = crow[i] - 40;
			G[x_result_len] = GICOV_spots[i];
			x_result_len++;
		}
	}
	
	// Make an array t which holds each "time step" for the possible cells
	t = (double *) malloc(sizeof(double) * 36);
	for (i = 0; i < 36; i++) {
		t[i] = (double)i * 2.0 * PI / 36.0;
	}
	
	// Store cell boundaries (as simple circles) for all cells
	cellx = m_get(x_result_len, 36);
	celly = m_get(x_result_len, 36);
	for(i = 0; i < x_result_len; i++) {
		for(j = 0; j < 36; j++) {
			m_set_val(cellx, i, j, x_result[i] + radius * cos(t[j]));
			m_set_val(celly, i, j, y_result[i] + radius * sin(t[j]));
		}
	}
	
	A = TMatrix(9,4);
	V = (double *) malloc(sizeof(double) * pair_counter);
	QAX_CENTERS = (double * )malloc(sizeof(double) * pair_counter);
	QAY_CENTERS = (double *) malloc(sizeof(double) * pair_counter);
	memset(V, 0, sizeof(double) * pair_counter);
	memset(QAX_CENTERS, 0, sizeof(double) * pair_counter);
	memset(QAY_CENTERS, 0, sizeof(double) * pair_counter);

	// For all possible results, find the ones that are feasibly leukocytes and store their centers
	k_count = 0;
	for (n = 0; n < x_result_len; n++) {
		if ((G[n] < -1 * threshold) || G[n] > threshold) {
			MAT * x, *y;
			VEC * x_row, * y_row;
			x = m_get(1, 36);
			y = m_get(1, 36);

			x_row = v_get(36);
			y_row = v_get(36);

			// Get current values of possible cells from cellx/celly matrices
			x_row = get_row(cellx, n, x_row);
			y_row = get_row(celly, n, y_row);
			uniformseg(x_row, y_row, x, y);

			// Make sure that the possible leukocytes are not too close to the edge of the frame
			if ((m_min(x) > b) && (m_min(y) > b) && (m_max(x) < cell_file->width - b) && (m_max(y) < cell_file->height - b)) {
				MAT * Cx, * Cy, *Cy_temp, * Ix1, * Iy1;
				VEC  *Xs, *Ys, *W, *Nx, *Ny, *X, *Y;
				Cx = m_get(1, 36);
				Cy = m_get(1, 36);
				Cx = mmtr_mlt(A, x, Cx);
				Cy = mmtr_mlt(A, y, Cy);
				
				Cy_temp = m_get(Cy->m, Cy->n);
				
				for (i = 0; i < 9; i++)
					m_set_val(Cy, i, 0, m_get_val(Cy, i, 0) + 40.0);
					
				// Iteratively refine the snake/spline
				for (i = 0; i < Iter; i++) {
					int typeofcell;
					
					if(G[n] > 0.0) typeofcell = 0;
					else typeofcell = 1;
					
					splineenergyform01(Cx, Cy, grad_x, grad_y, ns, delta, 2.0 * dt, typeofcell);
				}
				
				X = getsampling(Cx, ns);
				for (i = 0; i < Cy->m; i++)
					m_set_val(Cy_temp, i, 0, m_get_val(Cy, i, 0) - 40.0);
				Y = getsampling(Cy_temp, ns);
				
				Ix1 = linear_interp2(grad_x, X, Y);
				Iy1 = linear_interp2(grad_x, X, Y);
				Xs = getfdriv(Cx, ns);
				Ys = getfdriv(Cy, ns);
				
				Nx = v_get(Ys->dim);
				for (i = 0; i < Ys->dim; i++)
					v_set_val(Nx, i, v_get_val(Ys, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
					
				Ny = v_get(Xs->dim);
				for (i = 0; i < Xs->dim; i++)
					v_set_val(Ny, i, -1.0 * v_get_val(Xs, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
					
				W = v_get(Nx->dim);
				for (i = 0; i < Nx->dim; i++)
					v_set_val(W, i, m_get_val(Ix1, 0, i) * v_get_val(Nx, i) + m_get_val(Iy1, 0, i) * v_get_val(Ny, i));
					
				V[n] = mean(W) / std_dev(W);
				
				// Find the cell centers by computing the means of X and Y values for all snaxels of the spline contour
				QAX_CENTERS[k_count] = mean(X);
				QAY_CENTERS[k_count] = mean(Y) + TOP;
				
				k_count++;
				
				// Free memory
				v_free(W);
				v_free(Ny);
				v_free(Nx);
				v_free(Ys);
				v_free(Xs);
				m_free(Iy1);
				m_free(Ix1);
				v_free(Y);
				v_free(X);
				m_free(Cy_temp);
				m_free(Cy);
				m_free(Cx);				
			}

			// Free memory
			v_free(y_row);
			v_free(x_row);
			m_free(y);
			m_free(x);
		}
	}
	
	// Free memory
	free(gicov_mem);
	free(strel);
	free(V);
	free(ccol);
	free(crow);
	free(GICOV_spots);
	free(t);
	free(G);
	free(x_result);
	free(y_result);
	m_free(A);
	m_free(celly);
	m_free(cellx);
	m_free(img_dilated);
	m_free(gicov);
	m_free(grad_y);
	m_free(grad_x);
	
	// Report the total number of cells detected
	printf("Cells detected: %d\n\n", k_count);
	
	// Report the breakdown of the detection runtime
	printf("Detection runtime\n");
	printf("-----------------\n");
	printf("GICOV computation: %.5f seconds\n", ((float) (GICOV_end_time - GICOV_start_time)) / (1000*1000));
	printf("   GICOV dilation: %.5f seconds\n", ((float) (dilate_end_time - dilate_start_time)) / (1000*1000));
	printf("            Total: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
	
	// Now that the cells have been detected in the first frame,
	//  track the ellipses through subsequent frames
	if (num_frames > 1) printf("\nTracking cells across %d frames\n", num_frames);
	else                printf("\nTracking cells across 1 frame\n");
	long long tracking_start_time = get_time();
	int num_snaxels = 20;
	ellipsetrack(cell_file, QAX_CENTERS, QAY_CENTERS, k_count, radius, num_snaxels, num_frames);
	printf("           Total: %.5f seconds\n", ((float) (get_time() - tracking_start_time)) / (float) (1000*1000*num_frames));	
	
	// Report total program execution time
    printf("\nTotal application run time: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));

	return 0;
}
void ellipseevolve(MAT *f, double *xc0, double *yc0, double *r0, double *t, int Np, double Er, double Ey) {
    /*
    % ELLIPSEEVOLVE evolves a parametric snake according
    %  to some energy constraints.
    %
    % INPUTS:
    %   f............potential surface
    %   xc0,yc0......initial center position
    %   r0,t.........initial radii & angle vectors (with Np elements each)
    %   Np...........number of snaxel points per snake
    %   Er...........expected radius
    %   Ey...........expected y position
    %
    % OUTPUTS
    %   xc0,yc0.......final center position
    %   r0...........final radii
    %
    % Matlab code written by: DREW GILLIAM (based on work by GANG DONG /
    %                                                        NILANJAN RAY)
    % Ported to C by: MICHAEL BOYER
    */


    // Constants
    double deltax = 0.2;
    double deltay = 0.2;
    double deltar = 0.2;
    double converge = 0.1;
    double lambdaedge = 1;
    double lambdasize = 0.2;
    double lambdapath = 0.05;
    int iterations = 1000;      // maximum number of iterations

    int i, j;

    // Initialize variables
    double xc = *xc0;
    double yc = *yc0;
    double *r = (double *) malloc(sizeof(double) * Np);
    for (i = 0; i < Np; i++) r[i] = r0[i];

    // Compute the x- and y-gradients of the MGVF matrix
    MAT *fx = gradient_x(f);
    MAT *fy = gradient_y(f);

    // Normalize the gradients
    int fh = f->m, fw = f->n;
    for (i = 0; i < fh; i++) {
        for (j = 0; j < fw; j++) {
            double temp_x = m_get_val(fx, i, j);
            double temp_y = m_get_val(fy, i, j);
            double fmag = sqrt((temp_x * temp_x) + (temp_y * temp_y));
            m_set_val(fx, i, j, temp_x / fmag);
            m_set_val(fy, i, j, temp_y / fmag);
        }
    }

    double *r_old = (double *) malloc(sizeof(double) * Np);
    VEC *x = v_get(Np);
    VEC *y = v_get(Np);


    // Evolve the snake
    int iter = 0;
    double snakediff = 1.0;
    while (iter < iterations && snakediff > converge) {

        // Save the values from the previous iteration
        double xc_old = xc, yc_old = yc;
        for (i = 0; i < Np; i++) {
            r_old[i] = r[i];
        }

        // Compute the locations of the snaxels
        for (i = 0; i < Np; i++) {
            v_set_val(x, i, xc + r[i] * cos(t[i]));
            v_set_val(y, i, yc + r[i] * sin(t[i]));
        }

        // See if any of the points in the snake are off the edge of the image
        double min_x = v_get_val(x, 0), max_x = v_get_val(x, 0);
        double min_y = v_get_val(y, 0), max_y = v_get_val(y, 0);
        for (i = 1; i < Np; i++) {
            double x_i = v_get_val(x, i);
            if (x_i < min_x) min_x = x_i;
            else if (x_i > max_x) max_x = x_i;
            double y_i = v_get_val(y, i);
            if (y_i < min_y) min_y = y_i;
            else if (y_i > max_y) max_y = y_i;
        }
        if (min_x < 0.0 || max_x > (double) fw - 1.0 || min_y < 0 || max_y > (double) fh - 1.0) break;


        // Compute the length of the snake
        double L = 0.0;
        for (i = 0; i < Np - 1; i++) {
            double diff_x = v_get_val(x, i + 1) - v_get_val(x, i);
            double diff_y = v_get_val(y, i + 1) - v_get_val(y, i);
            L += sqrt((diff_x * diff_x) + (diff_y * diff_y));
        }
        double diff_x = v_get_val(x, 0) - v_get_val(x, Np - 1);
        double diff_y = v_get_val(y, 0) - v_get_val(y, Np - 1);
        L += sqrt((diff_x * diff_x) + (diff_y * diff_y));

        // Compute the potential surface at each snaxel
        MAT *vf  = linear_interp2(f,  x, y);
        MAT *vfx = linear_interp2(fx, x, y);
        MAT *vfy = linear_interp2(fy, x, y);

        // Compute the average potential surface around the snake
        double vfmean  = sum_m(vf ) / L;
        double vfxmean = sum_m(vfx) / L;
        double vfymean = sum_m(vfy) / L;

        // Compute the radial potential surface
        int m = vf->m, n = vf->n;
        MAT *vfr = m_get(m, n);
        for (i = 0; i < n; i++) {
            double vf_val  = m_get_val(vf,  0, i);
            double vfx_val = m_get_val(vfx, 0, i);
            double vfy_val = m_get_val(vfy, 0, i);
            double x_val = v_get_val(x, i);
            double y_val = v_get_val(y, i);
            double new_val = (vf_val + vfx_val * (x_val - xc) + vfy_val * (y_val - yc) - vfmean) / L;
            m_set_val(vfr, 0, i, new_val);
        }

        // Update the snake center and snaxels
        xc =  xc + (deltax * lambdaedge * vfxmean);
        yc = (yc + (deltay * lambdaedge * vfymean) + (deltay * lambdapath * Ey)) / (1.0 + deltay * lambdapath);
        double r_diff = 0.0;
        for (i = 0; i < Np; i++) {
            r[i] = (r[i] + (deltar * lambdaedge * m_get_val(vfr, 0, i)) + (deltar * lambdasize * Er)) /
                   (1.0 + deltar * lambdasize);
            r_diff += fabs(r[i] - r_old[i]);
        }

        // Test for convergence
        snakediff = fabs(xc - xc_old) + fabs(yc - yc_old) + r_diff;

        // Free temporary matrices
        m_free(vf);
        m_free(vfx);
        m_free(vfy);
        m_free(vfr);

        iter++;
    }

    // Set the return values
    *xc0 = xc;
    *yc0 = yc;
    for (i = 0; i < Np; i++)
        r0[i] = r[i];

    // Free memory
    free(r);
    free(r_old);
    v_free( x);
    v_free( y);
    m_free(fx);
    m_free(fy);
}