main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. #include "modulecomm.h"
  2. #include "xmlparam.h"
  3. #include "ivfault.h"
  4. #include "ivlog.h"
  5. #include "ivexit.h"
  6. #include "ivversion.h"
  7. #include "rawpic.pb.cc"
  8. #include <QCoreApplication>
  9. #include <thread>
  10. #include "ivversion.h"
  11. #include <chrono>
  12. #include "opencv2/imgcodecs/legacy/constants_c.h"
  13. #include "qmutex.h"
  14. #include "condition_variable"
  15. #include "laneatt.hh"
  16. #include <opencv2/opencv.hpp>
  17. #include "lanearray.pb.h"
  18. #include "imageBuffer.h"
  19. #define INPUT_H 720
  20. #define INPUT_W 1280
  21. #define N_OFFSETS 72
  22. #define N_STRIPS (N_OFFSETS - 1)
  23. #define MAX_COL_BLOCKS 1000
  24. using namespace std;
  25. const std::string trt_path = "./model/LaneATT_test.trt8"; // trt paths
  26. const bool calibrationstate = false;
  27. const std::string calibration_yamlpath = "./yaml/camera_middle_640_360.yaml";
  28. cv::Mat camera_matrix,dist_coe,map1,map2;
  29. //透视变换的点
  30. std::string PERS_FILE = "./yaml/pers_ori.yaml";
  31. const bool cropstate = false;
  32. cv::Range crop_height = cv::Range(240,600);
  33. cv::Range crop_width = cv::Range(320,960);
  34. //是否显示检测结果
  35. bool imshow_flag = true;
  36. //是否读取视频
  37. bool test_video = false;
  38. string video_path = "v4l2src device=/dev/video0 ! video/x-raw, width=(int)1280, height=(int)720 ! videoconvert ! appsink";
  39. //std::string video_path = "/home/nvidia/code/modularization/src/detection/laneATT_trt_old/test/camera_test1.mp4";
  40. bool stop_read = false;
  41. //图片队列
  42. void * gpcamera;
  43. const std::string cameraname="image00"; //共享内存的名字
  44. ConsumerProducerQueue<cv::Mat> * imageBuffer = new ConsumerProducerQueue<cv::Mat>(3,true);
  45. std::vector<cv::Point2f> warped_point, origin_point;
  46. cv::Point2i transed_O;
  47. float METER_PER_PIXEL_X,METER_PER_PIXEL_Y;
  48. float BOARD_SIDE_LENGTH_X = 3.7;
  49. float BOARD_SIDE_LENGTH_Y = 10.0;
  50. void * gpdetect;
  51. const std::string resultname="linearray"; //共享内存的名字
  52. iv::Ivfault *gfault = nullptr;
  53. iv::Ivlog *givlog = nullptr;
  54. cv::VideoWriter outputVideo;
  55. //读取视频数据
  56. void ReadFunc(int n)
  57. {
  58. cv::VideoCapture cap(video_path);
  59. if(!cap.isOpened())
  60. {
  61. cout<<"camera failed to open"<<endl;
  62. }
  63. while(!stop_read)
  64. {
  65. cv::Mat frame;
  66. //读视频的时候加上,读摄像头去掉
  67. if(imageBuffer->isFull())
  68. {
  69. continue;
  70. }
  71. if(cap.read(frame))
  72. {
  73. if(calibrationstate)
  74. cv::remap(frame,frame,map1,map2,cv::INTER_LINEAR,cv::BORDER_CONSTANT);
  75. if(cropstate)
  76. frame = frame(crop_height,crop_width);
  77. imageBuffer->add(frame);
  78. }
  79. else
  80. {
  81. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  82. }
  83. }
  84. return;
  85. }
  86. void Listenpic(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  87. {
  88. if(nSize<1000)return;
  89. iv::vision::rawpic pic;
  90. if(false == pic.ParseFromArray(strdata,nSize))
  91. {
  92. std::cout<<"picview Listenpic fail."<<std::endl;
  93. return;
  94. }
  95. cv::Mat mat(pic.height(),pic.width(),pic.mattype());
  96. if(pic.type() == 1)
  97. memcpy(mat.data,pic.picdata().data(),mat.rows*mat.cols*mat.elemSize());
  98. else
  99. {
  100. // mat.release();
  101. std::vector<unsigned char> buff(pic.picdata().data(),pic.picdata().data() + pic.picdata().size());
  102. mat = cv::imdecode(buff,cv::IMREAD_COLOR);
  103. }
  104. if(calibrationstate)
  105. cv::remap(mat,mat,map1,map2,cv::INTER_LINEAR,cv::BORDER_CONSTANT);
  106. if(cropstate)
  107. mat = mat(crop_height,crop_width);
  108. imageBuffer->add(mat);
  109. mat.release();
  110. }
  111. void exitfunc()
  112. {
  113. // gbstate = false;
  114. // gpthread->join();
  115. // std::cout<<"state thread closed."<<std::endl;
  116. return;
  117. }
  118. cv::Mat get_pers_mat(std::string pers_file)
  119. {
  120. cv::Point2f src[4];
  121. cv::Point2f dst[4];
  122. cv::FileStorage pf(pers_file, cv::FileStorage::READ);
  123. pf["board_left_top"]>>src[0];
  124. pf["board_left_bottom"]>>src[1];
  125. pf["board_right_top"]>>src[2];
  126. pf["board_right_bottom"]>>src[3];
  127. // pf["board_left_top_dst"]>>dst[0];
  128. // pf["board_left_bottom_dst"]>>dst[1];
  129. // pf["board_right_top_dst"]>>dst[2];
  130. // pf["board_right_bottom_dst"]>>dst[3];
  131. /* -------------------------------------zhengke
  132. dst[1].x = src[0].x;
  133. dst[1].y = src[1].y;
  134. dst[3].x = src[2].x;
  135. dst[3].y = src[3].y;
  136. int side_length = dst[3].x - dst[1].x;
  137. METER_PER_PIXEL = BOARD_SIDE_LENGTH / side_length;
  138. dst[0].x = src[0].x;
  139. dst[0].y = dst[1].y - side_length;
  140. dst[2].x = src[2].x;
  141. dst[2].y = dst[3].y - side_length;
  142. cv::Mat pers_mat = getPerspectiveTransform(dst, src);
  143. cv::Mat pers_mat_inv = pers_mat.inv();
  144. return pers_mat_inv;
  145. *///-------------------------------------zhengke
  146. dst[1].x = 130*2;
  147. dst[1].y = 330*2;
  148. dst[3].x = 510*2;
  149. dst[3].y = 330*2;
  150. int side_length_x = dst[3].x - dst[1].x;
  151. METER_PER_PIXEL_X = BOARD_SIDE_LENGTH_X / float(side_length_x);
  152. dst[0].x = dst[1].x;
  153. dst[0].y = 10*2;
  154. dst[2].x = dst[3].x;
  155. dst[2].y = 10*2;
  156. int side_length_y = dst[1].y - dst[0].y;
  157. METER_PER_PIXEL_Y = BOARD_SIDE_LENGTH_Y / float(side_length_y);
  158. transed_O.x = (dst[1].x + dst[3].x)/2;
  159. transed_O.y = (dst[1].y + dst[3].y)/2;
  160. cv::Mat pers_mat = getPerspectiveTransform(dst, src);
  161. cv::Mat pers_mat_inv = pers_mat.inv();
  162. return pers_mat_inv;
  163. }
  164. void transform (std::vector<std::vector<cv::Point2f>> &lanes,cv::Mat &pers_mat_inv,
  165. cv::Mat &raw_image,cv::Mat &img_warp)
  166. {
  167. // PerspectiveTransform
  168. std::vector<cv::Point2f> leftLane;
  169. std::vector<cv::Point2f> rightLane;
  170. std::vector<std::vector<cv::Point2f>> warped_lanes;
  171. for (int i = 0; i < lanes.size(); i++) {
  172. cv::perspectiveTransform(lanes[i], warped_point , pers_mat_inv); // 坐标变换(输入点,输出点,变换矩阵)
  173. warped_lanes.push_back(warped_point);
  174. double sum = 0.0;
  175. for (int i = 0 ; i < 5 ; i++){
  176. sum += warped_point[i].x;
  177. }
  178. double mean = sum / 5;
  179. if (mean < raw_image.size().width / 2){
  180. leftLane.push_back(cv::Point2f(mean, i));
  181. }else{
  182. rightLane.push_back(cv::Point2f(mean, i));
  183. }
  184. }
  185. float left_min = 0;
  186. float right_max = INPUT_W;
  187. int left_num = -1;
  188. int right_num = -1;
  189. int left_left = -1;
  190. int right_right = -1;
  191. for (const auto& points : leftLane){
  192. if(points.x > left_min){
  193. left_num = (int) round(points.y);
  194. left_min = points.x;
  195. }
  196. }
  197. for (const auto& points : leftLane){
  198. if((int)round(points.y) != left_num){
  199. left_left = points.y;
  200. }
  201. }
  202. // if (left_num == -1){
  203. // std::cout<<"left lane failed"<<std::endl;
  204. // }
  205. for (const auto& points : rightLane){
  206. if(points.x < right_max){
  207. right_num = (int) round(points.y);
  208. right_max = points.x;
  209. }
  210. }
  211. for (const auto& points : rightLane){
  212. if((int)round(points.y) != right_num){
  213. right_right = points.y;
  214. }
  215. }
  216. // if (right_num == -1){
  217. // std::cout<<"right lane failed"<<std::endl;
  218. // }
  219. // Visualize
  220. /*-----------------warp image and points ----------------------*/
  221. cv::Point2f pp;
  222. cv::Point2f ppp;
  223. int flag = 0;
  224. float DX = 0.055, DY = 0.26; // 像素和实际距离的比例
  225. std::vector<std::vector<cv::Point2f>> world_lanes;
  226. cv::warpPerspective(raw_image, img_warp, pers_mat_inv, raw_image.size()); // 图像变换(输入图像,输出图像,变换矩阵)
  227. for (const auto& lane_points : warped_lanes) {
  228. if(flag == left_num || flag == right_num){
  229. std::vector<cv::Point2f> world_points;
  230. for (const auto& point : lane_points) {
  231. pp.x =float(point.x);
  232. pp.y =float(point.y);
  233. cv::circle(img_warp, pp, 3, cv::Scalar(0, 255, 0), -1);
  234. //ppp.x = float((point.x - img_warp.size().width / 2) * METER_PER_PIXEL_X);
  235. //ppp.y = float((img_warp.size().height - point.y) * METER_PER_PIXEL_Y);
  236. ppp.x = float((point.x - transed_O.x) * METER_PER_PIXEL_X);
  237. ppp.y = float((transed_O.y - point.y) * METER_PER_PIXEL_Y);
  238. world_points.push_back(ppp);
  239. }
  240. world_lanes.push_back(world_points);
  241. }else{
  242. std::vector<cv::Point2f> world_points;
  243. for (const auto& point : lane_points) {
  244. pp.x =float(point.x);
  245. pp.y =float(point.y);
  246. //std::cout<<pp.x<<" "<<pp.y<<std::endl;
  247. cv::circle(img_warp, pp, 3, cv::Scalar(0, 0, 255), -1);
  248. ppp.x = float((point.x - transed_O.x) * METER_PER_PIXEL_X);
  249. ppp.y = float((transed_O.y - point.y) * METER_PER_PIXEL_Y);
  250. world_points.push_back(ppp);
  251. //std::cout<<ppp.x<<" "<<ppp.y<<std::endl;
  252. }
  253. world_lanes.push_back(world_points);
  254. }
  255. flag++;
  256. }
  257. //cv::imshow("warp",img_warp);
  258. /*------------------------show circle--------------------------*/
  259. flag = 0;
  260. for (const auto& lane_points : lanes) {
  261. if(flag == left_num || flag == right_num){
  262. for (int i=0; i<lane_points.size(); i++) {
  263. pp.x =float(lane_points[i].x);
  264. pp.y =float(lane_points[i].y);
  265. cv::circle(raw_image, pp, 3, cv::Scalar(0, 255, 0), -1);
  266. }
  267. }else if(flag == left_left){
  268. for (int i=0; i<lane_points.size(); i++) {
  269. pp.x =float(lane_points[i].x);
  270. pp.y =float(lane_points[i].y);
  271. cv::circle(raw_image, pp, 3, cv::Scalar(0, 0, 255), -1);
  272. }
  273. }else {
  274. for (int i=0; i<lane_points.size(); i++) {
  275. pp.x =float(lane_points[i].x);
  276. pp.y =float(lane_points[i].y);
  277. cv::circle(raw_image, pp, 3, cv::Scalar(255, 0, 0), -1);
  278. }
  279. }
  280. flag++;
  281. }
  282. /*------------------------show lanes_line------------------------------*/
  283. // cv::Point2f p1, p2;
  284. // flag = 0;
  285. // for (const auto& lane_points : lanes) {
  286. // if(flag == left_num || flag == right_num){
  287. // for (int i=0; i<lane_points.size()-1; i++) {
  288. // p1.x =float(lane_points[i].x) * x_ratio;
  289. // p1.y =float(lane_points[i].y) * y_ratio;
  290. // p2.x =float(lane_points[i+1].x) * x_ratio;
  291. // p2.y =float(lane_points[i+1].y) * y_ratio;
  292. // cv::line(raw_image, p1, p2, cv::Scalar(0, 255, 0), 1);
  293. // }
  294. // }else{
  295. // for (int i=0; i<lane_points.size()-1; i++) {
  296. // p1.x =float(lane_points[i].x) * x_ratio;
  297. // p1.y =float(lane_points[i].y) * y_ratio;
  298. // p2.x =float(lane_points[i+1].x) * x_ratio;
  299. // p2.y =float(lane_points[i+1].y) * y_ratio;
  300. // cv::line(raw_image, p1, p2, cv::Scalar(0, 0, 255), 1);
  301. // }
  302. // }
  303. // flag++;
  304. // }
  305. //cv::imshow("raw",raw_image);
  306. /*---------------------- protobuf ------------------------*/
  307. iv::vision::Linearray line_array;
  308. flag = 0;
  309. for (const auto& lane_points : world_lanes) {
  310. iv::vision::Line *line = line_array.add_line();
  311. if(flag == left_left){
  312. line->set_index(1);
  313. for (int i=0; i<lane_points.size(); i++) {
  314. iv::vision::Point2f *points = line->add_linepoint();
  315. points->set_x(lane_points[i].x);
  316. points->set_y(lane_points[i].y);
  317. }
  318. }else if(flag == left_num){
  319. line->set_index(2);
  320. for (int i=0; i<lane_points.size(); i++) {
  321. iv::vision::Point2f *points = line->add_linepoint();
  322. points->set_x(lane_points[i].x);
  323. points->set_y(lane_points[i].y);
  324. }
  325. }else if(flag == right_num){
  326. line->set_index(3);
  327. for (int i=0; i<lane_points.size(); i++) {
  328. iv::vision::Point2f *points = line->add_linepoint();
  329. points->set_x(lane_points[i].x);
  330. points->set_y(lane_points[i].y);
  331. }
  332. }else{
  333. line->set_index(4);
  334. for (int i=0; i<lane_points.size(); i++) {
  335. iv::vision::Point2f *points = line->add_linepoint();
  336. points->set_x(lane_points[i].x);
  337. points->set_y(lane_points[i].y);
  338. }
  339. }
  340. flag++;
  341. }
  342. /*-----------------------shareMsg-------------------------*/
  343. int size = line_array.ByteSize();
  344. char * strdata = new char[line_array.ByteSize()];
  345. if(line_array.SerializeToArray(strdata, size))
  346. {
  347. iv::modulecomm::ModuleSendMsg(gpdetect, strdata, size);
  348. std::cout<<"lane serialize success."<<std::endl;
  349. }
  350. else
  351. {
  352. std::cout<<"lane serialize error."<<std::endl;
  353. }
  354. delete strdata;
  355. }
  356. int main(int argc, char *argv[]) {
  357. // ==============================================================================
  358. showversion("laneatt");
  359. QCoreApplication a(argc, argv);
  360. gfault = new iv::Ivfault("laneATT");
  361. givlog = new iv::Ivlog("laneATT");
  362. gfault->SetFaultState(0,0,"laneATT initialize.");
  363. if(argc==3)
  364. {
  365. test_video = (strcmp(argv[1], "true") == 0)?true:false;
  366. video_path = argv[2];
  367. }
  368. if(argc==2)
  369. {
  370. test_video = (strcmp(argv[1], "true") == 0)?true:false;
  371. }
  372. if(test_video)
  373. std::thread * readthread = new std::thread(ReadFunc,1);
  374. else
  375. gpcamera= iv::modulecomm::RegisterRecv(&cameraname[0],Listenpic);
  376. gpdetect = iv::modulecomm::RegisterSend(&resultname[0],10000000,1);
  377. if (calibrationstate)
  378. {
  379. cv::FileStorage calib_file(calibration_yamlpath, cv::FileStorage::READ);
  380. calib_file["cameraMatrix"]>>camera_matrix;
  381. calib_file["distCoeffs"]>>dist_coe;
  382. cv::Mat R = cv::Mat::eye(3, 3, CV_64F);
  383. cv::Size imgsize=cv::Size(1280,720);
  384. cv::initUndistortRectifyMap(camera_matrix, dist_coe, R, camera_matrix,imgsize,CV_16SC2,map1,map2);
  385. }
  386. cv::Mat pers_mat_inv = get_pers_mat(PERS_FILE); // 得到透视变换关系
  387. //初始化模型
  388. LaneATT model(trt_path);
  389. double waittime = (double)cv::getTickCount();
  390. while (1)
  391. {
  392. if(imageBuffer->isEmpty())
  393. {
  394. double waittotal = (double)cv::getTickCount() - waittime;
  395. double totaltime = waittotal/cv::getTickFrequency();
  396. // //--------长时间获取不到图片则退出程序----------
  397. // if(totaltime>120.0)
  398. // {
  399. // cout<<"Cant't get frame and quit"<<endl;
  400. // cv::destroyAllWindows();
  401. // std::cout<<"------end program------"<<std::endl;
  402. // break;
  403. // }
  404. cout<<"Wait for frame "<<totaltime<<"s"<<endl;
  405. continue;
  406. }
  407. auto start = std::chrono::system_clock::now(); //时间函数
  408. cv::Mat raw_image,img_warp;
  409. imageBuffer->consume(raw_image);
  410. std::vector<std::vector<cv::Point2f>> lanes;
  411. lanes = model.DetectLane(raw_image);
  412. transform (lanes,pers_mat_inv,raw_image,img_warp);
  413. auto end = std::chrono::system_clock::now(); //时间函数
  414. std::cout <<"total time lane : "<<
  415. std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() <<
  416. "ms" << std::endl;
  417. if(imshow_flag)
  418. {
  419. cv::namedWindow("rst",cv::WINDOW_NORMAL);
  420. cv::namedWindow("warp",cv::WINDOW_NORMAL);
  421. cv::imshow("rst",raw_image);
  422. cv::imshow("warp",img_warp );
  423. if (cv::waitKey(10) == 'q')
  424. {
  425. stop_read = true;
  426. break;
  427. }
  428. }
  429. waittime = (double)cv::getTickCount();
  430. }
  431. cv::destroyAllWindows();
  432. //iv::ivexit::RegIVExitCall(exitfunc);
  433. return a.exec();
  434. }