Esempio n. 1
0
// Merge a connected compontent of lines to a new line with width.
void merge(const forward_list<LineSeg*>& component, LineSegW& out) {
	// TODO: in principle no loop/collection is necessary
	// Note: profiling indicates this is not even close to a bottleneck, so ok for now
	forward_list<Point*> component2i;
	for (auto vec = component.begin(); vec != component.end(); ++vec) {
		component2i.push_front(&(*vec)->s);
		component2i.push_front(&(*vec)->e);
		//component2i.push_front((Vec2i*)&(*vec)->val[0]);
		//component2i.push_front((Vec2i*)&(*vec)->val[2]);
	}

	line_fit(component2i, out);
}
Esempio n. 2
0
// Merge a connected compontent of lines to a new line with width.
void merge(const forward_list<LineSegW*>& component, LineSegW& out) {
	// TODO: in principle no loop/collection is necessary
	// Note: profiling indicates this is not even close to a bottleneck, so ok for now

	float maxw = 0.0f;

	forward_list<Point*> component2i;
	for (auto vec = component.begin(); vec != component.end(); ++vec) {
		component2i.push_front(&(*vec)->s);
		component2i.push_front(&(*vec)->e);
		if ((*vec)->width > maxw) {
			maxw = (*vec)->width;
		}
	}

	line_fit(component2i, out);
	out.width = max(maxw, out.width);
}
/**
 * Run the optical flow with EDGEFLOW on a new image frame
 * @param[in] *opticflow The opticalflow structure that keeps track of previous images
 * @param[in] *state The state of the drone
 * @param[in] *img The image frame to calculate the optical flow from
 * @param[out] *result The optical flow result
 */
void calc_edgeflow_tot(struct opticflow_t *opticflow, struct opticflow_state_t *state, struct image_t *img,
                       struct opticflow_result_t *result)
{
  // Define Static Variables
  static struct edge_hist_t edge_hist[MAX_HORIZON];
  static uint8_t current_frame_nr = 0;
  struct edge_flow_t edgeflow;
  static uint8_t previous_frame_offset[2] = {1, 1};

  // Define Normal variables
  struct edgeflow_displacement_t displacement;
  displacement.x = malloc(sizeof(int32_t) * img->w);
  displacement.y = malloc(sizeof(int32_t) * img->h);

  // If the methods just switched to this one, reintialize the
  // array of edge_hist structure.
  if (opticflow->just_switched_method == 1) {
    int i;
    for (i = 0; i < MAX_HORIZON; i++) {
      edge_hist[i].x = malloc(sizeof(int32_t) * img->w);
      edge_hist[i].y = malloc(sizeof(int32_t) * img->h);
      FLOAT_RATES_ZERO(edge_hist[i].rates);
    }
  }

  uint16_t disp_range;
  if (opticflow->search_distance < DISP_RANGE_MAX) {
    disp_range = opticflow->search_distance;
  } else {
    disp_range = DISP_RANGE_MAX;
  }

  uint16_t window_size;

  if (opticflow->window_size < MAX_WINDOW_SIZE) {
    window_size = opticflow->window_size;
  } else {
    window_size = MAX_WINDOW_SIZE;
  }

  uint16_t RES = opticflow->subpixel_factor;

  //......................Calculating EdgeFlow..................... //

  // Calculate current frame's edge histogram
  int32_t *edge_hist_x = edge_hist[current_frame_nr].x;
  int32_t *edge_hist_y = edge_hist[current_frame_nr].y;
  calculate_edge_histogram(img, edge_hist_x, 'x', 0);
  calculate_edge_histogram(img, edge_hist_y, 'y', 0);


  // Copy frame time and angles of image to calculated edge histogram
  edge_hist[current_frame_nr].frame_time = img->ts;
  edge_hist[current_frame_nr].rates = state->rates;

  // Calculate which previous edge_hist to compare with the current
  uint8_t previous_frame_nr[2];
  calc_previous_frame_nr(result, opticflow, current_frame_nr, previous_frame_offset, previous_frame_nr);

  //Select edge histogram from the previous frame nr
  int32_t *prev_edge_histogram_x = edge_hist[previous_frame_nr[0]].x;
  int32_t *prev_edge_histogram_y = edge_hist[previous_frame_nr[1]].y;

