/* * mariokart.cpp * * Copyright 2012 Florian Jung * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 3 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #include "os.h" #include #include #include #include #include #include #include #include #include "util.h" #include "steer_interface.h" #include "steer_accumulator.h" #include "naive_steerer.h" #include "horizon_steerer.h" #include "road_thresholder_iface.h" #include "road_thresholder.h" #include "xorg_grabber.h" #include "joystick.h" #include #include #include #include using namespace std; using namespace cv; #define HIST_SMOOTH 7 //#define NO_BRIGHTNESS // will man nicht, nur zu demonstrationszwecken #define ERODE_RADIUS_2D 4 #define IMG_HISTORY 3 int crosshair_x=0, crosshair_y=0; void mouse_callback(int event, int x, int y, int flags, void* userdata) { if (event==EVENT_LBUTTONDOWN) { crosshair_x=x; crosshair_y=y; } } sem_t thread1_go; sem_t thread1_done; Mat thread1_img; void* thread1_func(void*) { Mat gray; static Mat gray_prev; static std::vector points[2]; std::vector status; // status of tracked features std::vector err; // error in tracking cout << "thread 1 is alive :)" < features; // detected features // detect the features goodFeaturesToTrack(gray, // the image features, // the output detected features 3000, // the maximum number of features 0.2, // quality level 10); // min distance between two features // add the detected features to // the currently tracked features points[0].insert(points[0].end(), features.begin(),features.end()); } // for first image of the sequence if(gray_prev.empty()) gray.copyTo(gray_prev); cv::calcOpticalFlowPyrLK( gray_prev, gray, // 2 consecutive images points[0], // input point positions in first image points[1], // output point positions in the 2nd image status, // tracking success err); // tracking error int k=0; for(int i=0; i < points[1].size(); i++) { // do we keep this point? if (status[i]) { // keep this point in vector points[0][k] = points[0][i]; points[1][k++] = points[1][i]; } } // eliminate unsuccesful points points[0].resize(k); points[1].resize(k); // for all tracked points for(int i= 0; i < points[1].size(); i++ ) { // draw line and circle cv::line(thread1_img, points[0][i], // initial position points[1][i],// new position cv::Scalar(255,255,255)); cv::circle(thread1_img, points[1][i], 2, cv::Scalar(255,255,255),-1); } // 4. extrapolate movement for (int i=0;iadd_steerer(naive_steerer, 1.0); steerer->add_steerer(hor_steerer, 5.0); RoadThresholderIface* road_thresholder = new RoadThresholder(); while(1) { capture.read(img_); assert ((img_.cols==xlen) && (img_.rows==ylen)); Mat img; img_.convertTo(img, CV_8UC3, 1); //FINDMICH img.copyTo(thread1_img); sem_post(&thread1_go); #ifdef NO_BRIGHTNESS //assert(img.type()==CV_8UC3); for (int row = 0; row(row); for (int col=0; col0) { data[0]=(int)data[0] * 256 / sum; data[1]=(int)data[1] * 256 / sum; data[2]=(int)data[2] * 256 / sum; } else { data[0]=255/3; data[1]=255/3; data[2]=255/3; } data+=img.step[1]; } } #endif road_thresholder->process_image(img); Mat img_thres = road_thresholder->get_road(); Mat img_eroded(img_thres.rows, img_thres.cols, img_thres.type()); Mat img_tmp(img_thres.rows, img_thres.cols, img_thres.type()); Mat img_thres2(img_thres.rows, img_thres.cols, img_thres.type()); erode(img_thres, img_tmp, erode_2d_small); dilate(img_tmp, img_thres, erode_2d_small); dilate(img_thres, img_tmp, erode_2d_big); erode(img_tmp, img_thres2, erode_2d_big); assert(img.rows==img_eroded.rows); assert(img.cols==img_eroded.cols); /* Mat img_perspective(trans_height, trans_width, img_thres.type()); warpPerspective(img_thres, img_perspective, transform, img_perspective.size()); threshold(img_perspective, img_perspective, 127, 255, THRESH_BINARY); Mat img_perspective_temp(img_perspective.rows, img_perspective.cols, img_perspective.type()); Mat img_perspective_temp2(img_perspective.rows, img_perspective.cols, img_perspective.type()); erode(img_perspective, img_perspective_temp, circle_mat(7)); dilate(img_perspective_temp, img_perspective_temp2, circle_mat(7 + 15)); erode(img_perspective_temp2, img_perspective, circle_mat(15)); */ steerer->process_image(img_thres2); double steer_value = steerer->get_steer_data(); hor_steerer->process_image(img_thres2); img.row(crosshair_y)=Scalar(255,0,0); img.col(crosshair_x)=Scalar(255,0,0); img_thres2.row(crosshair_y)=128; img_thres2.col(crosshair_x)=128; Mat steer=Mat::zeros(20,1920,CV_8U); steer.col( steer.cols /2 )=128; if (steerer->get_confidence()>0) { int x = (steer_value/2.0 + 0.5)*steer.cols; if (x<1) x=1; if (x>=steer.cols-1) x=steer.cols-2; steer.col(x) = 255; steer.col(x-1)=240; steer.col(x+1)=240; joystick.steer( steer_value,0.05); } else joystick.steer(0.0); sem_wait(&thread1_done); // wait for thread1 to finish //imshow("orig", img); imshow("edit", img); //imshow("perspective", img_perspective); //imshow("diff", img_diff); imshow("thres", img_thres); imshow("thres2", img_thres2); imshow("tracked", thread1_img); imshow("steer", steer); //img_writer << img_diff; thres_writer << img_thres; thres2_writer << img_thres2; waitKey(1000/50); joystick.process(); } //} //try /*catch(string meh) { cout << "error: "<