main.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. #include <opencv2/opencv.hpp>
  2. //txs
  3. #include "opencv2/video/tracking.hpp"
  4. #include "opencv2/highgui/highgui.hpp"
  5. #include "cameraobjectarray.pb.h"
  6. //txs
  7. #include "TrtNet.h"
  8. #include "argsParser.h"
  9. #include "configs.h"
  10. #include <chrono>
  11. #include "YoloLayer.h"
  12. #include "dataReader.h"
  13. #include "eval.h"
  14. #include "imageBuffer.h"
  15. #include "modulecomm.h"
  16. #include "xmlparam.h"
  17. #include "rawpic.pb.h"
  18. #include <vector>
  19. #include <QFile>
  20. #include <QTextStream>
  21. #include "localization.h"
  22. #include <QDateTime>
  23. #include "Tracking.h"
  24. using namespace std;
  25. using namespace argsParser;
  26. using namespace Tn;
  27. using namespace Yolo;
  28. //txs
  29. using namespace cv;
  30. //iv::vision::cameraobjectarray gobj;
  31. int gntemp = 0;
  32. void * gpa;
  33. void * gpcamout;
  34. void * gdetec;
  35. qint64 pictime;
  36. //txs
  37. vector<string> cocoNames;
  38. ConsumerProducerQueue<cv::Mat> *imageBuffer = new ConsumerProducerQueue<cv::Mat>(1, true);
  39. std::string gstreamer_pipeline (int capture_width, int capture_height, int display_width, int display_height, int framerate, int flip_method) {
  40. return "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=(int)" + std::to_string(capture_width) + ", height=(int)" +
  41. std::to_string(capture_height) + ", format=(string)NV12, framerate=(fraction)" + std::to_string(framerate) +
  42. "/1 ! nvvidconv flip-method=" + std::to_string(flip_method) + " ! video/x-raw, width=(int)" + std::to_string(display_width) + ", height=(int)" +
  43. std::to_string(display_height) + ", format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink";
  44. }
  45. static vector<string> GetNamesFromFile(string filePathAndName)
  46. {
  47. vector<string> retVec;
  48. QFile qf(QString::fromStdString(filePathAndName));
  49. if(qf.exists())
  50. {
  51. if(qf.open(QIODevice::ReadOnly))
  52. {
  53. QTextStream in(&qf);
  54. while(!in.atEnd())
  55. {
  56. retVec.push_back(in.readLine(1024).toStdString());
  57. }
  58. qf.close();
  59. }
  60. }
  61. return retVec;
  62. }
  63. vector<float> prepareImage(cv::Mat& img)
  64. {
  65. using namespace cv;
  66. int c = parser::getIntValue("C");
  67. int h = parser::getIntValue("H"); //net h
  68. int w = parser::getIntValue("W"); //net w
  69. float scale = min(float(w)/img.cols,float(h)/img.rows);
  70. auto scaleSize = cv::Size(img.cols * scale,img.rows * scale);
  71. cv::Mat rgb ;
  72. cv::cvtColor(img, rgb, CV_BGR2RGB);
  73. cv::Mat resized;
  74. cv::resize(rgb, resized,scaleSize,0,0,INTER_CUBIC);
  75. cv::Mat cropped(h, w,CV_8UC3, 127);
  76. Rect rect((w- scaleSize.width)/2, (h-scaleSize.height)/2, scaleSize.width,scaleSize.height);
  77. resized.copyTo(cropped(rect));
  78. cv::Mat img_float;
  79. if (c == 3)
  80. cropped.convertTo(img_float, CV_32FC3, 1/255.0);
  81. else
  82. cropped.convertTo(img_float, CV_32FC1 ,1/255.0);
  83. //HWC TO CHW
  84. vector<Mat> input_channels(c);
  85. cv::split(img_float, input_channels);
  86. vector<float> result(h*w*c);
  87. auto data = result.data();
  88. int channelLength = h * w;
  89. for (int i = 0; i < c; ++i) {
  90. memcpy(data,input_channels[i].data,channelLength*sizeof(float));
  91. data += channelLength;
  92. }
  93. return result;
  94. }
  95. void DoNms(vector<Detection>& detections,int classes ,float nmsThresh)
  96. {
  97. auto t_start = chrono::high_resolution_clock::now();
  98. vector<vector<Detection>> resClass;
  99. resClass.resize(classes);
  100. for (const auto& item : detections)
  101. resClass[item.classId].push_back(item);
  102. auto iouCompute = [](float * lbox, float* rbox)
  103. {
  104. float interBox[] = {
  105. max(lbox[0] - lbox[2]/2.f , rbox[0] - rbox[2]/2.f), //left
  106. min(lbox[0] + lbox[2]/2.f , rbox[0] + rbox[2]/2.f), //right
  107. max(lbox[1] - lbox[3]/2.f , rbox[1] - rbox[3]/2.f), //top
  108. min(lbox[1] + lbox[3]/2.f , rbox[1] + rbox[3]/2.f), //bottom
  109. };
  110. if(interBox[2] > interBox[3] || interBox[0] > interBox[1])
  111. return 0.0f;
  112. float interBoxS =(interBox[1]-interBox[0])*(interBox[3]-interBox[2]);
  113. return interBoxS/(lbox[2]*lbox[3] + rbox[2]*rbox[3] -interBoxS);
  114. };
  115. vector<Detection> result;
  116. for (int i = 0;i<classes;++i)
  117. {
  118. auto& dets =resClass[i];
  119. if(dets.size() == 0)
  120. continue;
  121. sort(dets.begin(),dets.end(),[=](const Detection& left,const Detection& right){
  122. return left.prob > right.prob;
  123. });
  124. for (unsigned int m = 0;m < dets.size() ; ++m)
  125. {
  126. auto& item = dets[m];
  127. result.push_back(item);
  128. for(unsigned int n = m + 1;n < dets.size() ; ++n)
  129. {
  130. if (iouCompute(item.bbox,dets[n].bbox) > nmsThresh)
  131. {
  132. dets.erase(dets.begin()+n);
  133. --n;
  134. }
  135. }
  136. }
  137. }
  138. //swap(detections,result);
  139. detections = move(result);
  140. auto t_end = chrono::high_resolution_clock::now();
  141. float total = chrono::duration<float, milli>(t_end - t_start).count();
  142. mTensorIvlog->info("Time taken for nms is %f ms.", total);
  143. // cout << "Time taken for nms is " << total << " ms." << endl;
  144. }
  145. vector<Bbox> postProcessImg(cv::Mat& img,vector<Detection>& detections,int classes)
  146. {
  147. using namespace cv;
  148. int h = parser::getIntValue("H"); //net h
  149. int w = parser::getIntValue("W"); //net w
  150. //scale bbox to img
  151. int width = img.cols;
  152. int height = img.rows;
  153. float scale = min(float(w)/width,float(h)/height);
  154. float scaleSize[] = {width * scale,height * scale};
  155. //correct box
  156. for (auto& item : detections)
  157. {
  158. auto& bbox = item.bbox;
  159. bbox[0] = (bbox[0] * w - (w - scaleSize[0])/2.f) / scaleSize[0];
  160. bbox[1] = (bbox[1] * h - (h - scaleSize[1])/2.f) / scaleSize[1];
  161. bbox[2] /= scaleSize[0];
  162. bbox[3] /= scaleSize[1];
  163. }
  164. //nms
  165. float nmsThresh = parser::getFloatValue("nms");
  166. if(nmsThresh > 0)
  167. DoNms(detections,classes,nmsThresh);
  168. vector<Bbox> boxes;
  169. for(const auto& item : detections)
  170. {
  171. auto& b = item.bbox;
  172. Bbox bbox =
  173. {
  174. item.classId, //classId
  175. max(int((b[0]-b[2]/2.)*width),0), //left
  176. min(int((b[0]+b[2]/2.)*width),width), //right
  177. max(int((b[1]-b[3]/2.)*height),0), //top
  178. min(int((b[1]+b[3]/2.)*height),height), //bot
  179. item.prob //score
  180. };
  181. boxes.push_back(bbox);
  182. }
  183. return boxes;
  184. }
  185. vector<string> split(const string& str, char delim)
  186. {
  187. stringstream ss(str);
  188. string token;
  189. vector<string> container;
  190. while (getline(ss, token, delim)) {
  191. container.push_back(token);
  192. }
  193. return container;
  194. }
  195. //std::vector<Obstacle> objvec,iv::lidar::objectarray & lidarobjvec
  196. //txs
  197. void GetCameraObj(std::vector<Bbox> objvec,iv::vision::cameraobjectarray &cameraobjvec,double pictime)
  198. {
  199. mTensorIvlog->info("Bbox count: %d", objvec.size());
  200. // std::cout<<"Bbox count: "<<objvec.size()<<std::endl;
  201. int i;
  202. for(i=0;i<objvec.size();i++){
  203. Bbox x;
  204. //iv::vision::cameraobject cameraobj;
  205. x = objvec.at(i);
  206. mTensorIvlog->info("left: %d\tright: %d", x.left, x.right);
  207. // std::cout<<"left: " <<x.left<<"\tright: "<<x.right<<std::endl;
  208. iv::vision::cameraobject obj;
  209. MatrixXd SpeedInCamera(2,1);
  210. SpeedInCamera<<x.speedx, x.speedy;
  211. MatrixXd SpeedInWorld=TranslateToStandardLocation::translateCameraToStandardLocation(SpeedInCamera);
  212. obj.set_id(x.id);
  213. obj.set_type(cocoNames[x.classId]);
  214. obj.set_outpointx((x.left+x.right)/2);
  215. //2019-10-10 09-01AM
  216. //obj.set_outpointy((x.bot+x.top)/2);
  217. obj.set_outpointy(x.bot);
  218. obj.set_speedx(SpeedInWorld(0,0));
  219. obj.set_speedy(SpeedInWorld(1,0));
  220. obj.set_x((x.left+x.right)/2);
  221. obj.set_y((x.bot + x.top)/2);
  222. obj.set_w(x.right - x.left);
  223. obj.set_h(x.bot - x.top);
  224. obj.set_con(x.score);
  225. mTensorIvlog->info("raw output x: %f\traw output y: %f", obj.outpointx(), obj.outpointy());
  226. // std::cout<<"raw output x: "<<obj.outpointx()<<"\traw output y:" <<obj.outpointy()<<std::endl;
  227. iv::vision::cameraobject * po = cameraobjvec.add_obj();
  228. po->CopyFrom(obj);
  229. cameraobjvec.set_mstime(pictime);
  230. }
  231. }
  232. //txs
  233. int main( int argc, char* argv[] )
  234. {
  235. parser::ADD_ARG_STRING("prototxt",Desc("input yolov3 deploy"),DefaultValue(INPUT_PROTOTXT),ValueDesc("file"));
  236. parser::ADD_ARG_STRING("caffemodel",Desc("input yolov3 caffemodel"),DefaultValue(INPUT_CAFFEMODEL),ValueDesc("file"));
  237. parser::ADD_ARG_INT("C",Desc("channel"),DefaultValue(to_string(INPUT_CHANNEL)));
  238. parser::ADD_ARG_INT("H",Desc("height"),DefaultValue(to_string(INPUT_HEIGHT)));
  239. parser::ADD_ARG_INT("W",Desc("width"),DefaultValue(to_string(INPUT_WIDTH)));
  240. parser::ADD_ARG_STRING("calib",Desc("calibration image List"),DefaultValue(CALIBRATION_LIST),ValueDesc("file"));
  241. parser::ADD_ARG_STRING("mode",Desc("runtime mode"),DefaultValue(MODE), ValueDesc("fp32/fp16/int8"));
  242. parser::ADD_ARG_STRING("outputs",Desc("output nodes name"),DefaultValue(OUTPUTS));
  243. parser::ADD_ARG_INT("class",Desc("num of classes"),DefaultValue(to_string(DETECT_CLASSES)));
  244. parser::ADD_ARG_FLOAT("nms",Desc("non-maximum suppression value"),DefaultValue(to_string(NMS_THRESH)));
  245. parser::ADD_ARG_INT("batchsize",Desc("batch size for input"),DefaultValue("1"));
  246. parser::ADD_ARG_STRING("enginefile",Desc("load from engine"),DefaultValue(""));
  247. //input
  248. parser::ADD_ARG_STRING("input",Desc("input image file"),DefaultValue(INPUT_IMAGE),ValueDesc("file"));
  249. parser::ADD_ARG_STRING("evallist",Desc("eval gt list"),DefaultValue(EVAL_LIST),ValueDesc("file"));
  250. gTensorFault = new iv::Ivfault("TensorRT_yolov3");
  251. mTensorIvlog = new iv::Ivlog("TensorRT_youlov3");
  252. int capture_width = 1920 ;
  253. int capture_height = 1080 ;
  254. int display_width = 1920 ;
  255. int display_height = 1080 ;
  256. int framerate = 60 ;
  257. int flip_method = 0 ;
  258. QString strpath = "./vision_TensorRT_yolov3.xml";
  259. mTensorIvlog->info("%s", strpath.data());
  260. iv::xmlparam::Xmlparam xp(strpath.toStdString());
  261. std::string xmlmsgname = xp.GetParam("msgname","image00");
  262. // string engineName = "./../vision_TensorRT_yolov3/model/yolov3_fp16.engine";
  263. string engineName = "/home/nvidia/beiqi/models/vision/yolov3_fp16.engine";
  264. mTensorIvlog->info("msgname is %s",xmlmsgname.data());
  265. gpcamout = iv::modulecomm::RegisterSend("camera_output",1000000,1);//data
  266. //txs
  267. gdetec = iv::modulecomm::RegisterSend("camera_detect",10000000,1);//img
  268. std::unique_ptr<trtNet> net;
  269. int batchSize = 1;
  270. net.reset(new trtNet(engineName));
  271. assert(net->getBatchSize() == batchSize);
  272. RUN_MODE run_mode = RUN_MODE::FLOAT16;
  273. int outputCount = net->getOutputSize()/sizeof(float);
  274. unique_ptr<float[]> outputData(new float[outputCount]);
  275. // string inputFileName = "/home/nvidia/TensorRT-Yolov3/test.jpg";
  276. // fileNames.push_back(inputFileName);
  277. list<vector<Bbox>> outputs;
  278. int classNum = 80;
  279. int c = 608;
  280. int h = 608;
  281. int w = 3;
  282. int batchCount = 0;
  283. vector<float> inputData;
  284. // inputData.reserve(h*w*c*batchSize);
  285. // vector<cv::Mat> inputImgs;
  286. // auto iter = fileNames.begin();
  287. //txs
  288. cv::namedWindow("result",WINDOW_NORMAL);
  289. std::string pipeline = gstreamer_pipeline(capture_width,
  290. capture_height,
  291. display_width,
  292. display_height,
  293. framerate,
  294. flip_method);
  295. std::cout << "Using pipeline: \n\t" << pipeline << "\n";
  296. cv::VideoCapture cap(pipeline, cv::CAP_GSTREAMER);
  297. if(!cap.isOpened()) {
  298. std::cout<<"Failed to open camera."<<std::endl;
  299. return (-1);
  300. }
  301. //txs
  302. cv::Mat img2;
  303. int count = 0;
  304. bool m_isTrackerInitialized = false;
  305. TrackerSettings settings;
  306. CTracker tracker(settings);
  307. while(1)
  308. {
  309. if (!cap.read(img2)) {
  310. std::cout<<"Capture read error"<<std::endl;
  311. break;
  312. }
  313. pictime = QDateTime::currentMSecsSinceEpoch();
  314. // cv::imshow("imgs",img2);
  315. // cv::waitKey(10);
  316. imageBuffer->add(img2);
  317. imageBuffer->consume(img2);
  318. if(!img2.rows)
  319. {
  320. gTensorFault->SetFaultState(1, 0, "img2.rows state Error");
  321. break;
  322. }
  323. vector<float> curInput = prepareImage(img2);
  324. net->doInference(curInput.data(), outputData.get(),1);
  325. mTensorIvlog->info("run");
  326. // std::cout<<"run"<<std::endl;
  327. auto output = outputData.get();
  328. int detCount = output[0];
  329. //later detect result
  330. vector<Detection> result;
  331. result.resize(detCount);
  332. memcpy(result.data(), &output[1], detCount*sizeof(Detection));
  333. outputs.clear();
  334. auto boxes = postProcessImg(img2,result,classNum);
  335. //--------------------------------------------- init tracker -------------------------------------------------
  336. cv::UMat ufirst = img2.getUMat(cv::ACCESS_READ);
  337. if (!m_isTrackerInitialized)
  338. {
  339. m_isTrackerInitialized = InitTracker(ufirst,tracker);
  340. if (!m_isTrackerInitialized)
  341. {
  342. std::cerr << "Tracker initialize error!!!" << std::endl;
  343. break;
  344. }
  345. }
  346. Tracking(img2,boxes,tracker);
  347. //-------------------------------------------- end tracking ---------------------------------------------------
  348. outputs.emplace_back(boxes);
  349. // vector<string> cocoNames = GetNamesFromFile("./../vision_TensorRT_yolov3/model/coco.names");
  350. cocoNames = GetNamesFromFile("/home/nvidia/beiqi/models/vision/coco.names");
  351. // cout<<"cocoNames: "<<endl<<endl;
  352. mTensorIvlog->info("cocoName:");
  353. // for(int i=0; i<cocoNames.size(); i++)
  354. // {
  355. // std::cout<<cocoNames[i]<<std::endl;
  356. // // cout<<cocoNames[i]<<endl;
  357. // mTensorIvlog->info("%s",cocoNames[i].data());
  358. // }
  359. // cout<<"cocoNames end"<<endl<<endl;
  360. mTensorIvlog->info("cocoNames End");
  361. //txs
  362. iv::vision::cameraobjectarray cameraobjvec;
  363. GetCameraObj(boxes,cameraobjvec,pictime);
  364. std::cout<<"time :"<<cameraobjvec.mstime()<<std::endl;
  365. boxes.clear();
  366. int ntlen;
  367. std::string out = cameraobjvec.SerializeAsString();
  368. iv::modulecomm::ModuleSendMsg(gpcamout,out.data(),out.length());
  369. mTensorIvlog->info("--------------");
  370. // std::cout<<"------------------"<<std::endl;
  371. mTensorIvlog->info("lenth is %d",out.length());
  372. //txs
  373. auto bbox = *outputs.begin();
  374. for(const auto& item : bbox)
  375. {
  376. cv::rectangle(img2,cv::Point(item.left,item.top),cv::Point(item.right,item.bot),cv::Scalar(0,0,255),3,8,0);
  377. std::cout << "id=" << item.id << " class=" << item.classId << " prob=" << item.score*100 << std::endl;
  378. cout << "left=" << item.left << " right=" << item.right << " top=" << item.top << " bot=" << item.bot << endl;
  379. cout << "speedx=" << item.speedx << " speedy=" << item.speedy << endl;
  380. // cout<<cocoNames[item.classId]<<endl;
  381. //txs
  382. MatrixXd local(2,1);
  383. local<<(item.left +item.right)/2,(item.bot +item.bot)/2;
  384. // local<<(item.bot +item.bot)/2,(item.left +item.right)/2;
  385. MatrixXd location=TranslateToStandardLocation::translateCameraToStandardLocation(local);
  386. // string str = cocoNames[item.classId] +":" + std::to_string(item.score*100)+":"+std::to_string(location(0,0))+std::to_string(location(1,0));
  387. string str = std::to_string((int)(location(0,0)/100.0))+" " + std::to_string((int)(location(1,0)/100.0));
  388. // string str1=cocoNames[item.classId];
  389. cv::putText(img2,str, cv::Point(item.left, item.top), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(255, 0, 0));
  390. // cv::putText(img2,str1, cv::Point(item.left, item.top-15), cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(0, 255, 0));
  391. //txs
  392. }
  393. // ou.write(img2);
  394. //txs
  395. // cv::imwrite("img/"+ std::to_string(count)+".jpg", img2);
  396. //txs
  397. iv::vision::rawpic pic;
  398. pic.set_time(pictime);
  399. // pic.set_index(gpicindex);
  400. pic.set_elemsize(img2.elemSize());
  401. pic.set_width(img2.cols);
  402. pic.set_height(img2.rows);
  403. pic.set_mattype(img2.type());
  404. std::vector<int> param = std::vector<int>(2);
  405. param[0] = CV_IMWRITE_JPEG_QUALITY;
  406. param[1] = 95; // default(95) 0-100
  407. std::vector<unsigned char> buff;
  408. cv::imencode(".jpg",img2,buff,param);
  409. pic.set_picdata(buff.data(),buff.size());
  410. buff.clear();
  411. pic.set_type(2);
  412. unsigned int nsize = pic.ByteSize();
  413. char * strser = new char[nsize];
  414. bool bser = pic.SerializeToArray(strser,nsize);
  415. if(bser)iv::modulecomm::ModuleSendMsg(gdetec,strser,nsize);
  416. delete[] strser;
  417. count += 1;
  418. cv::imshow("result",img2);
  419. cv::waitKey(1);
  420. curInput.clear();
  421. // free(output_cpu);
  422. // free(output2_cpu);
  423. // img2.release();
  424. // ou.release();
  425. }
  426. img2.release();
  427. // ou.release();
  428. // gTensorFault->SetFaultState(0, 0, "ok");
  429. return 0;
  430. }