  //Calculate the corresponding derotation of the two frames
  int16_t der_shift_x = 0;
  int16_t der_shift_y = 0;

  if (opticflow->derotation) {
    der_shift_x = (int16_t)(edge_hist[current_frame_nr].rates.p  /
                            result->fps *
                            (float)img->w / (OPTICFLOW_FOV_W) * opticflow->derotation_correction_factor_x);
    der_shift_y = (int16_t)(edge_hist[current_frame_nr].rates.q /
                            result->fps *
                            (float)img->h / (OPTICFLOW_FOV_H) * opticflow->derotation_correction_factor_y);
  }

  // Estimate pixel wise displacement of the edge histograms for x and y direction
  calculate_edge_displacement(edge_hist_x, prev_edge_histogram_x,
                              displacement.x, img->w,
                              window_size, disp_range,  der_shift_x);
  calculate_edge_displacement(edge_hist_y, prev_edge_histogram_y,
                              displacement.y, img->h,
                              window_size, disp_range, der_shift_y);

  // Fit a line on the pixel displacement to estimate
  // the global pixel flow and divergence (RES is resolution)
  line_fit(displacement.x, &edgeflow.div_x,
           &edgeflow.flow_x, img->w,
           window_size + disp_range, RES);
  line_fit(displacement.y, &edgeflow.div_y,
           &edgeflow.flow_y, img->h,
           window_size + disp_range, RES);

  /* Save Resulting flow in results
   * Warning: The flow detected here is different in sign
   * and size, therefore this will be multiplied with
   * the same subpixel factor and -1 to make it on par with
   * the LK algorithm of t opticalflow_calculator.c
   * */
  edgeflow.flow_x = -1 * edgeflow.flow_x;
  edgeflow.flow_y = -1 * edgeflow.flow_y;

  result->flow_x = (int16_t)edgeflow.flow_x / previous_frame_offset[0];
  result->flow_y = (int16_t)edgeflow.flow_y / previous_frame_offset[1];

  //Fill up the results optic flow to be on par with LK_fast9
  result->flow_der_x =  result->flow_x;
  result->flow_der_y =  result->flow_y;
  result->corner_cnt = getAmountPeaks(edge_hist_x, 500 , img->w);
  result->tracked_cnt = getAmountPeaks(edge_hist_x, 500 , img->w);
  result->divergence = (float)edgeflow.flow_x / RES;
  result->div_size = 0.0f;
  result->noise_measurement = 0.0f;
  result->surface_roughness = 0.0f;

  //......................Calculating VELOCITY ..................... //

  /*Estimate fps per direction
   * This is the fps with adaptive horizon for subpixel flow, which is not similar
   * to the loop speed of the algorithm. The faster the quadcopter flies
   * the higher it becomes
  */
  float fps_x = 0;
  float fps_y = 0;
  float time_diff_x = (float)(timeval_diff(&edge_hist[previous_frame_nr[0]].frame_time, &img->ts)) / 1000.;
  float time_diff_y = (float)(timeval_diff(&edge_hist[previous_frame_nr[1]].frame_time, &img->ts)) / 1000.;
  fps_x = 1 / (time_diff_x);
  fps_y = 1 / (time_diff_y);

  result->fps = fps_x;

  // Calculate velocity
  float vel_x = edgeflow.flow_x * fps_x * state->agl * OPTICFLOW_FOV_W / (img->w * RES);
  float vel_y = edgeflow.flow_y * fps_y * state->agl * OPTICFLOW_FOV_H / (img->h * RES);

  //Apply a  median filter to the velocity if wanted
  if (opticflow->median_filter == true) {
    result->vel_x = (float)update_median_filter(&vel_x_filt, (int32_t)(vel_x * 1000)) / 1000;
    result->vel_y = (float)update_median_filter(&vel_y_filt, (int32_t)(vel_y * 1000)) / 1000;
  } else {
    result->vel_x = vel_x;
    result->vel_y = vel_y;
  }

