static lgfs2_rgrps_t mockup_rgrp(void) { struct gfs2_sbd *sdp; lgfs2_rgrps_t rgs; unsigned i; uint64_t addr; struct gfs2_rindex ri = {0}; lgfs2_rgrp_t rg; uint32_t rgsize = (1024 << 20) / 4096; sdp = calloc(1, sizeof(*sdp)); fail_unless(sdp != NULL); sdp->device.length = rgsize + 20; sdp->device_fd = -1; sdp->bsize = sdp->sd_sb.sb_bsize = 4096; compute_constants(sdp); rgs = lgfs2_rgrps_init(sdp, 0, 0); fail_unless(rgs != NULL); lgfs2_rgrps_plan(rgs, sdp->device.length - 16, rgsize); addr = lgfs2_rindex_entry_new(rgs, &ri, 16, rgsize); ck_assert(addr != 0); rg = lgfs2_rgrps_append(rgs, &ri); fail_unless(rg != NULL); for (i = 0; i < rg->ri.ri_length; i++) { rg->bits[i].bi_bh = bget(sdp, rg->ri.ri_addr + i); fail_unless(rg->bits[i].bi_bh != NULL); } return rgs; }
static double distance(struct SubSig *SubSig1, struct SubSig *SubSig2, int nbands) { double dist; static int first = 1; struct SigSet S; static struct ClassSig *Sig3; static struct SubSig *SubSig3; /* allocate scratch space first time subroutine is called */ if (first) { I_InitSigSet(&S); I_SigSetNBands(&S, nbands); Sig3 = I_NewClassSig(&S); I_NewSubSig(&S, Sig3); SubSig3 = Sig3->SubSig; first = 0; } /* form SubSig3 by adding SubSig1 and SubSig2 */ add_SubSigs(SubSig1, SubSig2, SubSig3, nbands); /* compute constant for SubSig3 */ compute_constants(Sig3, nbands); /* compute distance */ dist = SubSig1->N * SubSig1->cnst + SubSig2->N * SubSig2->cnst - SubSig3->N * SubSig3->cnst; return (dist); }
static void reduce_order(struct ClassSig *Sig, int nbands, int *min_ii, int *min_jj) { int i, j; int min_i = 0, min_j = 0; double dist; double min_dist = 0; struct SubSig *SubSig1, *SubSig2; static int first = 1; struct SigSet S; static struct ClassSig *Sig3; static struct SubSig *SubSig3; /* allocate scratch space first time subroutine is called */ if (first) { I_InitSigSet(&S); I_SigSetNBands(&S, nbands); Sig3 = I_NewClassSig(&S); I_NewSubSig(&S, Sig3); SubSig3 = Sig3->SubSig; first = 0; } if (Sig->nsubclasses > 1) { /* find the closest subclasses */ for (i = 0; i < Sig->nsubclasses - 1; i++) for (j = i + 1; j < Sig->nsubclasses; j++) { dist = distance(&(Sig->SubSig[i]), &(Sig->SubSig[j]), nbands); if ((i == 0) && (j == 1)) { min_dist = dist; min_i = i; min_j = j; } if (dist < min_dist) { min_dist = dist; min_i = i; min_j = j; } } *min_ii = min_i; *min_jj = min_j; /* Combine Subclasses */ SubSig1 = &(Sig->SubSig[min_i]); SubSig2 = &(Sig->SubSig[min_j]); add_SubSigs(SubSig1, SubSig2, SubSig3, nbands); compute_constants(Sig3, nbands); copy_SubSig(SubSig3, SubSig1, nbands); /* remove extra subclass */ for (i = min_j; i < Sig->nsubclasses - 1; i++) copy_SubSig(&(Sig->SubSig[i + 1]), &(Sig->SubSig[i]), nbands); /* decrement number of Subclasses */ Sig->nsubclasses--; } }
static int reestimate(struct ClassSig *Sig, int nbands) { int i; int s; int b1, b2; int singular; double pi_sum; double diff1, diff2; struct ClassData *Data; G_debug(2, "reestimate()"); /* set data pointer */ Data = &(Sig->ClassData); pi_sum = 0; for (i = 0; i < Sig->nsubclasses; i++) { /* Compute N */ Sig->SubSig[i].N = 0; for (s = 0; s < Data->npixels; s++) Sig->SubSig[i].N += Data->p[s][i]; Sig->SubSig[i].pi = Sig->SubSig[i].N; /* Compute means and variances for each subcluster, */ /* and remove small clusters. */ /* For large subclusters */ if (Sig->SubSig[i].N > SMALLEST_SUBCLUST) { /* Compute mean */ for (b1 = 0; b1 < nbands; b1++) { Sig->SubSig[i].means[b1] = 0; for (s = 0; s < Data->npixels; s++) if (!Rast_is_d_null_value(&Data->x[s][b1])) Sig->SubSig[i].means[b1] += Data->p[s][i] * Data->x[s][b1]; Sig->SubSig[i].means[b1] /= (Sig->SubSig[i].N); /* Compute R */ for (b2 = 0; b2 <= b1; b2++) { Sig->SubSig[i].R[b1][b2] = 0; for (s = 0; s < Data->npixels; s++) { if (!Rast_is_d_null_value(&Data->x[s][b1]) && !Rast_is_d_null_value(&Data->x[s][b2])) { diff1 = Data->x[s][b1] - Sig->SubSig[i].means[b1]; diff2 = Data->x[s][b2] - Sig->SubSig[i].means[b2]; Sig->SubSig[i].R[b1][b2] += Data->p[s][i] * diff1 * diff2; } } Sig->SubSig[i].R[b1][b2] /= (Sig->SubSig[i].N); Sig->SubSig[i].R[b2][b1] = Sig->SubSig[i].R[b1][b2]; } } } /* For small subclusters */ else { G_warning(_("Subsignature %d only contains %.0f pixels"), i, Sig->SubSig[i].N); Sig->SubSig[i].pi = 0; for (b1 = 0; b1 < nbands; b1++) { Sig->SubSig[i].means[b1] = 0; for (b2 = 0; b2 < nbands; b2++) Sig->SubSig[i].R[b1][b2] = 0; } } pi_sum += Sig->SubSig[i].pi; } /* Normalize probabilities for subclusters */ if (pi_sum > 0) { for (i = 0; i < Sig->nsubclasses; i++) Sig->SubSig[i].pi /= pi_sum; } else { for (i = 0; i < Sig->nsubclasses; i++) Sig->SubSig[i].pi = 0; } /* Compute constants and reestimate if any singular subclusters occur */ singular = compute_constants(Sig, nbands); return (singular); }
static void seed(struct ClassSig *Sig, int nbands) { int i, b1, b2; double period; double *mean, **R; G_debug(1, "seed()"); /* Compute the mean of variance for each band */ mean = G_alloc_vector(nbands); R = G_alloc_matrix(nbands, nbands); n_nulls = (int *)G_calloc(nbands, sizeof(int)); total_nulls = 0; for (b1 = 0; b1 < nbands; b1++) { n_nulls[b1] = 0; mean[b1] = 0.0; for (i = 0; i < Sig->ClassData.npixels; i++) { if (Rast_is_d_null_value(&Sig->ClassData.x[i][b1])) { n_nulls[b1]++; total_nulls++; } else mean[b1] += Sig->ClassData.x[i][b1]; } mean[b1] /= (double)(Sig->ClassData.npixels - n_nulls[b1]); } for (b1 = 0; b1 < nbands; b1++) for (b2 = 0; b2 < nbands; b2++) { R[b1][b2] = 0.0; for (i = 0; i < Sig->ClassData.npixels; i++) { if (!Rast_is_d_null_value(&Sig->ClassData.x[i][b1]) && !Rast_is_d_null_value(&Sig->ClassData.x[i][b2])) R[b1][b2] += (Sig->ClassData.x[i][b1]) * (Sig->ClassData.x[i][b2]); } R[b1][b2] /= (double)(Sig->ClassData.npixels - n_nulls[b1] - n_nulls[b2]); R[b1][b2] -= mean[b1] * mean[b2]; } /* Compute the sampling period for seeding */ if (Sig->nsubclasses > 1) { period = (Sig->ClassData.npixels - 1) / (Sig->nsubclasses - 1.0); } else period = 0; /* Seed the means and set the diagonal covariance components */ for (i = 0; i < Sig->nsubclasses; i++) { for (b1 = 0; b1 < nbands; b1++) { if (Rast_is_d_null_value(&Sig->ClassData.x[(int)(i * period)][b1])) Rast_set_d_null_value(&Sig->SubSig[i].means[b1], 1); else Sig->SubSig[i].means[b1] = Sig->ClassData.x[(int)(i * period)][b1]; for (b2 = 0; b2 < nbands; b2++) { Sig->SubSig[i].R[b1][b2] = R[b1][b2]; } } Sig->SubSig[i].pi = 1.0 / Sig->nsubclasses; } G_free_vector(mean); G_free_matrix(R); compute_constants(Sig, nbands); }
int main(int argc, char *argv[]) { struct gfs2_sbd sbd, *sdp = &sbd; int rindex_fd; int error = EXIT_SUCCESS; int devflags = (test ? O_RDONLY : O_RDWR) | O_CLOEXEC; setlocale(LC_ALL, ""); textdomain("gfs2-utils"); srandom(time(NULL) ^ getpid()); memset(sdp, 0, sizeof(struct gfs2_sbd)); sdp->bsize = GFS2_DEFAULT_BSIZE; sdp->rgsize = -1; sdp->jsize = GFS2_DEFAULT_JSIZE; sdp->qcsize = GFS2_DEFAULT_QCSIZE; sdp->md.journals = 1; decode_arguments(argc, argv, sdp); for(; (argc - optind) > 0; optind++) { struct metafs mfs = {0}; struct mntent *mnt; unsigned rgcount; unsigned old_rg_count; lgfs2_rgrps_t rgs; error = lgfs2_open_mnt(argv[optind], O_RDONLY|O_CLOEXEC, &sdp->path_fd, devflags, &sdp->device_fd, &mnt); if (error != 0) { fprintf(stderr, _("Error looking up mount '%s': %s\n"), argv[optind], strerror(errno)); exit(EXIT_FAILURE); } if (mnt == NULL) { fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), argv[optind]); continue; } if (lgfs2_get_dev_info(sdp->device_fd, &sdp->dinfo) < 0) { perror(mnt->mnt_fsname); exit(EXIT_FAILURE); } sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE; sdp->bsize = sdp->sd_sb.sb_bsize; if (compute_constants(sdp)) { log_crit("%s\n", _("Failed to compute file system constants")); exit(EXIT_FAILURE); } if (read_sb(sdp) < 0) { fprintf(stderr, _("Error reading superblock.\n")); exit(EXIT_FAILURE); } if (sdp->gfs1) { fprintf(stderr, _("cannot grow gfs1 filesystem\n")); exit(EXIT_FAILURE); } fix_device_geometry(sdp); mfs.context = copy_context_opt(mnt); if (mount_gfs2_meta(&mfs, mnt->mnt_dir, (print_level > MSG_NOTICE))) { perror(_("Failed to mount GFS2 meta file system")); exit(EXIT_FAILURE); } rindex_fd = open_rindex(mfs.path, (test ? O_RDONLY : O_RDWR)); if (rindex_fd < 0) { cleanup_metafs(&mfs); exit(EXIT_FAILURE); } /* Get master dinode */ sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr); if (sdp->master_dir == NULL) { perror(_("Could not read master directory")); exit(EXIT_FAILURE); } rgs = rgrps_init(sdp); if (rgs == NULL) { perror(_("Could not initialise resource groups")); error = -1; goto out; } /* Fetch the rindex from disk. We aren't using gfs2 here, */ /* which means that the bitmaps will most likely be cached */ /* and therefore out of date. It shouldn't matter because */ /* we're only going to write out new RG information after */ /* the existing RGs, and only write to the index at EOF. */ log_info(_("Gathering resource group information for %s\n"), argv[optind]); old_rg_count = lgfs2_rindex_read_fd(rindex_fd, rgs); if (old_rg_count == 0) { perror(_("Failed to scan existing resource groups")); error = -EXIT_FAILURE; goto out; } if (metafs_interrupted) goto out; fssize = lgfs2_rgrp_align_addr(rgs, filesystem_size(rgs) + 1); /* We're done with the old rgs now that we have the fssize and rg count */ lgfs2_rgrps_free(&rgs); /* Now lets set up the new ones with alignment and all */ rgs = rgrps_init(sdp); if (rgs == NULL) { perror(_("Could not initialise new resource groups")); error = -1; goto out; } fsgrowth = (sdp->device.length - fssize); rgcount = lgfs2_rgrps_plan(rgs, fsgrowth, ((GFS2_MAX_RGSIZE << 20) / sdp->bsize)); if (rgcount == 0) { log_err( _("The calculated resource group size is too small.\n")); log_err( _("%s has not grown.\n"), argv[optind]); error = -1; goto out; } print_info(sdp, mnt->mnt_fsname, mnt->mnt_dir); rgcount = initialize_new_portion(sdp, rgs); if (rgcount == 0 || metafs_interrupted) goto out; fsync(sdp->device_fd); fix_rindex(rindex_fd, rgs, old_rg_count, rgcount); out: lgfs2_rgrps_free(&rgs); close(rindex_fd); cleanup_metafs(&mfs); close(sdp->device_fd); if (metafs_interrupted) break; } close(sdp->path_fd); sync(); if (metafs_interrupted) { log_notice( _("gfs2_grow interrupted.\n")); exit(1); } log_notice( _("gfs2_grow complete.\n")); return error; }
// 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; }