summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <florian.a.jung@web.de>2012-11-28 23:34:34 +0100
committerFlorian Jung <florian.a.jung@web.de>2012-11-28 23:34:34 +0100
commitbd758519c960f0f69a2a4f0488b4b5ef19f1b998 (patch)
tree364573153c294b9f35512bc2450dab66afca42a9
parented1f87e456476d53b962b37e5e7fbc8f9fc60499 (diff)
detect_road_borders etwas verschönert (WIP)
-rw-r--r--detect_road_borders.cpp221
-rw-r--r--mariokart01.cpp3
2 files changed, 125 insertions, 99 deletions
diff --git a/detect_road_borders.cpp b/detect_road_borders.cpp
index 5a7c31d..33d3d2f 100644
--- a/detect_road_borders.cpp
+++ b/detect_road_borders.cpp
@@ -124,86 +124,72 @@ double linear(double x, double x1, double y1, double x2, double y2, bool clip=fa
}
-#define AREA_HISTORY 10
-int alertcnt=21;
-int main(int argc, char* argv[])
+int annotate_regions(Mat img) //img is treated as black/white (0, !=0)
+// changes img, and returns the number of found areas
{
- if (argc!=2) {printf("usage: %s videofile\n",argv[0]); exit(1);}
- VideoCapture capture(argv[1]);
-
- if (!capture.isOpened())
+ int region_index=1; // "0" means "no area"
+ for (int row = 0; row<img.rows; row++)
{
- cout << "couldn't open file" << endl;
- exit(1);
+ 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++;
+ }
}
-
- Mat erode_kernel=circle_mat(10);
-
-
- Mat frame;
- capture >> frame;
-
-
+ return region_index-1;
+}
+Mat nicely_draw_regions(Mat annotated, int* area_cnt, int total_area_cnt, int largest_region)
+{
+ Mat result;
+ annotated.copyTo(result);
-
- Mat thres(frame.rows, frame.cols, CV_8UC1);
- Mat tmp(frame.rows, frame.cols, CV_8UC1);
- int** contour_map;
- contour_map=new int*[frame.cols];
- for (int i=0;i<frame.cols;i++)
- contour_map[i]=new int[frame.rows];
-
- int area_history[AREA_HISTORY];
- for (int i=0;i<AREA_HISTORY;i++) area_history[i]=1;
- int area_history_ptr=0;
- int area_history_sum=AREA_HISTORY;
- cout << endl<<endl<<endl;
- int frameno=0;
- while (1)
+ // Das ist nur zum schönsein.
+ for (int row=0; row<result.rows; row++)
{
- capture >> frame;
-
- if (frameno<190)
- {
- frameno++;
- continue;
- }
-
- cvtColor(frame, tmp, CV_RGB2GRAY);
- threshold(tmp, thres, 132, 255, THRESH_BINARY);
- dilate(thres,tmp,Mat());
- erode(tmp,thres,Mat());
- erode(thres,tmp,Mat());
- dilate(tmp,thres,Mat());
-
- int area_index=1; // "0" means "no area"
- for (int row = 0; row<thres.rows; row++)
- {
- uchar* data=thres.ptr<uchar>(row);
+ uchar* data=result.ptr<uchar>(row);
- for (int col=0; col<thres.cols;col++)
+ for (int col=0; col<result.cols;col++)
+ {
+ if (*data)
{
- if (*data==255)
- {
- floodFill(thres, Point(col,row), area_index);
- area_index++;
- }
-
- 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 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);
-
- int* area_cnt = new int[area_index-1];
+ // 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 i=0;i<area_index-1;i++) area_cnt[i]=0;
- for (int row = 0; row<thres.rows; row++)
+ for (int row=0; row<img.rows; row++)
{
- uchar* data=thres.ptr<uchar>(row);
+ uchar* data=img.ptr<uchar>(row);
- for (int col=0; col<thres.cols;col++)
+ for (int col=0; col<img.cols;col++)
{
if (*data)
{
@@ -216,30 +202,11 @@ int main(int argc, char* argv[])
}
- /*
- // Das ist nur zum schönsein. man wird einfach den größten area_cnt nehmen wollen und den rest nullen.
- for (int row = 0; row<thres.rows; row++)
- {
- uchar* data=thres.ptr<uchar>(row);
-
- for (int col=0; col<thres.cols;col++)
- {
- if (*data)
- {
- long long tmp = (long long )30000*(long)area_cnt[*data-1]/(long)total_area_cnt + 64;
- if (tmp>200) tmp=255;
- *data=tmp;
- }
-
- data++;
- }
- }
- */
// finde die größte und zweitgrößte fläche
int maxi=0, maxa=area_cnt[0], maxi2=-1;
- for (int i=1;i<area_index-1;i++)
+ for (int i=1;i<n_regions;i++)
{
if (area_cnt[i]>maxa)
{
@@ -251,11 +218,11 @@ int main(int argc, char* argv[])
// lösche alle bis auf die größte fläche
- for (int row = 0; row<thres.rows; row++)
+ for (int row = 0; row<img.rows; row++)
{
- uchar* data=thres.ptr<uchar>(row);
+ uchar* data=img.ptr<uchar>(row);
- for (int col=0; col<thres.cols;col++)
+ for (int col=0; col<img.cols;col++)
{
if (*data)
{
@@ -266,6 +233,67 @@ int main(int argc, char* argv[])
}
+ if (size) *size=area_cnt[maxi];
+
+ if (maxi2==-1) return 0;
+ else return (double)area_cnt[maxi2]/(double)area_cnt[maxi];
+}
+
+#define AREA_HISTORY 10
+int alertcnt=21;
+int main(int argc, char* argv[])
+{
+ if (argc!=2) {printf("usage: %s videofile\n",argv[0]); exit(1);}
+ VideoCapture capture(argv[1]);
+
+ if (!capture.isOpened())
+ {
+ cout << "couldn't open file" << endl;
+ exit(1);
+ }
+
+ Mat erode_kernel=circle_mat(10);
+
+
+ Mat frame;
+ capture >> frame;
+
+
+
+
+
+ Mat thres(frame.rows, frame.cols, CV_8UC1);
+ Mat tmp(frame.rows, frame.cols, CV_8UC1);
+ int** contour_map;
+ contour_map=new int*[frame.cols];
+ for (int i=0;i<frame.cols;i++)
+ contour_map[i]=new int[frame.rows];
+
+ int area_history[AREA_HISTORY];
+ for (int i=0;i<AREA_HISTORY;i++) area_history[i]=1;
+ int area_history_ptr=0;
+ int area_history_sum=AREA_HISTORY;
+ cout << endl<<endl<<endl;
+ int frameno=0;
+ while (1)
+ {
+ capture >> frame;
+
+ if (frameno<190)
+ {
+ frameno++;
+ continue;
+ }
+
+ cvtColor(frame, tmp, CV_RGB2GRAY);
+ threshold(tmp, thres, 132, 255, THRESH_BINARY);
+ dilate(thres,tmp,Mat());
+ erode(tmp,thres,Mat());
+ erode(thres,tmp,Mat());
+ dilate(tmp,thres,Mat());
+
+ int area_abs;
+ double area_ratio = only_retain_largest_region(thres, &area_abs);
dilate(thres, tmp, erode_kernel);
@@ -273,9 +301,8 @@ int main(int argc, char* argv[])
- Mat thres_tmp, thres_tmp_;
- thres.copyTo(thres_tmp);
- //thres_tmp=thres_tmp_.rowRange(0, 0.6*thres_tmp_.rows );
+ Mat thres_tmp;
+ thres.copyTo(thres_tmp); // this is needed because findContours destroys its input.
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
@@ -521,21 +548,21 @@ int main(int argc, char* argv[])
area_history_sum-=area_history[area_history_ptr];
- area_history[area_history_ptr]=area_cnt[maxi];
- area_history_sum+=area_cnt[maxi];
+ area_history[area_history_ptr]=area_abs;
+ area_history_sum+=area_abs;
area_history_ptr=(area_history_ptr+1)%AREA_HISTORY;
int prev_area=area_history_sum/AREA_HISTORY;
- cout << "\r\e[2A area = "<<area_cnt[maxi]<<", \tvize = "<<((maxi2!=-1)?area_cnt[maxi2]:-1)<<", \tratio="<< ((maxi2!=-1)?(area_cnt[maxi]/area_cnt[maxi2]):-1 )<<" \n" <<
- "prev area = "<<prev_area<<",\tchange="<< (100*area_cnt[maxi]/prev_area -100) <<"%\n"<<flush;
+ cout << "\r\e[2A area = "<<area_abs<<",\tratio="<< area_ratio <<" \n" <<
+ "prev area = "<<prev_area<<",\tchange="<< (100*area_abs/prev_area -100) <<"%\n"<<flush;
- if (maxi!=-1 && maxi2!=-1 && (area_cnt[maxi]/area_cnt[maxi2]) < 10)
+ if (area_ratio>0.1)
{
cout << "\nALERT: possibly split road!\n\n\n" << flush;
alertcnt=0;
}
- if (abs(100*area_cnt[maxi]/prev_area -100) >=10)
+ if (abs(100*area_abs/prev_area -100) >=10)
{
cout << "\nALERT: too fast road area change!\n\n\n" << flush;
alertcnt=0;
diff --git a/mariokart01.cpp b/mariokart01.cpp
index 955bbe7..3e4d98b 100644
--- a/mariokart01.cpp
+++ b/mariokart01.cpp
@@ -697,8 +697,7 @@ try {
joystick.reset();
getchar();
joystick.reset();
-joystick.press_a(true);
-getchar();
+
#ifdef LINUX
XorgGrabber capture("glN64");
#endif