main.cpp 16 KB

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