int vs_vector_append_dup(VSVector *V, void *data, int data_size){ assert(V && data); if(!V->data || V->buffersize < 1) vs_vector_init(V,4); void* d = vs_malloc(data_size); if(!d) return VS_ERROR; memcpy(d, data, data_size); return vs_vector_append(V, d); }
int* localmotions_gety(const LocalMotions* localmotions){ int len = vs_vector_size(localmotions); int* ys = vs_malloc(sizeof(int) * len); int i; for (i=0; i<len; i++){ ys[i]=LMGet(localmotions,i)->v.y; } return ys; }
Transform simpleMotionsToTransform(TransformData* td, const LocalMotions* motions){ int center_x = 0; int center_y = 0; Transform t = null_transform(); if(motions==0) return t; int num_motions=vs_vector_size(motions); double *angles = (double*) vs_malloc(sizeof(double) * num_motions); LocalMotion meanmotion; int i; if(num_motions < 1) return t; // calc center point of all remaining fields for (i = 0; i < num_motions; i++) { center_x += LMGet(motions,i)->f.x; center_y += LMGet(motions,i)->f.y; } center_x /= num_motions; center_y /= num_motions; // cleaned mean meanmotion = cleanmean_localmotions(motions); // figure out angle if (num_motions < 6) { // the angle calculation is inaccurate for 5 and less fields t.alpha = 0; } else { for (i = 0; i < num_motions; i++) { // substract avg and calc angle LocalMotion m = sub_localmotion(LMGet(motions,i),&meanmotion); angles[i] = calcAngle(&m, center_x, center_y); } double min, max; t.alpha = -cleanmean(angles, num_motions, &min, &max); if (max - min > td->maxAngleVariation) { t.alpha = 0; vs_log_info(td->modName, "too large variation in angle(%f)\n", max-min); } } vs_free(angles); // compensate for off-center rotation double p_x = (center_x - td->fiSrc.width / 2); double p_y = (center_y - td->fiSrc.height / 2); t.x = meanmotion.v.x + (cos(t.alpha) - 1) * p_x - sin(t.alpha) * p_y; t.y = meanmotion.v.y + sin(t.alpha) * p_x + (cos(t.alpha) - 1) * p_y; return t; }
/** * calulcates the cleaned maximum and minimum of an array of transforms, * considerung only x and y * It cuts off the upper and lower x-th percentil * * Parameters: * transforms: array of transforms. * len: length of array * percentil: the x-th percentil to cut off * min: pointer to min (return value) * max: pointer to max (return value) * Return value: * call by reference in min and max * Preconditions: * len>0, 0<=percentil<50 * Side effects: * only on min and max */ void cleanmaxmin_xy_transform(const Transform* transforms, int len, int percentil, Transform* min, Transform* max){ Transform* ts = vs_malloc(sizeof(Transform) * len); int cut = len * percentil / 100; memcpy(ts, transforms, sizeof(Transform) * len); qsort(ts,len, sizeof(Transform), cmp_trans_x); min->x = ts[cut].x; max->x = ts[len-cut-1].x; qsort(ts, len, sizeof(Transform), cmp_trans_y); min->y = ts[cut].y; max->y = ts[len-cut-1].y; vs_free(ts); }
int localmotions2TransformsSimple(TransformData* td, const ManyLocalMotions* motions, Transformations* trans ){ int i; int len = vs_vector_size(motions); assert(trans->len==0 && trans->ts == 0); trans->ts = vs_malloc(sizeof(Transform)*len ); for(i=0; i< vs_vector_size(motions); i++) { trans->ts[i]=simpleMotionsToTransform(td,MLMGet(motions,i)); // storeLocalmotions(stderr,MLMGet(motions,i)); // storeTransform(stderr,&trans->ts[i]); } trans->len=len; return VS_OK; }
/** * median_xy_transform: calulcates the median of an array * of transforms, considering only x and y * * Parameters: * transforms: array of transforms. * len: length of array * Return value: * A new transform with x and y beeing the median of * all transforms. alpha and other fields are 0. * Preconditions: * len>0 * Side effects: * None */ Transform median_xy_transform(const Transform* transforms, int len) { Transform* ts = vs_malloc(sizeof(Transform) * len); Transform t; memcpy(ts,transforms, sizeof(Transform)*len ); int half = len/2; qsort(ts, len, sizeof(Transform), cmp_trans_x); t.x = len % 2 == 0 ? ts[half].x : (ts[half].x + ts[half+1].x)/2; qsort(ts, len, sizeof(Transform), cmp_trans_y); t.y = len % 2 == 0 ? ts[half].y : (ts[half].y + ts[half+1].y)/2; t.alpha = 0; t.zoom = 0; t.extra = 0; vs_free(ts); return t; }
/** * cleanmean_xy_transform: calulcates the cleaned mean of an array * of transforms, considering only x and y * * Parameters: * transforms: array of transforms. * len: length of array * Return value: * A new transform with x and y beeing the cleaned mean * (meaning upper and lower pentile are removed) of * all transforms. alpha and other fields are 0. * Preconditions: * len>0 * Side effects: * None */ Transform cleanmean_xy_transform(const Transform* transforms, int len) { Transform* ts = vs_malloc(sizeof(Transform) * len); Transform t = null_transform(); int i, cut = len / 5; memcpy(ts, transforms, sizeof(Transform) * len); qsort(ts,len, sizeof(Transform), cmp_trans_x); for (i = cut; i < len - cut; i++){ // all but cutted t.x += ts[i].x; } qsort(ts, len, sizeof(Transform), cmp_trans_y); for (i = cut; i < len - cut; i++){ // all but cutted t.y += ts[i].y; } vs_free(ts); return mult_transform(&t, 1.0 / (len - (2.0 * cut))); }
void* vs_vector_set_dup(VSVector *V, int pos, void *data, int data_size){ void* d = vs_malloc(data_size); if(!d) return 0; // insuficient error handling here! VS_ERROR memcpy(d, data, data_size); return vs_vector_set(V, pos, d); }