diff options
author | Florian Jung <florian.a.jung@web.de> | 2012-12-03 21:01:01 +0100 |
---|---|---|
committer | Florian Jung <florian.a.jung@web.de> | 2012-12-03 21:01:01 +0100 |
commit | 6175f64926b52b4d35379d4cc872b7c4cee7dd98 (patch) | |
tree | 171044422e8d8248e7f4860a806d0649d9f7a36f | |
parent | 2b023e3bb1176e24d722ec0943b14864f5a70205 (diff) |
anfänge der steerer-klassen
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | horizon_steerer.cpp | 588 | ||||
-rw-r--r-- | horizon_steerer.h | 37 | ||||
-rw-r--r-- | mariokart01.cpp | 3 | ||||
-rw-r--r-- | steer_accumulator.cpp | 33 | ||||
-rw-r--r-- | steer_accumulator.h | 26 | ||||
-rw-r--r-- | steer_interface.h | 17 |
7 files changed, 710 insertions, 0 deletions
@@ -3,6 +3,12 @@ all: detect_road_borders mariokart01 detect_road_borders: detect_road_borders.cpp g++ `pkg-config --libs --cflags opencv` -g $< -o $@ +horizon_steerer.o: horizon_steerer.cpp horizon_steerer.h + g++ `pkg-config --libs --cflags opencv` -g horizon_steerer.cpp -c + +steer_accumulator.o: steer_accumulator.cpp steer_accumulator.h + g++ `pkg-config --libs --cflags opencv` -g steer_accumulator.cpp -c + test_detect: detect_road_borders ./detect_road_borders test.mpg diff --git a/horizon_steerer.cpp b/horizon_steerer.cpp new file mode 100644 index 0000000..a553410 --- /dev/null +++ b/horizon_steerer.cpp @@ -0,0 +1,588 @@ +#include <stdlib.h> +#include <stdio.h> +#include <iostream> +#include <math.h> +#include <opencv2/opencv.hpp> +#include "horizon_steerer.h" + +using namespace std; +using namespace cv; + +HorizonSteerer::HorizonSteerer(int xlen_, int ylen_) +{ + xlen=xlen_; + ylen=ylen_; + + int** contour_map; + contour_map=new int*[xlen]; + for (int i=0;i<xlen;i++) + contour_map[i]=new int[ylen]; +} + + +static void set_pixel(Mat m, Point p, Scalar color) +{ + line(m,p,p,color); +} + +int HorizonSteerer::find_intersection_index(int x0, int y0, int x1, int y1, int** contour_map, bool stop_at_endpoint) // bresenham aus der dt. wikipedia +// returns: the point's index where the intersection happened, or a negative number if no intersection. +{ + int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; + int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1; + int err = dx+dy, e2; /* error value e_xy */ + + for(;;) + { + + //setPixel(x0,y0); + if (contour_map[x0][y0]>0) return contour_map[x0][y0]; // found intersection? + if (contour_map[x0][y0+1]>0) return contour_map[x0][y0+1]; + if (contour_map[x0+1][y0]>0) return contour_map[x0+1][y0]; + + + + + if (stop_at_endpoint && x0==x1 && y0==y1) break; + e2 = 2*err; + if (e2 > dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ + if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ + } + + return -1; +} + + +static void hue2rgb(float hue, int* r, int* g, int* b) +{ + double ff; + int i; + + + if (hue >= 360.0) hue = 0.0; + hue /= 60.0; + i = (int)hue; + ff = hue - i; + int x=ff*255; + + switch(i) { + case 0: + *r = 255; + *g = x; + *b = 0; + break; + case 1: + *r = 255-x; + *g = 255; + *b = 0; + break; + case 2: + *r = 0; + *g = 255; + *b = x; + break; + + case 3: + *r = 0; + *g = 255-x; + *b = 255; + break; + case 4: + *r = x; + *g = 0; + *b = 255; + break; + case 5: + default: + *r = 255; + *g = 0; + *b = 255-x; + break; + } +} + +static double linear(double x, double x1, double y1, double x2, double y2, bool clip=false, double clipmin=INFINITY, double clipmax=INFINITY) +{ + if (clipmin==INFINITY) clipmin=y1; + if (clipmax==INFINITY) clipmax=y2; + if (clipmin>clipmax) { int tmp=clipmin; clipmin=clipmax; clipmax=tmp; } + + double result = (y2-y1)*(x-x1)/(x2-x1)+y1; + + if (clip) + { + if (result>clipmax) return clipmax; + else if (result<clipmin) return clipmin; + else return result; + } + else + return result; +} + + +int HorizonSteerer::annotate_regions(Mat img) //img is treated as black/white (0, !=0) +// changes img, and returns the number of found areas +{ + int region_index=1; // "0" means "no area" + for (int row = 0; row<img.rows; row++) + { + uchar* data=img.ptr<uchar>(row); + + for (int col=0; col<img.cols;col++) + { + if (*data==255) + { + floodFill(img, Point(col,row), region_index); + region_index++; + } + + data++; + } + } + return region_index-1; +} + +Mat HorizonSteerer::nicely_draw_regions(Mat annotated, int* area_cnt, int total_area_cnt, int largest_region) +{ + Mat result; + annotated.copyTo(result); + + // Das ist nur zum schönsein. + for (int row=0; row<result.rows; row++) + { + uchar* data=result.ptr<uchar>(row); + + for (int col=0; col<result.cols;col++) + { + if (*data) + { + long long tmp = (long long)30000*(long)area_cnt[*data-1]/(long)total_area_cnt + 64; + if (tmp>200) tmp=200; + if (*data==largest_region) tmp=255; + *data=tmp; + } + + data++; + } + } +} + +double HorizonSteerer::only_retain_largest_region(Mat img, int* size) +// img is a binary image +// in *size, if non-NULL, the size of the largest area is stored. +// returns: ratio between the second-largest and largest region +// 0.0 means "that's the only region", 1.0 means "both had the same size!" +// can be interpreted as 1.0 - "confidence". +{ + int n_regions = annotate_regions(img); + + // calculate the area of each region + int* area_cnt = new int[n_regions]; + for (int i=0;i<n_regions;i++) area_cnt[i]=0; + int total_area_cnt=0; + + for (int row=0; row<img.rows; row++) + { + uchar* data=img.ptr<uchar>(row); + + for (int col=0; col<img.cols;col++) + { + if (*data) + { + area_cnt[*data-1]++; + total_area_cnt++; + } + + data++; + } + } + + + + + // finde die größte und zweitgrößte fläche + int maxi=0, maxa=area_cnt[0], maxi2=-1; + for (int i=1;i<n_regions;i++) + { + if (area_cnt[i]>maxa) + { + maxa=area_cnt[i]; + maxi2=maxi; + maxi=i; + } + } + + + // lösche alle bis auf die größte fläche + for (int row = 0; row<img.rows; row++) + { + uchar* data=img.ptr<uchar>(row); + + for (int col=0; col<img.cols;col++) + { + if (*data) + { + if (*data!=maxi+1) *data=0; else *data=255; + } + data++; + } + } + + + if (size) *size=area_cnt[maxi]; + + if (maxi2==-1) return 0; + else return (double)area_cnt[maxi2]/(double)area_cnt[maxi]; +} + + +vector<Point>& HorizonSteerer::prepare_and_get_contour(vector< vector<Point> >& contours, const vector<Vec4i>& hierarchy, + int* low_y, int* low_idx, int* high_y, int* first_nonbottom_idx) +{ + assert(low_y!=NULL); + assert(low_idx!=NULL); + assert(high_y!=NULL); + assert(first_nonbottom_idx!=NULL); + + + // find index of our road contour + int road_contour_idx=-1; + for (road_contour_idx=0; road_contour_idx<contours.size(); road_contour_idx++) + if (hierarchy[road_contour_idx][3]<0) // this will be true for exactly one road_contour_idx. + break; + + + assert(road_contour_idx>=0 && road_contour_idx<contours.size()); + assert(contours[road_contour_idx].size()>0); + vector<Point>& contour = contours[road_contour_idx]; // just a shorthand + + // our road is now in contour. + + + // find highest and lowest contour point. (where "low" means high y-coordinate) + *low_y=0; *low_idx=0; + *high_y=ylen; + + for (int j=0;j<contour.size(); j++) + { + if (contour[j].y > *low_y) + { + *low_y=contour[j].y; + *low_idx=j; + } + if (contour[j].y < *high_y) + { + *high_y=contour[j].y; + } + } + + + // make the contour go "from bottom upwards and then downwards back to bottom". + std::rotate(contour.begin(),contour.begin()+*low_idx,contour.end()); + + *first_nonbottom_idx = 0; + for (;*first_nonbottom_idx<contour.size();*first_nonbottom_idx++) + if (contour[*first_nonbottom_idx].y < contour[0].y-1) break; + + // indices 0 to *first_nonbottom_idx-1 is now the bottom line of our contour. + + return contour; +} + +void HorizonSteerer::init_contour_map(const vector<Point>& contour, int** contour_map) +{ + for (int j=0;j<xlen;j++) // zero it + memset(contour_map[j],0,ylen*sizeof(**contour_map)); + + for (int j=0;j<contour.size(); j++) // fill it + contour_map[contour[j].x][contour[j].y]=j; +} + +// returns a new double[] +double* HorizonSteerer::calc_contour_angles(const vector<Point>& contour, int first_nonbottom_idx, int smoothen_middle, int smoothen_bottom) +{ + // calculate directional angle for each nonbottom contour point + double* angles = new double[contour.size()]; + for (int j=first_nonbottom_idx; j<contour.size(); j++) + { + int smoothen=linear(contour[j].y, ylen/2 ,smoothen_middle, ylen,smoothen_bottom, true); + + + // calculate left and right point for the difference quotient, possibly wrap. + int j1=(j+smoothen); while (j1 >= contour.size()) j1-=contour.size(); + int j2=(j-smoothen); while (j2 < 0) j2+=contour.size(); + + + // calculate angle, adjust it to be within [0, 360) + angles[j] = atan2(contour[j1].y - contour[j2].y, contour[j1].x - contour[j2].x) * 180/3.141592654; + if (angles[j]<0) angles[j]+=360; + } + return angles; +} + +double* HorizonSteerer::calc_angle_deriv(double* angles, int first_nonbottom_idx, int size, int ang_smooth) +{ + // calculate derivative of angle for each nonbottom contour point + double* angle_derivative = new double[size]; + for (int j=first_nonbottom_idx+ang_smooth; j<size-ang_smooth; j++) + { + // calculate angular difference, adjust to be within [0;360) and take the shorter way. + double ang_diff = angles[j+ang_smooth]-angles[j-ang_smooth]; + while (ang_diff<0) ang_diff+=360; + while (ang_diff>=360) ang_diff-=360; + if (ang_diff>=180) ang_diff=360-ang_diff; + + angle_derivative[j] = (double)ang_diff / ang_smooth; + } + + // poorly extrapolate the ang_smooth margins + for (int j=first_nonbottom_idx; j<first_nonbottom_idx+ang_smooth; j++) angle_derivative[j]=angle_derivative[first_nonbottom_idx+ang_smooth]; + for (int j=size-ang_smooth; j<size; j++) angle_derivative[j]=angle_derivative[size-ang_smooth-1]; + + return angle_derivative; +} + + + +int HorizonSteerer::find_bestquality_index(const vector<Point>& contour, double* angle_derivative, int high_y, int first_nonbottom_idx, Mat& drawing, + int* bestquality_j_out, int* bestquality_width_out, int* bestquality_out, int* bestquality_max_out) +{ + assert(bestquality_out!=NULL); + assert(bestquality_j_out!=NULL); + assert(bestquality_width_out!=NULL); + + double lastmax=-999999; + double bestquality=0.0; + double bestquality_max=0.0; + int bestquality_j=-1; + int bestquality_width=-1; + + #define MAX_HYST 0.8 + // search for "maximum regions"; i.e. intervals [a,b] with + // ang_deriv[i] >= MAX_HYST * max_deriv \forall i \in [a,b] and + // ang_deriv[a-1,2,3], ang_deriv[b+1,2,3] < MAX_HYST * max_deriv + // where max_deriv = max_{i \in [a,b]} ang_deriv[i]; + for (int j=3; j<contour.size()-3; j++) + { + // search forward for a maximum, and the end of a maximum region. + if (angle_derivative[j] > lastmax) lastmax=angle_derivative[j]; + + if (angle_derivative[j] < MAX_HYST*lastmax && // found the end of the max. region + angle_derivative[j+1] < MAX_HYST*lastmax && + angle_derivative[j+2] < MAX_HYST*lastmax) + { + if (lastmax > 7) // threshold the maximum. + { + // search backward for the begin of that maximum region + int j0; + for (j0=j-1; j0>=0; j0--) + if (angle_derivative[j0] < MAX_HYST*lastmax && + angle_derivative[j0-1] < MAX_HYST*lastmax && + angle_derivative[j0-2] < MAX_HYST*lastmax) + break; + + // maximum region is [j0; j] + + double median_of_max_region = (double)angle_derivative[(j+j0)/2]; + + // calculate quality of that maximum. quality is high, if + // 1) the maximum has a high value AND + // 2) the corresponding point's y-coordinates are near the top image border AND + // 3) the corresponding point's x-coordinates are near the middle of the image, if in doubt + int middle_x = xlen/2; + int distance_from_middle_x = abs(xlen/2 - contour[j].x); + double quality = lastmax + * linear( contour[j].y, high_y, 1.0, high_y+ (ylen-high_y)/10, 0.0, true) // excessively punish points far away from the top border + * linear( distance_from_middle_x, 0.8*middle_x, 1.0, middle_x, 0.6, true); // moderately punish point far away from the x-middle. + + // keep track of the best point + if (quality>bestquality) + { + bestquality=quality; + bestquality_max=lastmax; + bestquality_j=(j+j0)/2; + bestquality_width=j-j0; + } + + + // irrelevant drawing stuff + int x=drawing.cols-drawing.cols*((j+j0)/2-first_nonbottom_idx)/(contour.size()-first_nonbottom_idx); + line(drawing, Point(x,25+40-3*quality), Point(x, 25+40), Scalar(0,255,0)); + circle(drawing, contour[(j+j0)/2], 1, Scalar(128,0,0)); + } + + lastmax=-999999; // reset lastmax, so the search can go on + } + } + // now bestquality_j holds the index of the point with the best quality. + + *bestquality_out = bestquality; + *bestquality_max_out = bestquality_max; + *bestquality_j_out = bestquality_j; + *bestquality_width_out = bestquality_width; +} + +int HorizonSteerer::find_ideal_line(vector<Point>& contour, Point origin_point, int** contour_map, int bestquality_j) +// TODO: this code is crappy, slow, and uses brute force. did i mention it's crappy and slow? +{ + int intersection = find_intersection_index(origin_point.x, origin_point.y, + contour[bestquality_j].x, contour[bestquality_j].y, contour_map); + int steering_point=-1; + + if (intersection<0) + { + cout << "THIS SHOULD NEVER HAPPEN" << endl; + return -1; + } + else + { + int xx=contour[bestquality_j].x; + int lastheight=-1; + if (intersection < bestquality_j) // too far on the right == intersecting the right border + { + // rotate the line to the left till it gets better + for (; xx>=0; xx--) + { + int intersection2 = find_intersection_index(origin_point.x, origin_point.y, xx, contour[bestquality_j].y, contour_map); + if (intersection2<0) // won't happen anyway + break; + + if (intersection2>=bestquality_j) // now we intersect the opposite (=left) border + { + if (contour[intersection2].y>=lastheight) // we intersect at a lower = worse point? + xx++; // then undo last step + + break; + } + lastheight=contour[intersection2].y; + } + } + else if (intersection > bestquality_j) // too far on the left == intersecting the left border + { + // rotate the line to the right till it gets better + for (; xx<xlen; xx++) + { + int intersection2 = find_intersection_index(origin_point.x, origin_point.y, xx, contour[bestquality_j].y, contour_map); + if (intersection2<0)// won't happen anyway + break; + + if (intersection2<=bestquality_j) // now we intersect the opposite (=right) border + { + if (contour[intersection2].y>=lastheight) // we intersect at a lower = worse point? + xx--; // then undo last step + + break; + } + lastheight=contour[intersection2].y; + } + } + // else // we directly met the bestquality point, i.e. where we wanted to go to. + // do nothing + + return find_intersection_index(origin_point.x,origin_point.y, xx, contour[bestquality_j].y, contour_map, false); + } +} + + +void HorizonSteerer::draw_it_all(Mat drawing, vector< vector<Point> >& contours, const vector<Vec4i>& hierarchy, int first_nonbottom_idx, vector<Point>& contour, + double* angles, double* angle_derivative, int bestquality_j, int bestquality_width, int bestquality, + int steering_point, Point origin_point) +{ + // Draw contours + drawContours(drawing, contours, -1, Scalar(255,0,0), 1, 8, hierarchy); + + // draw the angles + for (int j=first_nonbottom_idx; j<contour.size(); j++) + { + int x=drawing.cols-drawing.cols*(j-first_nonbottom_idx)/(contour.size()-first_nonbottom_idx); + + // draw angle as color bar + int r,g,b; + hue2rgb(angles[j], &r, &g, &b); + line(drawing,Point(x,0), Point(x,10), Scalar(b,g,r)); + + // draw derivation of angle as color bar + int c=abs(20* angle_derivative[j]); + Scalar col=(c<256) ? Scalar(255-c,255-c,255) : Scalar(255,0,255); + line(drawing, Point(x,12), Point(x,22), col); + + // and as x-y-graph + int y=25+40-2*angle_derivative[j]; + set_pixel(drawing, Point(x,y), Scalar(255,255,255)); + + // draw into contour + //circle(drawing, contour[j], 2, col); + set_pixel(drawing, contour[j], col); + } + + // draw the point where the left touches the right road border + circle(drawing, contour[bestquality_j], 3, Scalar(255,255,0)); + circle(drawing, contour[bestquality_j], 2, Scalar(255,255,0)); + circle(drawing, contour[bestquality_j], 1, Scalar(255,255,0)); + circle(drawing, contour[bestquality_j], 0, Scalar(255,255,0)); + + // draw the detected left and right border. low saturation means + // a worse detection result + int antisaturation = 200-(200* bestquality/10.0); + if (antisaturation<0) antisaturation=0; + for (int j=0;j<bestquality_j-bestquality_width/2;j++) + set_pixel(drawing, contour[j], Scalar(255,antisaturation,255)); + for (int j=bestquality_j+bestquality_width/2;j<contour.size();j++) + set_pixel(drawing, contour[j], Scalar(antisaturation,255,antisaturation)); + + // a direct line to where left touches right + line(drawing, contour[bestquality_j], origin_point, Scalar(0,64,64)); + + if (steering_point>=0) // should be always true + line(drawing, contour[steering_point], origin_point, Scalar(0,255,255)); +} + +#define SMOOTHEN_BOTTOM 20 +#define SMOOTHEN_MIDDLE 7 +#define ANG_SMOOTH 9 +// return the index of the point to steer to. +int HorizonSteerer::find_steering_point(Mat orig_img, Point origin_point, int** contour_map, Mat& drawing, double* confidence) // orig_img is a binary image +// confidence is between 0.0 (not sure at all) and 1.0 (definitely sure) +{ + assert(confidence!=NULL); + + Mat img; + orig_img.copyTo(img); // this is needed because findContours destroys its input. + drawing = Mat::zeros( img.size(), CV_8UC3 ); + + vector<vector<Point> > contours; + vector<Vec4i> hierarchy; + + findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0, 0)); + + int low_y, low_idx, high_y, first_nonbottom_idx; + vector<Point>& contour = prepare_and_get_contour(contours, hierarchy, + &low_y, &low_idx, &high_y, &first_nonbottom_idx); + + init_contour_map(contour, contour_map); + + + double* angles = calc_contour_angles(contour, first_nonbottom_idx, SMOOTHEN_MIDDLE, SMOOTHEN_BOTTOM); + double* angle_derivative = calc_angle_deriv(angles, first_nonbottom_idx, contour.size(), ANG_SMOOTH); + + int bestquality, bestquality_j, bestquality_width, bestquality_max; + find_bestquality_index(contour, angle_derivative, high_y, first_nonbottom_idx, drawing, + &bestquality_j, &bestquality_width, &bestquality, &bestquality_max); + + // now we have a naive steering point. the way to it might lead + // us offroad, however. + + int steering_point=find_ideal_line(contour, origin_point, contour_map, bestquality_j); + + + draw_it_all(drawing, contours, hierarchy, first_nonbottom_idx, contour, angles, angle_derivative,bestquality_j,bestquality_width,bestquality_max,steering_point, origin_point); + cout << bestquality << "\t" << bestquality_max<<endl; + delete [] angle_derivative; + delete [] angles; + + *confidence = (bestquality-1.0) / 3.0; + if (*confidence<0.0) *confidence=0; + if (*confidence>1.0) *confidence=1.0; + return steering_point; +} + diff --git a/horizon_steerer.h b/horizon_steerer.h new file mode 100644 index 0000000..fba4209 --- /dev/null +++ b/horizon_steerer.h @@ -0,0 +1,37 @@ +#ifndef __HORIZON_STEERER_H__ +#define __HORIZON_STEERER_H__ + +#include <opencv2/opencv.hpp> +#include "steer_interface.h" + +using namespace cv; + +class HorizonSteerer : SteerIface +{ +public: + HorizonSteerer(int xlen_, int ylen_); + virtual ~HorizonSteerer(); + int find_ideal_line(vector<Point>& contour, Point origin_point, int** contour_map, int bestquality_j); + +private: + int find_intersection_index(int x0, int y0, int x1, int y1, int** contour_map, bool stop_at_endpoint=true); + int annotate_regions(Mat img); + Mat nicely_draw_regions(Mat annotated, int* area_cnt, int total_area_cnt, int largest_region); + double only_retain_largest_region(Mat img, int* size); + vector<Point>& prepare_and_get_contour(vector< vector<Point> >& contours, const vector<Vec4i>& hierarchy, + int* low_y, int* low_idx, int* high_y, int* first_nonbottom_idx); + void init_contour_map(const vector<Point>& contour, int** contour_map); + double* calc_contour_angles(const vector<Point>& contour, int first_nonbottom_idx, int smoothen_middle, int smoothen_bottom); + double* calc_angle_deriv(double* angles, int first_nonbottom_idx, int size, int ang_smooth); + int find_bestquality_index(const vector<Point>& contour, double* angle_derivative, int high_y, int first_nonbottom_idx, Mat& drawing, + int* bestquality_j_out, int* bestquality_width_out, int* bestquality_out, int* bestquality_max_out); + void draw_it_all(Mat drawing, vector< vector<Point> >& contours, const vector<Vec4i>& hierarchy, int first_nonbottom_idx, vector<Point>& contour, + double* angles, double* angle_derivative, int bestquality_j, int bestquality_width, int bestquality, + int steering_point, Point origin_point); + int find_steering_point(Mat orig_img, Point origin_point, int** contour_map, Mat& drawing, double* confidence); + + int xlen; + int ylen; +}; + +#endif diff --git a/mariokart01.cpp b/mariokart01.cpp index 3e4d98b..8a8b39d 100644 --- a/mariokart01.cpp +++ b/mariokart01.cpp @@ -44,6 +44,7 @@ #include <iostream> +#include <list> #include <xcb/xcb.h> #include <assert.h> @@ -532,6 +533,8 @@ float flopow(float b, float e) + + sem_t thread1_go; sem_t thread1_done; Mat thread1_img; diff --git a/steer_accumulator.cpp b/steer_accumulator.cpp new file mode 100644 index 0000000..65ce38b --- /dev/null +++ b/steer_accumulator.cpp @@ -0,0 +1,33 @@ +#include "steer_accumulator.h" + +using namespace std; + +void SteerAccumulator::add_steerer(SteerIface* steerer) +{ + steerers.push_back(steerer); +} + +void SteerAccumulator::process_image(const Mat& img) +{ + for (list<SteerIface*>::iterator it = steerers.begin(); it!=steerers.end(); ++it) + (*it)->process_image(img); +} + +double SteerAccumulator::get_steer_data() +{ + double sum=0; + for (list<SteerIface*>::iterator it = steerers.begin(); it!=steerers.end(); ++it) + sum+=(*it)->get_steer_data() * (*it)->get_confidence(); + + double confidence = get_confidence(); + + return (confidence==0) ? 0.0 : (sum/confidence); +} + +double SteerAccumulator::get_confidence() +{ + double sum=0; + for (list<SteerIface*>::iterator it = steerers.begin(); it!=steerers.end(); ++it) + sum+=(*it)->get_confidence(); + return sum; +} diff --git a/steer_accumulator.h b/steer_accumulator.h new file mode 100644 index 0000000..b99602d --- /dev/null +++ b/steer_accumulator.h @@ -0,0 +1,26 @@ +#ifndef __STEER_ACCUMULATOR_H__ +#define __STEER_ACCUMULATOR_H__ + +#include <opencv2/opencv.hpp> +#include "steer_interface.h" +#include <list> + +using namespace cv; + + +class SteerAccumulator : SteerIface +{ + public: + virtual ~SteerAccumulator() {}; + + void add_steerer(SteerIface* steerer); + + virtual void process_image(const Mat& img); + virtual double get_steer_data(); + virtual double get_confidence(); + + private: + std::list<SteerIface*> steerers; +}; + +#endif diff --git a/steer_interface.h b/steer_interface.h new file mode 100644 index 0000000..31d8453 --- /dev/null +++ b/steer_interface.h @@ -0,0 +1,17 @@ +#ifndef __STEER_IFACE_H__ +#define __STEER_IFACE_H__ + +#include <opencv2/opencv.hpp> + +using namespace cv; + +class SteerIface +{ + public: + virtual void process_image(const Mat& img)=0; + virtual double get_steer_data()=0; + virtual double get_confidence()=0; +}; + + +#endif |