  result->noise_measurement = 0.2;



#if OPTICFLOW_SHOW_FLOW
  draw_edgeflow_img(img, edgeflow, prev_edge_histogram_x, edge_hist_x);
#endif
  // Increment and wrap current time frame
  current_frame_nr = (current_frame_nr + 1) % MAX_HORIZON;
}
int  geometric_descriptors (Protein * protein) {
    
    int helix_ctr, strand_ctr, res_ctr, atom_ctr, ctr, no_of_points;
    double **point;
    double  p[3]; /* the direction vector */
    double cm[3]; /* the CM vector */
    int sheet[100][100] = {{0}}; /* TODO I can have up to a 100 sheets, 100 starnds each */
    char sheet_id [100][PDB_SHEET_SHEET_LEN+1] = {{'\0'}}; /* TODO id for each sheet */
    int sheet_ctr,  no_of_sheets = 0;
    int n_params = 7;
    double *params;
    Residue * residue;
    int lm_fit (double **points, int n_points, double *params, int n_params);
    int line_fit (double **point, int no_of_points,
	      double p[], double center_of_mass[]);
    int perp_line_fit (double **point, int no_of_points,
		       double p[], double cm[], double avg[]);
    double normal_to_catenoid (double **point, int no_of_points,
			       double *params, double normal[3], double foot[3]);
    
    if ( ! (params = emalloc (n_params*sizeof(double) ) ) ) return 1;
    /* allocate 3 times the protein length (= numbr of residues),
       bcs for the fiting purposes
       we might extract C,N and perhaps O backbone atoms */
    if ( ! (point = dmatrix (3*protein->length, 3) ) ) return 1;
     
    /************************************************************************/
    /************************************************************************/
    /************************************************************************/
    /*****               HELIX   PROCESSING  ********************************/
    /************************************************************************/
    /************************************************************************/
    /*for each helix, extact C-alpha in an array, and fit a line through it */
     
    for (helix_ctr=0; helix_ctr<protein->no_helices; helix_ctr++) {
	ctr = 0;

	/* extract C-alphas */
	for (res_ctr = 	protein->helix[helix_ctr].begin;
	     res_ctr <= protein->helix[helix_ctr].end; res_ctr++) {
	    residue = protein->sequence+res_ctr;
	    for (atom_ctr = 0; atom_ctr < residue->no_atoms; atom_ctr++) {
		if ( ! strcmp (residue->atom[atom_ctr].type, "CA") ) {
		    point[ctr][0] = residue->atom[atom_ctr].x;
		    point[ctr][1] = residue->atom[atom_ctr].y;
		    point[ctr][2] = residue->atom[atom_ctr].z;
		    ctr++;
		    break;
		}
	    }
	}
	no_of_points = ctr;
	
	/* fit a line through them */
	line_fit (point, no_of_points, p, cm);
	if ( ! (protein->helix[helix_ctr].p  = dmatrix (1,3)) ) return 1;
	if ( ! (protein->helix[helix_ctr].cm = dmatrix (1,3)) ) return 1;
	memcpy (protein->helix[helix_ctr].p[0],   p, 3*sizeof(double) );
	memcpy (protein->helix[helix_ctr].cm[0], cm, 3*sizeof(double) );
	protein->helix[helix_ctr].no_of_vectors = 1;

    }
    
    /************************************************************************/
    /************************************************************************/
    /************************************************************************/
    /*****              SHEET    PROCESSING  ********************************/
    /************************************************************************/
    /************************************************************************/
    /*for the moment, do the same for each strand */
    /*for each strand, extact C-alpha in an array, and fit a line through it */
    for (strand_ctr=0; strand_ctr<protein->no_strands; strand_ctr++) {

	/* which sheet does this strand belong to? */
	for ( sheet_ctr=0; sheet_ctr < no_of_sheets; sheet_ctr++ ) {
	    if ( ! strcmp (sheet_id[sheet_ctr],
			   protein->strand[strand_ctr].sheet_id) ) {
		break;
	    }
	}
	
	/* some sheet we have not seen so far: */
	if ( sheet_ctr == no_of_sheets ) {
	    memcpy (sheet_id[sheet_ctr],  protein->strand[strand_ctr].sheet_id,
		    PDB_SHEET_SHEET_LEN); 
	    no_of_sheets ++; 
	}
	sheet[sheet_ctr][0] ++; 
	sheet[sheet_ctr][ sheet[sheet_ctr][0] ] = strand_ctr; 
	protein->strand[strand_ctr].sheet_number = sheet_ctr+1;

	/**** associate a direction with each strand ****/
	/* extract C's and N's */
	ctr = 0;
	for (res_ctr = 	protein->strand[strand_ctr].begin;
	     res_ctr <= protein->strand[strand_ctr].end; res_ctr++) {
	    residue = protein->sequence+res_ctr;
	    for (atom_ctr = 0; atom_ctr < residue->no_atoms; atom_ctr++) {
		if ( ! strcmp (residue->atom[atom_ctr].type, "C")      
		     ||  ! strcmp (residue->atom[atom_ctr].type, "N") ) {
		    point[ctr][0] = residue->atom[atom_ctr].x;
		    point[ctr][1] = residue->atom[atom_ctr].y;
		    point[ctr][2] = residue->atom[atom_ctr].z;
		    ctr++;
		}
	    }
	}
	no_of_points = ctr;
	
	/* allocate */
	if ( ! (protein->strand[strand_ctr].p  = dmatrix (1,3)) ) return 1;
	if ( ! (protein->strand[strand_ctr].cm = dmatrix (1,3)) ) return 1;
	/***********/
	
	/* fit a line through C's and N's ,--- cannot use CA trace*/
	line_fit (point, no_of_points, p, cm);
	memcpy (protein->strand[strand_ctr].p[0],   p, 3*sizeof(double) );
	memcpy (protein->strand[strand_ctr].cm[0], cm, 3*sizeof(double) );
	protein->strand[strand_ctr].no_of_vectors = 1;
	/***********/


    }
    protein->no_sheets  = no_of_sheets;
    if ( ! no_of_sheets) return 0;

    
    free (params);
    free_dmatrix (point);
    
    return 0;
}
Esempio n. 5
0
/**
 * Run the optical flow with EDGEFLOW on a new image frame
 * @param[in] *opticflow The opticalflow structure that keeps track of previous images
 * @param[in] *state The state of the drone
 * @param[in] *img The image frame to calculate the optical flow from
 * @param[out] *result The optical flow result
 */
