#include #include #include #include #include using namespace std; using namespace cv; Mat circle_mat(int radius) { Mat result(radius*2+1, radius*2+1, CV_8U); for (int x=0; x<=result.cols/2; x++) for (int y=0; y<=result.rows/2; y++) { unsigned char& p1 = result.at(result.cols/2 + x, result.rows/2 + y); unsigned char& p2 = result.at(result.cols/2 - x, result.rows/2 + y); unsigned char& p3 = result.at(result.cols/2 + x, result.rows/2 - y); unsigned char& p4 = result.at(result.cols/2 - x, result.rows/2 - y); if ( x*x + y*y < radius*radius ) p1=p2=p3=p4=255; else p1=p2=p3=p4=0; } return result; } 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; } } 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> frame; Mat thres(frame.rows, frame.cols, CV_8UC1); Mat tmp(frame.rows, frame.cols, CV_8UC1); int area_history[AREA_HISTORY]; for (int i=0;i> frame; 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(row); for (int col=0; col(row); for (int col=0; col(row); for (int col=0; col200) 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;imaxa) { maxa=area_cnt[i]; maxi2=maxi; maxi=i; } } // lösche alle bis auf die größte fläche for (int row = 0; row(row); for (int col=0; col > contours; vector hierarchy; findContours(thres_tmp, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, Point(0, 0)); /// Draw contours Mat drawing = Mat::zeros( thres_tmp.size(), CV_8UC3 ); //drawContours( drawing, contours, -1, Scalar(250,0,0) , 2,8, hierarchy); for( int i = 0; i< contours.size(); i++ ) { //if (hierarchy[i][3]<0) // no parent Scalar color = Scalar( 255 ,(hierarchy[i][3]<0)?255:0, (hierarchy[i][3]<0)?255:0 ); drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); } for( int i = 0; i< contours.size(); i++ ) { if (hierarchy[i][3]<0) { int lowy=0, lowj=-1; int highy=drawing.rows; for (int j=0;j lowy) { lowy=contours[i][j].y; lowj=j; } if (contours[i][j].y < highy) highy=contours[i][j].y; } if (lowj!=-1) { std::rotate(contours[i].begin(),contours[i].begin()+lowj,contours[i].end()); int j; for (j=0;j= contours[i].size()) j1-=contours[i].size(); int j2=(j-smoothen); if (j2 < 0) j2+=contours[i].size(); angles[j] = atan2(contours[i][j1].y - contours[i][j2].y, contours[i][j1].x - contours[i][j2].x) * 180 /3.141592654; if (angles[j]<0) angles[j]+=360; int r,g,b; hue2rgb(angles[j], &r, &g, &b); circle(drawing, contours[i][j], 2, Scalar(b,g,r)); int x=drawing.cols-drawing.cols*(j-init_j)/(contours[i].size()-init_j); line(drawing,Point(x,0), Point(x,10), Scalar(b,g,r)); } #define ANG_SMOOTH 9 for (j=init_j+ANG_SMOOTH;j=360) ang_diff-=360; if (ang_diff>=180) ang_diff=360-ang_diff; int c=abs(20* ang_diff/ANG_SMOOTH); Scalar col=(c<256) ? Scalar(255-c,255-c,255) : Scalar(255,0,255); line(drawing, Point(x,12), Point(x,22), col); int y=25+40-2*ang_diff/ANG_SMOOTH; double quality = ((double)ang_diff/ANG_SMOOTH) * linear(contours[i][j].y, highy, 1.0, highy+ (drawing.rows-highy)/10, 0.0, true) * linear( abs(drawing.cols/2 - contours[i][j].x), 0.8*drawing.cols/2, 1.0, drawing.cols/2, 0.6, true); int y2=25+40+100-5*quality; line(drawing, Point(x,y), Point(x,y), Scalar(255,255,255)); line(drawing, Point(x,25+40+100), Point(x,25+40+100), Scalar(127,127,127)); line(drawing, Point(x,y2), Point(x,y2), Scalar(255,255,255)); circle(drawing, contours[i][j], 2, col); } delete [] angles; } } } Point midpoint=Point(drawing.cols/2, 250); for (int a=0; a<360; a++) { double s=sin((double)a*3.141592654/180.0); double c=cos((double)a*3.141592654/180.0); int r,g,b; hue2rgb(a, &r, &g, &b); line(drawing,midpoint-Point(c*5, s*5), midpoint-Point(c*30, s*30),Scalar(b,g,r) ); } area_history_sum-=area_history[area_history_ptr]; area_history[area_history_ptr]=area_cnt[maxi]; area_history_sum+=area_cnt[maxi]; area_history_ptr=(area_history_ptr+1)%AREA_HISTORY; int prev_area=area_history_sum/AREA_HISTORY; cout << "\r\e[2A area = "<=10) { cout << "\nALERT: too fast road area change!\n\n\n" << flush; alertcnt=0; } alertcnt++; if (alertcnt == 20) cout << "\n\n\n\n\n\n------------------------\n\n\n"; imshow("input",thres); imshow("contours",drawing); //waitKey(100); waitKey(); } }