void normalize_data_to_match_target(VIO_Volume d1, VIO_Volume m1, VIO_Real thresh1, VIO_Volume d2, VIO_Volume m2, VIO_Real thresh2, Arg_Data *globals) { VectorR vector_step; PointR starting_position, slice, row, col, pos2, voxel; double tx,ty,tz; int i,j,k, r,c,s; VIO_Real min_range, max_range, data_vox, data_val, value1, value2; VIO_Real t1,t2, /* temporary threshold values */ s1,s2,s3; /* to store the sums for f1,f2,f3 */ float *ratios, result; /* the result */ int sizes[VIO_MAX_DIMENSIONS],ratios_size,count1,count2; VIO_Volume vol; VIO_progress_struct progress; VIO_Data_types data_type; set_feature_value_threshold(d1,d2, &thresh1, &thresh2, &t1, &t2); if (globals->flags.debug) { print ("In normalize_data_to_match_target, thresh = %10.3f %10.3f\n",t1,t2) ; } ratios_size = globals->count[ROW_IND] * globals->count[COL_IND] * globals->count[SLICE_IND]; ALLOC(ratios, ratios_size); fill_Point( starting_position, globals->start[VIO_X], globals->start[VIO_Y], globals->start[VIO_Z]); s1 = s2 = s3 = 0.0; count1 = count2 = 0; for(s=0; s<=globals->count[SLICE_IND]; s++) { SCALE_VECTOR( vector_step, globals->directions[SLICE_IND], s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=globals->count[ROW_IND]; r++) { SCALE_VECTOR( vector_step, globals->directions[ROW_IND], r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=globals->count[COL_IND]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { value1 = get_value_of_point_in_volume( Point_x(col), Point_y(col), Point_z(col), d1); if ( value1 > t1 ) { count1++; DO_TRANSFORM(pos2, globals->trans_info.transformation, col); convert_3D_world_to_voxel(d2, Point_x(pos2), Point_y(pos2), Point_z(pos2), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m2, Point_x(pos2), Point_y(pos2), Point_z(pos2))) { value2 = get_value_of_point_in_volume( Point_x(pos2), Point_y(pos2), Point_z(pos2), d2); if ( (value2 > t2) && ((value2 < -1e-15) || (value2 > 1e-15)) ) { ratios[count2++] = value1 / value2 ; s1 += value1*value2; s2 += value1*value1; s3 += value2*value2; } /* if voxel in d2 */ } /* if point in mask volume two */ } /* if voxel in d1 */ } /* if point in mask volume one */ ADD_POINT_VECTOR( col, col, globals->directions[COL_IND] ); } /* for c */ } /* for r */ } /* for s */ if (count2 > 0) { if (globals->flags.debug) (void)print ("Starting qsort of ratios..."); qs_list (ratios,0,count2); if (globals->flags.debug) (void)print ("Done.\n"); result = ratios[ (int)(count2/2) ]; /* the median value */ if (globals->flags.debug) (void)print ("Normalization: %7d %7d -> %10.8f\n",count1,count2,result); if ( fabs(result) < 1e-15) { print_error_and_line_num("Error computing normalization ratio `%f'.",__FILE__, __LINE__, result); } else { data_type = get_volume_data_type(d1); switch( data_type ) { case SIGNED_BYTE: case UNSIGNED_BYTE: case SIGNED_SHORT: case UNSIGNED_SHORT: /* build temporary working volume */ vol = copy_volume_definition_no_alloc(d1, NC_UNSPECIFIED, FALSE, 0.0, 0.0); get_volume_minimum_maximum_real_value(d1, &min_range, &max_range); min_range /= result; max_range /= result; set_volume_real_range(vol, min_range, max_range); get_volume_sizes(d1, sizes); initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1, "Normalizing source data" ); count1 = 0; /* reset values in the data volume */ for(i=0; i<sizes[0]; i++) for(j=0; j<sizes[1]; j++) { count1++; update_progress_report( &progress, count1); for(k=0; k<sizes[2]; k++) { GET_VOXEL_3D( data_vox, d1, i, j, k ); data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); data_val /= result; data_vox = CONVERT_VALUE_TO_VOXEL( vol, data_val); SET_VOXEL_3D( d1 , i, j, k, data_vox ); } } terminate_progress_report( &progress ); set_volume_real_range(d1, min_range, max_range); if (globals->flags.debug) (void)print ("After normalization min,max, thresh = %f %f %f\n", min_range, max_range, t1/result); delete_volume(vol); break; default: /* then volume should be either float or double */ get_volume_sizes(d1, sizes); initialize_progress_report(&progress, FALSE, sizes[0]*sizes[1]*sizes[2] + 1, "Normalizing source data" ); count1 = 0; /* nomalize the values in the data volume */ for(i=0; i<sizes[0]; i++) for(j=0; j<sizes[1]; j++) { count1++; update_progress_report( &progress, count1); for(k=0; k<sizes[2]; k++) { /* it should be possible to directly stream through the voxels, without indexing... */ GET_VOXEL_3D( data_vox, d1, i, j, k ); data_val = CONVERT_VOXEL_TO_VALUE(d1, data_vox); data_val /= result; data_vox = CONVERT_VALUE_TO_VOXEL( d1, data_val); SET_VOXEL_3D( d1 , i, j, k, data_vox ); } } terminate_progress_report( &progress ); } } } FREE(ratios); }
VIO_BOOL vol_to_cov(VIO_Volume d1, VIO_Volume m1, float centroid[4], float covar[4][4], double *step) { VectorR vector_step, slice_step, row_step, col_step; PointR starting_offset, starting_origin, starting_position, slice, row, col, voxel; VIO_Real tx,ty,tz; int i,r,c,s, limits[VOL_NDIMS]; float t, sxx,syy,szz, sxy,syz,sxz, sx,sy,sz,si; VIO_Real thickness[3]; int sizes[3]; VIO_Real true_value; get_volume_separations(d1, thickness); get_volume_sizes(d1, sizes); /* build sampling lattice info */ for(i=0; i<3; i++) { step[i] *= thickness[i] / fabs( thickness[i]); } fill_Vector( col_step, step[COL_IND], 0.0, 0.0 ); fill_Vector( row_step, 0.0, step[ROW_IND], 0.0 ); fill_Vector( slice_step, 0.0, 0.0, step[SLICE_IND] ); convert_3D_voxel_to_world(d1, 0.0, 0.0, 0.0, &tx, &ty, &tz); fill_Point( starting_origin, tx, ty, tz); for(i=0; i<3; i++) { /* for each dim, get # of steps in that direction, and set starting offset */ t = sizes[i] * thickness[i] / step[i]; limits[i] = abs( t ); Point_coord( starting_offset, (i) ) = ( (sizes[i]-1)*thickness[i] - (limits[i] * step[i] ) ) / 2.0; } ADD_POINTS( starting_position, starting_origin, starting_offset ); /* */ /* calculate centroids first */ sx = 0.0; sy = 0.0; sz = 0.0; si = 0.0; for(s=0; s<=limits[SLICE_IND]; s++) { SCALE_VECTOR( vector_step, slice_step, s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=limits[ROW_IND]; r++) { SCALE_VECTOR( vector_step, row_step, r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=limits[COL_IND]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) { sx += Point_x(col) * true_value; sy += Point_y(col) * true_value; sz += Point_z(col) * true_value; si += true_value; } /* else requested voxel is just outside volume., so ignore it */ } ADD_POINT_VECTOR( col, col, col_step ); } } } if (si!=0.0) { centroid[1] = sx/ si; centroid[2] = sy/ si; centroid[3] = sz/ si; sxx = syy = szz = 0.0; sxy = syz = sxz = 0.0; /* now calculate variances and co-variances */ for(s=0; s<=limits[VIO_Z]; s++) { SCALE_VECTOR( vector_step, slice_step, s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=limits[VIO_Y]; r++) { SCALE_VECTOR( vector_step, row_step, r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=limits[VIO_X]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) { sxx += (Point_x( col )-centroid[1]) * (Point_x( col )-centroid[1]) * true_value; syy += (Point_y( col )-centroid[2]) * (Point_y( col )-centroid[2]) * true_value; szz += (Point_z( col )-centroid[3]) * (Point_z( col )-centroid[3]) * true_value; sxy += (Point_x( col )-centroid[1]) * (Point_y( col )-centroid[2]) * true_value; syz += (Point_y( col )-centroid[2]) * (Point_z( col )-centroid[3]) * true_value; sxz += (Point_x( col )-centroid[1]) * (Point_z( col )-centroid[3]) * true_value; } /* else requested voxel is just outside volume., so ignore it */ } ADD_POINT_VECTOR( col, col, col_step ); } } } covar[1][1] = sxx/si; covar[1][2] = sxy/si; covar[1][3] = sxz/si; covar[2][1] = sxy/si; covar[2][2] = syy/si; covar[2][3] = syz/si; covar[3][1] = sxz/si; covar[3][2] = syz/si; covar[3][3] = szz/si; return(TRUE); } else { return(FALSE); } }
void add_speckle_to_volume(VIO_Volume d1, float speckle, double *start, int *count, VectorR directions[]) { VectorR vector_step; PointR starting_position, slice, row, col; VIO_Real valid_min_voxel, valid_max_voxel; double tx,ty,tz, voxel_value; int xi,yi,zi, flip_flag,r,c,s; flip_flag = FALSE; get_volume_voxel_range(d1, &valid_min_voxel, &valid_max_voxel); fill_Point( starting_position, start[0], start[1], start[2]); for(s=0; s<count[SLICE_IND]; s++) { SCALE_VECTOR( vector_step, directions[SLICE_IND], s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<count[ROW_IND]; r++) { SCALE_VECTOR( vector_step, directions[ROW_IND], r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<count[COL_IND]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); xi = (int)floor(tx + 0.5); yi = (int)floor( ty + 0.5); zi = (int)floor( tz + 0.5 ); GET_VOXEL_3D( voxel_value, d1 , xi, yi, zi ); if (voxel_value >= valid_min_voxel && voxel_value <= valid_max_voxel) { if (flip_flag) voxel_value = voxel_value * (1 + 0.01*speckle); else voxel_value = voxel_value * (1 - 0.01*speckle); SET_VOXEL_3D( d1 , xi, yi, zi, voxel_value ); } flip_flag = !flip_flag; ADD_POINT_VECTOR( col, col, directions[COL_IND] ); } } } }