void calc_edgeflow_tot(struct opticflow_t *opticflow, struct opticflow_state_t *state, struct image_t *img,
                       struct opticflow_result_t *result)
{
    // Define Static Variables
    static struct edge_hist_t edge_hist[MAX_HORIZON];
    static uint8_t current_frame_nr = 0;
    static struct edge_flow_t edgeflow;
    static uint8_t previous_frame_offset[2] = {1, 1};

    // Define Normal variables
    struct edgeflow_displacement_t displacement;
    uint16_t disp_range;
    if (opticflow->search_distance < DISP_RANGE_MAX) {
        disp_range = opticflow->search_distance;
    } else {
        disp_range = DISP_RANGE_MAX;
    }

    uint16_t window_size;

    if (opticflow->window_size < MAX_WINDOW_SIZE) {
        window_size = opticflow->window_size;
    } else {
        window_size = MAX_WINDOW_SIZE;
    }

    uint16_t RES = opticflow->subpixel_factor;

    //......................Calculating EdgeFlow..................... //

    // Calculate current frame's edge histogram
    int32_t *edge_hist_x = edge_hist[current_frame_nr].x;
    int32_t *edge_hist_y = edge_hist[current_frame_nr].y;
    calculate_edge_histogram(img, edge_hist_x, 'x', 0);
    calculate_edge_histogram(img, edge_hist_y, 'y', 0);

    // Copy frame time and angles of image to calculated edge histogram
    memcpy(&edge_hist[current_frame_nr].frame_time, &img->ts, sizeof(struct timeval));
    edge_hist[current_frame_nr].pitch = state->theta;
    edge_hist[current_frame_nr].roll = state->phi;

    // Calculate which previous edge_hist to compare with the current
    uint8_t previous_frame_nr[2];
    calc_previous_frame_nr(result, opticflow, current_frame_nr, previous_frame_offset, previous_frame_nr);

    //Select edge histogram from the previous frame nr
    int32_t *prev_edge_histogram_x = edge_hist[previous_frame_nr[0]].x;
    int32_t *prev_edge_histogram_y = edge_hist[previous_frame_nr[1]].y;

