static plane bisection_plane(unsigned n, point o[]) { point com = center_of_mass(n, o); basis im = inertia_matrix(n, o, com); point axis = min_eigenvec(im); return median_plane(n, o, axis); }
static int private_add_shape ( LIPhyShape* self, btConvexShape* shape, const LIMatTransform* transform) { btVector3 p(0.0f, 0.0f, 0.0f); btQuaternion r(0.0f, 0.0f, 0.0f, 1.0f); btTransform center_of_mass(r, btVector3 ( self->center_of_mass.x, self->center_of_mass.y, self->center_of_mass.z)); if (transform != NULL) { p = btVector3 (transform->position.x, transform->position.y, transform->position.z); r = btQuaternion(transform->rotation.x, transform->rotation.y, transform->rotation.z, transform->rotation.w); } try { self->shape->addChildShape (center_of_mass.inverse() * btTransform (r, p), shape); } catch (...) { return 0; } /* Update the bounding box. */ btVector3 min; btVector3 max; self->shape->getAabb(btTransform::getIdentity (), min, max); self->bounds.min = limat_vector_init (min[0], min[1], min[2]); self->bounds.max = limat_vector_init (max[0], max[1], max[2]); return 1; }
void map_fragment::center_by_mass() { shift(center_of_mass().vector_negation()); area_.clear(); for (tile_info& ti : items_) { area_.insert(ti.offset); } }
static void compute_vectors(SegmentArray* segments, SkPoint* fanPt, SkPath::Direction dir, int* vCount, int* iCount) { center_of_mass(*segments, fanPt); int count = segments->count(); // Make the normals point towards the outside SkPoint::Side normSide; if (dir == SkPath::kCCW_Direction) { normSide = SkPoint::kRight_Side; } else { normSide = SkPoint::kLeft_Side; } *vCount = 0; *iCount = 0; // compute normals at all points for (int a = 0; a < count; ++a) { Segment& sega = (*segments)[a]; int b = (a + 1) % count; Segment& segb = (*segments)[b]; const SkPoint* prevPt = &sega.endPt(); int n = segb.countPoints(); for (int p = 0; p < n; ++p) { segb.fNorms[p] = segb.fPts[p] - *prevPt; segb.fNorms[p].normalize(); segb.fNorms[p].setOrthog(segb.fNorms[p], normSide); prevPt = &segb.fPts[p]; } if (Segment::kLine == segb.fType) { *vCount += 5; *iCount += 9; } else { *vCount += 6; *iCount += 12; } } // compute mid-vectors where segments meet. TODO: Detect shallow corners // and leave out the wedges and close gaps by stitching segments together. for (int a = 0; a < count; ++a) { const Segment& sega = (*segments)[a]; int b = (a + 1) % count; Segment& segb = (*segments)[b]; segb.fMid = segb.fNorms[0] + sega.endNorm(); segb.fMid.normalize(); // corner wedges *vCount += 4; *iCount += 6; } }
struct tvector* negative_center_of_mass (struct atomgrp* ag) { struct tvector* tvec = center_of_mass (ag); // negate the tvec tvec->X = -tvec->X; tvec->Y = -tvec->Y; tvec->Z = -tvec->Z; return tvec; }
template <> complex_number Graph<Circle>::direction_from_center_of_mass(const unsigned int &index) const { if (index > vertices_.size()) { std::cout << "ERROR in Graph<Point>::direction_from_center_of_mass: bad index" << std::endl; throw(QString("ERROR in Graph<Point>::direction_from_center_of_mass: bad index")); } complex_number u = get_affix_by_index(index) - center_of_mass().get_affix(); return u/abs(u); }
int main(int argc, char *argv[]) { int dims = 2; int nr_particles = 5; if (argc > 1) dims = atoi(argv[1]); if (argc > 2) nr_particles = atoi(argv[2]); System *system = init_system(nr_particles, dims); print_system(system); printf("total mass = %lf\n", total_mass(system)); double cms[dims]; center_of_mass(system, cms); print_position(cms, dims); free_system(system); return EXIT_SUCCESS; }
float* moment_of_inertia (struct atomgrp* ag) { struct tvector* com = center_of_mass (ag); float sq_x_com = powf (com->X, 2.0); float sq_y_com = powf (com->Y, 2.0); float sq_z_com = powf (com->Z, 2.0); float sum_sq_x = 0; float sum_sq_y = 0; float sum_sq_z = 0; float sum_mult_xy = 0; float sum_mult_xz = 0; float sum_mult_yz = 0; int i; for (i = 0; i < ag->natoms; i++) { sum_sq_x += powf (ag->atoms[i].X, 2.0); sum_sq_y += powf (ag->atoms[i].Y, 2.0); sum_sq_z += powf (ag->atoms[i].Z, 2.0); sum_mult_xy += ag->atoms[i].X * ag->atoms[i].Y; sum_mult_xz += ag->atoms[i].X * ag->atoms[i].Z; sum_mult_yz += ag->atoms[i].Y * ag->atoms[i].Z; } float* moi_matrix = (float*) _mol_malloc (sizeof (float) * 9); moi_matrix[0] = sum_sq_y + sum_sq_z - (sq_y_com + sq_z_com) * ag->natoms; moi_matrix[1] = -sum_mult_xy + com->X * com->Y * ag->natoms; moi_matrix[2] = -sum_mult_xz + com->X * com->Z * ag->natoms; moi_matrix[3] = -sum_mult_xy + com->X * com->Y * ag->natoms; moi_matrix[4] = sum_sq_x + sum_sq_z - (sq_x_com + sq_z_com) * ag->natoms; moi_matrix[5] = -sum_mult_yz + com->Y * com->Z * ag->natoms; moi_matrix[6] = -sum_mult_xz + com->X * com->Z * ag->natoms; moi_matrix[7] = -sum_mult_yz + com->Y * com->Z * ag->natoms; moi_matrix[8] = sum_sq_x + sum_sq_y - (sq_x_com + sq_y_com) * ag->natoms; free (com); return moi_matrix; }
int main(int argc, char **argv) { Ics_Error icserr; ICS* ics; size_t dims[ICS_MAXDIM]; int ndims; int i,j; Ics_DataType dt; char fname[32]; char cmdlin[256]; /* TODO */ pix_type *prev; /* previous frame */ unsigned char *buf; /* 8-bit buffer */ int startframe,endframe; int *tmp; int *probb; int *prob; int *imsob; FILE *f; int w,h; int err; /* unsigned char *wsh; */ int markx[2],marky[2]; unsigned char *wsh; if(argc < 2){ printf(" usage: edgeprob <filename>.ics <prob.pgm> [startframe [endframe]] [-e cutoff]\n"); printf(" example: edgeprob livecell.ics livecell1.pgm 30 35 e\n"); printf(" center of cell should be marked with single dot of intensity 128\n"); printf(" does all frames if start frame not specified\n"); return 0; } /* Open file */ icserr = IcsOpen(&ics, argv[1], "r"); ICS_CHECK(icserr); #ifdef DEBUG_PRINT printf("ics file loaded.\n"); #endif /* Sniff out file; make sure it is compatible with our prog */ icserr = IcsGetLayout(ics, &dt, &ndims, dims); ICS_CHECK(icserr); if(dt != Ics_uint16){ printf("Sorry, image modes other than 16-bit (unsigned) "); printf("not supported at the moment.\n"); return 0; } /* number of frames specified */ startframe = 0; endframe = dims[3]; if(argc >= 4){ startframe = strtol(argv[3],NULL,0); if(startframe > dims[3]) startframe = dims[3]; if(startframe < 0){ printf("Start frame number must be non-negative.\n"); return 1; } if(argc >= 5){ endframe = strtol(argv[4],NULL,0); if(endframe < startframe){ printf("End frame number must be greater than start.\n"); return 2; } if(endframe > dims[3]) endframe = dims[3]; } } #ifdef DEBUG_PRINT printf("dimensions: "); for(i=0;i<ndims;i++) printf("%ld ", dims[i]); printf("data type: %d \n", dt); #endif /* TODO: warning if dimensions look non-standard */ /* allocate space before reading */ /* Only allocate for one frame; allows images with many frames * to be loaded without much memory, unlike some programs * (I'm looking at you, ics_opener/ImageJ ! */ prev = (pix_type *) malloc(dims[1]*dims[2]*sizeof(pix_type)); buf = (unsigned char *)malloc(dims[1]*dims[2]*sizeof(unsigned char)); tmp = (int *) malloc(dims[1]*dims[2]*sizeof(int)); probb = (int *) malloc(dims[1]*dims[2]*sizeof(int)); prob = (int *) malloc(dims[1]*dims[2]*sizeof(int)); imsob = (int *) malloc(dims[1]*dims[2]*sizeof(int)); wsh = (unsigned char *)malloc(dims[1]*dims[2]*sizeof(unsigned char)); if((!prev)||(!buf)||(!tmp)||(!probb)||(!prob)||(!imsob)||(!wsh)) { printf("Couldn't allocate enough memory.\n"); return 1; } /* load probabilities */ f = fopen(argv[2],"r"); if(!f){ printf("Error: could not open file %s\n",argv[2]); return 10; } if((err = load_data(f, &prob, &w, &h))){ printf("Error: %s: incorrect or corrupt pgm file.\n",argv[2]); return 11; } if((w!=dims[1])||(h!=dims[2])){ printf("Error: Size mismatch. ICS data are %ldx%ld but probability data are %dx%d\n", dims[1],dims[2],w,h); return 9; } fclose(f); /* obtain marker from prob image */ markx[0]=10; marky[0]=10; markx[1]=markx[0]; marky[1]=marky[0]; for(j=0;j<dims[2];j++){ for(i=0;i<dims[1];i++){ if(prob[j*dims[1] + i]==128){ markx[1]=i; marky[1]=j; } } } if((markx[0]==markx[1])&&(marky[1]==marky[0])){ printf("Error: marker not found in prob image.\n"); printf("(should be single pixel with intensity 128)\n"); return 8; } printf("tracking...\n"); /* read sequentially from file. */ /* Each call to IcsGetDataBlock proceeds from the end of the last */ for(i=0;i<endframe;i++){ icserr = IcsGetDataBlock(ics, prev, dims[1]*dims[2]*2); ICS_CHECK(icserr); if(i>=startframe){ /* blur probabilities */ memcpy(probb, prob, sizeof(int)*dims[1]*dims[2]); blur_diffuse(probb, tmp, dims[1], dims[2]); blur_diffuse(tmp, probb, dims[1], dims[2]); blur_cusp(probb, tmp, dims[1], dims[2], 210); blur_diffuse(probb, tmp, dims[1], dims[2]); blur_diffuse(tmp, probb, dims[1], dims[2]); /* come up with new probabilities */ im2int(prev, tmp, dims[1], dims[2]); sobel(tmp, imsob, dims[1], dims[2]); /* convert to probability */ for(j=0;j<dims[1]*dims[2];j++){ imsob[j] >>= 4; if(imsob[j]>255) imsob[j]=255; } /* mix them up */ combine_prob(probb, imsob, prob, dims[1], dims[2]); normalize_prob(prob, dims[1], dims[2]); /* watershed to 'collapse' probabilities */ /*watershed(prob, wsh, tmp, dims[1], dims[2], markx, marky, 2); for(j=0;j<dims[1]*dims[2];j++){ wsh[j] = (wsh[j]==2 ? 8 : 0); }*/ watershed_rep(prob, buf, tmp, dims[1], dims[2], markx, marky, 2, wsh, 8, 24.0); center_of_mass(wsh, dims[1], dims[2], 8, markx, marky); hardedge(wsh, buf, dims[1], dims[2]); /* now combine the existing probabilities with the ones from hardedge */ for(j=0;j<dims[1]*dims[2];j++){ if(buf[j]==255) prob[j]=(3*255+prob[j])/4; } for(j=0;j<dims[1]*dims[2];j++) buf[j]=prob[j]; printf("frame %d\n", i); sprintf(fname, "prob_%04d.png", i); export_8bit_pgm(buf, dims[1], dims[2], "tmp.pgm"); sprintf(cmdlin, "pnmtopng -compression 1 < tmp.pgm > %s", fname); system(cmdlin); } }
virtual void init(Voxel& voxel) { if(voxel.vs[0] == 0.0 || voxel.vs[1] == 0.0 || voxel.vs[2] == 0.0) throw std::runtime_error("No spatial information found in src file. Recreate src file or contact developer for assistance"); begin_prog("normalization"); VG = fa_template_imp.I; VF = voxel.fa_map; image::filter::gaussian(voxel.fa_map); image::filter::gaussian(voxel.fa_map); image::filter::gaussian(voxel.qa_map); image::filter::gaussian(voxel.qa_map); image::normalize(voxel.fa_map,1.0); image::normalize(voxel.qa_map,1.0); for(unsigned int index = 0;index < voxel.qa_map.size();++index) if(voxel.qa_map[index] == 0.0 || voxel.fa_map[index]/voxel.qa_map[index] > 2.5) VF[index] = 0.0; image::filter::gaussian(VF); src_geo = VF.geometry(); image::normalize(VF,1.0); //VF.save_to_file<image::io::nifti<> >("VF.nii"); image::normalize(VG,1.0); // get rid of the gray matters image::minus_constant(VF.begin(),VF.end(),0.3); image::lower_threshold(VF.begin(),VF.end(),0.00); image::normalize(VF,1.0); image::minus_constant(VG.begin(),VG.end(),0.3); image::lower_threshold(VG.begin(),VG.end(),0.00); image::normalize(VG,1.0); VGvs[0] = std::fabs(fa_template_imp.tran[0]); VGvs[1] = std::fabs(fa_template_imp.tran[5]); VGvs[2] = std::fabs(fa_template_imp.tran[10]); image::affine_transform<3,double> arg_min; // VG: FA TEMPLATE // VF: SUBJECT QA arg_min.scaling[0] = voxel.vs[0] / VGvs[0]; arg_min.scaling[1] = voxel.vs[1] / VGvs[1]; arg_min.scaling[2] = voxel.vs[2] / VGvs[2]; voxel_volume_scale = arg_min.scaling[0]*arg_min.scaling[1]*arg_min.scaling[2]; // calculate center of mass image::vector<3,double> mF = center_of_mass(VF); image::vector<3,double> mG = center_of_mass(VG); arg_min.translocation[0] = mG[0]-mF[0]*arg_min.scaling[0]; arg_min.translocation[1] = mG[1]-mF[1]*arg_min.scaling[1]; arg_min.translocation[2] = mG[2]-mF[2]*arg_min.scaling[2]; bool terminated = false; set_title("linear registration"); begin_prog("conducting registration"); check_prog(0,2); image::reg::linear(VF,VG,arg_min,image::reg::affine,image::reg::square_error(),terminated,0.25); check_prog(1,2); // create VFF the affine transformed VF image::basic_image<float,3> VFF(VG.geometry()); { affine = arg_min; image::reg::linear_get_trans(VF.geometry(),VG.geometry(),affine); { std::vector<double> T(16); affine.save_to_transform(T.begin()); T[15] = 1.0; math::matrix_inverse(T.begin(),math::dim<4,4>()); affine.load_from_transform(T.begin()); } image::resample(VF,VFF,affine); //VFF.save_to_file<image::io::nifti<> >("VFF.nii"); //VG.save_to_file<image::io::nifti<> >("VG.nii"); } { switch(voxel.reg_method) { case 0: mni.normalize(VG,VFF); break; case 1: mni.normalize(VG,VFF,12,14,12,4,8); break; } //calculate the goodness of fit std::vector<float> x,y; x.reserve(VG.size()); y.reserve(VG.size()); image::interpolation<image::linear_weighting,3> trilinear_interpolation; for(image::pixel_index<3> index;VG.geometry().is_valid(index); index.next(VG.geometry())) if(VG[index.index()] != 0) { image::vector<3,double> pos; mni.warp_coordinate(index,pos); double value = 0.0; if(!trilinear_interpolation.estimate(VFF,pos,value)) continue; x.push_back(VG[index.index()]); y.push_back(value); } R2 = x.empty() ? 0.0 : image::correlation(x.begin(),x.end(),y.begin()); R2 *= R2; std::cout << "R2 = " << R2 << std::endl; } check_prog(2,2); // setup output bounding box { //setBoundingBox(-78,-112,-50,78,76,85,1.0); float voxel_size = voxel.param[1]; bounding_box_lower[0] = std::floor(-78.0/voxel_size+0.5)*voxel_size; bounding_box_lower[1] = std::floor(-112.0/voxel_size+0.5)*voxel_size; bounding_box_lower[2] = std::floor(-50.0/voxel_size+0.5)*voxel_size; bounding_box_upper[0] = std::floor(78.0/voxel_size+0.5)*voxel_size; bounding_box_upper[1] = std::floor(76.0/voxel_size+0.5)*voxel_size; bounding_box_upper[2] = std::floor(85.0/voxel_size+0.5)*voxel_size; des_geo[0] = (bounding_box_upper[0]-bounding_box_lower[0])/voxel_size+1;//79 des_geo[1] = (bounding_box_upper[1]-bounding_box_lower[1])/voxel_size+1;//95 des_geo[2] = (bounding_box_upper[2]-bounding_box_lower[2])/voxel_size+1;//69 des_offset[0] = bounding_box_lower[0]/VGvs[0]-fa_template_imp.tran[3]/fa_template_imp.tran[0]; des_offset[1] = bounding_box_lower[1]/VGvs[1]-fa_template_imp.tran[7]/fa_template_imp.tran[5]; des_offset[2] = bounding_box_lower[2]/VGvs[2]-fa_template_imp.tran[11]/fa_template_imp.tran[10]; scale[0] = voxel_size/VGvs[0]; scale[1] = voxel_size/VGvs[1]; scale[2] = voxel_size/VGvs[2]; } begin_prog("q-space diffeomorphic reconstruction"); float sigma = voxel.param[0]; //diffusion sampling length ratio, optimal 1.24 // setup mask { // set the current mask to template space voxel.image_model->set_dimension(des_geo[0],des_geo[1],des_geo[2]); for(image::pixel_index<3> index;des_geo.is_valid(index);index.next(des_geo)) { image::vector<3,int> mni_pos(index); mni_pos *= voxel.param[1]; mni_pos[0] /= VGvs[0]; mni_pos[1] /= VGvs[1]; mni_pos[2] /= VGvs[2]; mni_pos += des_offset; voxel.image_model->mask[index.index()] = fa_template_imp.I.at(mni_pos[0],mni_pos[1],mni_pos[2]) > 0.0? 1: 0; } } q_vectors_time.resize(voxel.bvalues.size()); for (unsigned int index = 0; index < voxel.bvalues.size(); ++index) { q_vectors_time[index] = voxel.bvectors[index]; q_vectors_time[index] *= std::sqrt(voxel.bvalues[index]*0.01506);// get q in (mm) -1 q_vectors_time[index] *= sigma; } b0_index = -1; if(voxel.half_sphere) for(unsigned int index = 0;index < voxel.bvalues.size();++index) if(voxel.bvalues[index] == 0) b0_index = index; ptr_images.clear(); for (unsigned int index = 0; index < voxel.image_model->dwi_data.size(); ++index) ptr_images.push_back(point_image_type((const unsigned short*)voxel.image_model->dwi_data[index],src_geo)); voxel.qa_scaling = voxel.reponse_function_scaling/voxel.vs[0]/voxel.vs[1]/voxel.vs[2]; max_accumulated_qa = 0; std::fill(voxel.vs.begin(),voxel.vs.end(),voxel.param[1]); jdet.resize(des_geo.size()); if (voxel.odf_deconvolusion) { gqi.init(voxel); deconvolution.init(voxel); } if (voxel.odf_decomposition) { gqi.init(voxel); decomposition.init(voxel); } angle_variance = 8; //degress; angle_variance *= M_PI/180; angle_variance *= angle_variance; angle_variance *= 2.0; }
// EVT_SNAPSHOT std::ostream& record_output_1(std::ostream &out, gpulog::logrecord &lr, swarm::body_range_t &body_range) { double time; int nbod, sys, flags; const body *bodies; lr >> time >> sys >> flags >> nbod >> bodies; body center; const swarm::body &star = bodies[0]; switch(planets_coordinate_system) { case astrocentric: center = star; break; case barycentric: center = center_of_mass( bodies, nbod ); break; case jacobi: center = star; break; case origin: center.x = center.y = center.z = center.vx = center.vy = center.vz = 0.; center.mass = star.mass; break; }; if((time<=0.) && false) // was used for debugging at some point { if (keplerian_output) { std::cerr << "# Output in Keplerian coordinates "; } else { std::cerr << "# Output in Cartesian coordinates "; } switch(planets_coordinate_system) { case astrocentric: std::cerr << "(astrocentric) " << center.x << ' ' << center.y << ' '<< center.z << " " << center.vx << ' ' << center.vy << ' ' << center.vz; break; case barycentric: std::cerr << "(barycentric) "<< center.x << ' ' << center.y << ' '<< center.z << " " << center.vx << ' ' << center.vy << ' ' << center.vz; break; case jacobi: std::cerr << "(jacobi) " << center.x << ' ' << center.y << ' '<< center.z << " " << center.vx << ' ' << center.vy << ' ' << center.vz; break; case origin: std::cerr << "(origin) " << center.x << ' ' << center.y << ' '<< center.z << " " << center.vx << ' ' << center.vy << ' ' << center.vz; break; } std::cerr << "\n"; } size_t bufsize = 1000; char buf[bufsize]; for(int bod = 0; bod < nbod; bod++) { if(!body_range.in(bod)) { continue; } const swarm::body &b = bodies[bod]; if( keplerian_output && (bod==0) ) { continue; } if( (planets_coordinate_system==jacobi) && (bod==0) ) { continue; } if( ( !keplerian_output && (planets_coordinate_system!=jacobi) && (bod> 0) ) || ( !keplerian_output && (planets_coordinate_system==jacobi) && (bod> 1) ) || ( keplerian_output && (bod> 1 ) ) ){ out << "\n"; } if( planets_coordinate_system == jacobi ) { center = center_of_mass ( bodies, bod); } if( keplerian_output && bod > 0) { if(planets_coordinate_system==barycentric) center.mass -= b.mass; keplerian_t orbit = keplerian_for_cartesian( b, center ); if(planets_coordinate_system==barycentric) center.mass += b.mass; const double rad2deg = 180./M_PI; snprintf(buf, bufsize, "%10d %lg %6d %6d %lg % 9.5lg % 9.5lg % 9.5lg % 9.5lg % 9.5lg % 9.5lg %d", lr.msgid(), time, sys, bod, b.mass, orbit.a, orbit.e , orbit.i*rad2deg, orbit.O*rad2deg, orbit.w *rad2deg, orbit.M*rad2deg, flags); } if(!keplerian_output) { double x = b.x - center.x; double y = b.y - center.y; double z = b.z - center.z; double vx= b.vx- center.vx; double vy= b.vy- center.vy; double vz= b.vz- center.vz; snprintf(buf, bufsize, "%10d %lg %6d %6d %lg %9.5lg %9.5lg %9.5lg %9.5lg %9.5lg %9.5lg %d", lr.msgid(), time, sys, bod, b.mass, x, y, z, vx, vy, vz, flags); } out << buf; // << "\n"; } return out; }
int main(int argc, char **argv) { Ics_Error icserr; ICS* ics; size_t dims[ICS_MAXDIM]; int ndims; int i,j; Ics_DataType dt; /* TODO */ pix_type *prev; /* previous frame */ unsigned char *buf; /* 8-bit buffer */ int startframe,endframe; int *tmp1,*tmp2,*var,*sob; int xmark[2],ymark[2]; unsigned char *wsh; FILE *comf; char fname[64],cmdlin[128]; if(argc < 4){ printf("usage: nucfollow <filename>.ics <x> <y> [startframe [endframe]] [-e cutoff]\n"); printf("(x,y) is the coordinate of the nucleus at first iteration.\n"); printf("example: nucfollow livecell.ics 400 300 30\n"); printf("extracts all frames if start frame not specified\n"); return 0; } /* Open file */ icserr = IcsOpen(&ics, argv[1], "r"); ICS_CHECK(icserr); #ifdef DEBUG_PRINT printf("ics file loaded.\n"); #endif /* Sniff out file; make sure it is compatible with our prog */ icserr = IcsGetLayout(ics, &dt, &ndims, dims); ICS_CHECK(icserr); if(dt != Ics_uint16){ printf("Sorry, image modes other than 16-bit (unsigned) "); printf("not supported at the moment.\n"); return 0; } /* marker */ xmark[0] = 10; ymark[0] = 10; xmark[1] = strtol(argv[2],NULL,0); ymark[1] = strtol(argv[3],NULL,0); /* number of frames specified */ startframe = 0; endframe = 1; if(argc >= 5){ startframe = strtol(argv[4],NULL,0); if(startframe > dims[3]) startframe = dims[3]; if(startframe < 0){ printf("Start frame number must be non-negative.\n"); return 1; } if(argc >= 6){ endframe = strtol(argv[5],NULL,0); if(endframe < startframe){ printf("End frame number must be greater than start.\n"); return 2; } if(endframe > dims[3]) endframe = dims[3]; } else { endframe = startframe+1; } } #ifdef DEBUG_PRINT printf("dimensions: "); for(i=0;i<ndims;i++) printf("%ld ", dims[i]); printf("data type: %d \n", dt); #endif /* TODO: warning if dimensions look non-standard */ /* allocate space before reading */ /* Only allocate for one frame; allows images with many frames * to be loaded without much memory, unlike some programs * (I'm looking at you, ics_opener/ImageJ ! */ prev = malloc(dims[1]*dims[2]*sizeof(pix_type)); buf = malloc(dims[1]*dims[2]*sizeof(unsigned char)); tmp1 = (int *)malloc(dims[1]*dims[2]*sizeof(int)); tmp2 = (int *)malloc(dims[1]*dims[2]*sizeof(int)); var = (int *)malloc(dims[1]*dims[2]*sizeof(int)); sob = (int *)malloc(dims[1]*dims[2]*sizeof(int)); wsh = (unsigned char*)malloc(dims[1]*dims[2]*sizeof(int)); if((!prev)||(!buf)||(!tmp1)||(!tmp2)||(!var)||(!sob)||(!wsh)) { printf("Couldn't allocate enough memory.\n"); return 1; } /* open CoM file for output */ comf = fopen("comf.txt","w"); if(!comf){ printf("error: couldn't open comf.txt to write center of mass data!\n"); return 22; } fprintf(comf,"frame x y\n"); /* legend */ printf("tracking...\n"); /* read sequentially from file. */ /* Each call to IcsGetDataBlock proceeds from the end of the last */ for(i=0;i<endframe;i++){ icserr = IcsGetDataBlock(ics, prev, dims[1]*dims[2]*2); ICS_CHECK(icserr); if(i <startframe) continue; /* we are at the desired frame sequence. */ /* variance filter */ printf("frame %d\n", i); printf(" Variance filter...\n"); #if 0 if(variance(prev,var,tmp1,tmp2,dims[1],dims[2],1.0,4.0,12)) printf("Variance filter error!\n"); #endif fast_variance(prev, var, tmp1, dims[1], dims[2]); printf(" Cusp blur...\n"); blur_cusp(var,tmp1,dims[1],dims[2],230); /*printf("Diffusion blur...\n"); blur_diffuse(var,tmp2,dims[1],dims[2]); blur_diffuse(tmp2,var,dims[1],dims[2]); */ int maxo; maxo=0; for(j=0;j<dims[1]*dims[2];j++) if(var[j]>maxo) maxo=var[j]; printf(" maxo: %d\n", maxo); printf(" Sobel edge detection...\n"); sobel(var, sob, dims[1], dims[2]); /* reduce the output of sobel before watershed; * this greatly reduces processing time */ /* TODO: infer this from the actual histographic data */ for(j=0;j<dims[1]*dims[2];j++) sob[j] /= 10; for(j=0;j<dims[1]*dims[2];j++) if(sob[j]>255) sob[j]=255; printf(" watershed assembly...\n"); if(watershed_rep(sob, wsh, tmp1, dims[1], dims[2], xmark, ymark, 2, buf, 8, 8.0)){ printf(" error during watershed!\n"); return 1; } /* print center of mass to file */ fprintf(comf,"%d %d %d\n", i, xmark[1], ymark[1]); /* modify mark */ if(center_of_mass(buf, dims[1], dims[2], 8, xmark+1, ymark+1)){ printf(" zero identified regions!\n aborting.\n"); break; /* abort so we can at least see the results */ } /* output superimposed image */ for(j=0;j<dims[1]*dims[2];j++) wsh[j] = prev[j] >> 4; hardedge(buf, wsh, dims[1], dims[2]); sprintf(fname,"vesw_sup_%04d.pgm",i); export_8bit_pgm(wsh, dims[1], dims[2], fname); sprintf(cmdlin,"pnmtopng < %s > vesw_sup_%04d.png\nrm %s\n", fname, i, fname); if(system(cmdlin)){ printf("Error during NetPbm invoke!\n"); return 55; } } buf[ymark[1]*dims[1] + xmark[1]]=255-buf[ymark[1]*dims[1] + xmark[1]]; /* mark next CoM */ export_8bit_pgm(buf, dims[1], dims[2], "vesw.pgm"); for(j=0;j<dims[1]*dims[2];j++) buf[j] = var[j]/64; export_8bit_pgm(buf, dims[1], dims[2], "ve.pgm"); for(j=0;j<dims[1]*dims[2];j++) buf[j] = sob[j]/8; export_8bit_pgm(buf, dims[1], dims[2], "ves.pgm"); fclose(comf); /* no need to free memory; that's just silly */ IcsClose(ics); return 0; }