    //Calculate the corresponding derotation of the two frames
    int16_t der_shift_x = 0;
    int16_t der_shift_y = 0;

    if (opticflow->derotation) {
        der_shift_x = -(int16_t)((edge_hist[previous_frame_nr[0]].roll - edge_hist[current_frame_nr].roll) *
                                 (float)img->w / (OPTICFLOW_FOV_W));
        der_shift_y = -(int16_t)((edge_hist[previous_frame_nr[1]].pitch - edge_hist[current_frame_nr].pitch) *
                                 (float)img->h / (OPTICFLOW_FOV_H));
    }

    // Estimate pixel wise displacement of the edge histograms for x and y direction
    calculate_edge_displacement(edge_hist_x, prev_edge_histogram_x,
                                displacement.x, img->w,
                                window_size, disp_range,  der_shift_x);
    calculate_edge_displacement(edge_hist_y, prev_edge_histogram_y,
                                displacement.y, img->h,
                                window_size, disp_range, der_shift_y);

    // Fit a line on the pixel displacement to estimate
    // the global pixel flow and divergence (RES is resolution)
    line_fit(displacement.x, &edgeflow.div_x,
             &edgeflow.flow_x, img->w,
             window_size + disp_range, RES);
    line_fit(displacement.y, &edgeflow.div_y,
             &edgeflow.flow_y, img->h,
             window_size + disp_range, RES);

    /* Save Resulting flow in results
     * Warning: The flow detected here is different in sign
     * and size, therefore this will be multiplied with
     * the same subpixel factor and -1 to make it on par with
     * the LK algorithm of t opticalflow_calculator.c
     * */
    edgeflow.flow_x = -1 * edgeflow.flow_x;
    edgeflow.flow_y = -1 * edgeflow.flow_y;

    result->flow_x = (int16_t)edgeflow.flow_x / previous_frame_offset[0];
    result->flow_y = (int16_t)edgeflow.flow_y / previous_frame_offset[1];

    //Fill up the results optic flow to be on par with LK_fast9
    result->flow_der_x =  result->flow_x;
    result->flow_der_y =  result->flow_y;
    result->corner_cnt = getAmountPeaks(edge_hist_x, 500 , img->w);
    result->tracked_cnt = getAmountPeaks(edge_hist_x, 500 , img->w);
    result->divergence = (float)edgeflow.flow_x / RES;
    result->div_size = 0.0f;
    result->noise_measurement = 0.0f;
    result->surface_roughness = 0.0f;

    //......................Calculating VELOCITY ..................... //

    /*Estimate fps per direction
     * This is the fps with adaptive horizon for subpixel flow, which is not similar
     * to the loop speed of the algorithm. The faster the quadcopter flies
     * the higher it becomes
    */
    float fps_x = 0;
    float fps_y = 0;
    float time_diff_x = (float)(timeval_diff(&edge_hist[previous_frame_nr[0]].frame_time, &img->ts)) / 1000.;
    float time_diff_y = (float)(timeval_diff(&edge_hist[previous_frame_nr[1]].frame_time, &img->ts)) / 1000.;
    fps_x = 1 / (time_diff_x);
    fps_y = 1 / (time_diff_y);

    result->fps = fps_x;

    // Calculate velocity
    float vel_x = edgeflow.flow_x * fps_x * state->agl * OPTICFLOW_FOV_W / (img->w * RES);
    float vel_y = edgeflow.flow_y * fps_y * state->agl * OPTICFLOW_FOV_H / (img->h * RES);
    result->vel_x = vel_x;
    result->vel_y = vel_y;

    /* Rotate velocities from camera frame coordinates to body coordinates.
    * IMPORTANT This frame to body orientation should be the case for the Parrot
    * ARdrone and Bebop, however this can be different for other quadcopters
    * ALWAYS double check!
    */
    result->vel_body_x = - vel_y;
    result->vel_body_y = vel_x;

#if OPTICFLOW_DEBUG && OPTICFLOW_SHOW_FLOW
    draw_edgeflow_img(img, edgeflow, displacement, *edge_hist_x)
#endif
    // Increment and wrap current time frame
    current_frame_nr = (current_frame_nr + 1) % MAX_HORIZON;
}