cameras_sdk_demo.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. //
  2. // Created by alex on 18-12-8.
  3. //
  4. //
  5. #include <opencv2/opencv.hpp>
  6. #include <opencv2/core/core.hpp>
  7. #include <opencv2/highgui/highgui.hpp>
  8. #include <string>
  9. #include <iostream>
  10. #include <zconf.h>
  11. #include <csignal>
  12. #include <thread>
  13. #include "MvGmslCamera.h"
  14. #include <fstream>
  15. #include <chrono>
  16. using namespace std::chrono;
  17. using std::string;
  18. sig_atomic_t exitRequested = 0;
  19. uint camera_num = 1;
  20. struct sync_out_a_cfg_client_t stCameraCfgSend = {};
  21. char dev_node[32] = "/dev/video0";/*不输入-d参数时,默认开启的第一个的设备*/
  22. std::string camera_fmt_str = "UYVY";/*默认采集的图像格式*/
  23. std::string output_fmt_str = "BGRA32";/*默认输出的图像格式,支持类型见README*/
  24. uint cam_w = 1280;/*不输入-s参数时。默认采集摄像头的分辨率*/
  25. uint cam_h = 720;/*不输入-s参数时。默认采集摄像头的分辨率*/
  26. uint out_w = 640;/*屏幕输出的视频分辨率*/
  27. uint out_h = 360;/*屏幕输出的视频分辨率*/
  28. uint64_t timestampbefore[8] = {0};/*上一次采集图像时采集时间*/
  29. uint64_t LinuxGetFrameTimeBefore[8] = {0};/*上一次采集图像时的系统时间*/
  30. std::string g_camera_dev = "NONE";/*默认名字*/
  31. void handler(int) {
  32. std::cout << "will exit..." << std::endl;
  33. exitRequested = true;
  34. }
  35. /*图像采集时的时间戳记录,将时间戳间隔与帧数不相符的相关时间信息打印到/tmp/cameras_sdk_demo.log文件中,每个设备生成单独log文件*/
  36. void CheckTimeStampLog(uint64_t timestamp,uint8_t camera_no)
  37. {
  38. uint64_t FrameInterval = 0;
  39. char buffer[256] = {0};
  40. uint64_t LinuxFrameInterval{};
  41. struct timeval cur_time;
  42. uint64_t LinuxGetFrameTime{};
  43. uint64_t time_interval{};
  44. uint64_t FrameTransferDelay{};
  45. FILE * file_diff = NULL;
  46. char file_name[100] = {0};
  47. if(0 == timestamp)
  48. {
  49. /*camera Data is not available during camera preparation*/
  50. return;
  51. }
  52. gettimeofday(&cur_time, NULL);
  53. LinuxGetFrameTime = cur_time.tv_sec * 1000000000 + cur_time.tv_usec * 1000;
  54. FrameInterval = timestamp - timestampbefore[camera_no];
  55. LinuxFrameInterval = LinuxGetFrameTime - LinuxGetFrameTimeBefore[camera_no];
  56. LinuxGetFrameTimeBefore[camera_no] = LinuxGetFrameTime;
  57. FrameTransferDelay = LinuxGetFrameTime - timestamp;
  58. if(stCameraCfgSend.sync_freq != 0)
  59. time_interval = 1000000000 / stCameraCfgSend.sync_freq;
  60. else{
  61. time_interval = 1000000000 / stCameraCfgSend.async_freq;
  62. }
  63. if(timestampbefore[camera_no] == 0) { //first frame
  64. FrameInterval = time_interval;
  65. LinuxFrameInterval = time_interval;
  66. }
  67. timestampbefore[camera_no] = timestamp;
  68. /* if((FrameInterval > (time_interval + 15000000) || FrameInterval < (time_interval - 15000000))
  69. || (LinuxFrameInterval > (time_interval + 15000000) || LinuxFrameInterval < (time_interval - 15000000))
  70. || FrameTransferDelay < 70000000 || FrameTransferDelay > 90000000)
  71. {
  72. printf("camera_no==========%d\n",camera_no);
  73. printf("timestamp==========%ld\n",timestamp/1000000);
  74. printf("FrameInterva===-------------=======%ld\n",FrameInterval/1000000);
  75. printf("LinuxGetFrameTime======------------====%ld\n",LinuxGetFrameTime/1000000);
  76. printf("LinuxFrameInterval======---------------====%ld\n",LinuxFrameInterval/1000000);
  77. printf("FrameTransferDelay======-----------------------------------====%ld\n",FrameTransferDelay/1000000);
  78. }*/
  79. if(((FrameInterval > (time_interval + 12000000) || FrameInterval < (time_interval - 12000000))) || (FrameInterval == 0))
  80. {
  81. sprintf(file_name,"/tmp/cameras_sdk_demo_video%d.log",camera_no);
  82. file_diff = fopen(file_name,"a+");
  83. sprintf(buffer,"Timestamp : %ld FrameInterval : %ld FrameTransferDelay : %ld LinuxGetFrameTime : %ld LinuxFrameInterval : %ld\n"
  84. ,timestamp,FrameInterval,FrameTransferDelay,LinuxGetFrameTime,LinuxFrameInterval);
  85. fwrite(buffer,sizeof(char),strlen(buffer),file_diff);
  86. fflush(file_diff);
  87. fclose(file_diff);
  88. }
  89. if(atoi(getenv("CHECK_TIME")))
  90. {
  91. printf("Timestamp : %ld FrameInterval : %ld FrameTransferDelay : %ld LinuxGetFrameTime : %ld LinuxFrameInterval : %ld\n"
  92. ,timestamp,FrameInterval,FrameTransferDelay,LinuxGetFrameTime,LinuxFrameInterval);
  93. }
  94. }
  95. /*demo程序命令相关参数介绍,详细解释见README*/
  96. static void
  97. print_usage(void) {
  98. printf("\n\tUsage: example [OPTIONS]\n\n"
  99. "\tExample: \n"
  100. "\t./cameras_sdk_demo -d /dev/video0 -s 1280x720\n\n"
  101. "\tSupported options:\n"
  102. "\t-d\t\tSet V4l2 video device node\n"
  103. "\t-m\t\tSet V4l2 video num\n"
  104. "\t-s\t\tSet output resolution of video device\n"
  105. "\t-n\t\tSet sync and async camera no. for example: [-n 2-4] the forward one is sync cameras no 2,the after one is async cameras no 4 (8 sync cameras is setted by default.like [-n 8-0])\n"
  106. "\t-r\t\tSet sync and async camera freq for example: [-r 30-20] the forward one is sync cameras freq 30,the after one is async cameras freq 20(sync freq 30 is setted by default.like [-r 30-0]) \n"
  107. "\t-b\t\tSet which cameras you want to trigger.example: [-b 0x0f-0xf0] the forward one is sync cameras which you want trigger,the after one is async cameras which you want trigger(all 8 cameras is setted sync model by default.like[-b 0xff-0])\n"
  108. "\t-p\t\tSet async cameras is triggered at which angle in a circle,not set by default.\n"
  109. "\t-c\t\tEnter the name of the camera that requires frame counting .example:isx031\n"
  110. "\t-h\t\tPrint this usage\n\n"
  111. "\tNOTE: It runs infinitely until you terminate it with <ctrl+c>\n");
  112. }
  113. /*demo程序命令相关参数设置接口,详细解释见README*/
  114. static bool
  115. parse_cmdline(int argc, char **argv) {
  116. int c;
  117. unsigned int tmp_w;
  118. unsigned int tmp_h;
  119. int sync_camera_bit_draw = 0,async_camera_bit_draw = 0;
  120. if (argc < 2) {
  121. print_usage();
  122. exit(EXIT_SUCCESS);
  123. }
  124. while ((c = getopt(argc, argv, "d:s:r:n:b:f:p:m:c:h")) != -1) {
  125. switch (c) {
  126. case 'd':
  127. strcpy(dev_node, optarg);
  128. break;
  129. case 's':
  130. if (sscanf(optarg, "%dx%d",
  131. &tmp_w, &tmp_h) != 2) {
  132. return false;
  133. }
  134. cam_w = tmp_w;
  135. cam_h = tmp_h;
  136. break;
  137. case 'f':
  138. camera_fmt_str = optarg;
  139. break;
  140. case 'm':
  141. camera_num = strtol(optarg, NULL, 10);
  142. break;
  143. case 'r':
  144. if (sscanf(optarg, "%hhu-%hhu",&stCameraCfgSend.sync_freq, &stCameraCfgSend.async_freq) != 2) {
  145. print_usage();
  146. return false;
  147. }
  148. printf("sync_freq : %d async_freq:%d\n",stCameraCfgSend.sync_freq,stCameraCfgSend.async_freq);
  149. break;
  150. case 'n':
  151. if (sscanf(optarg, "%hhu-%hhu",&stCameraCfgSend.sync_camera_num, &stCameraCfgSend.async_camera_num) != 2) {
  152. print_usage();
  153. return false;
  154. }
  155. printf("sync_camera_num : %d async_camera_num:%d\n",(stCameraCfgSend.sync_camera_num),(stCameraCfgSend.async_camera_num));
  156. break;
  157. case 'b':
  158. if (sscanf(optarg, "%x-%x",&sync_camera_bit_draw, &async_camera_bit_draw) != 2) {
  159. print_usage();
  160. return false;
  161. }
  162. stCameraCfgSend.sync_camera_bit_draw = (unsigned char)sync_camera_bit_draw;
  163. stCameraCfgSend.async_camera_bit_draw = (unsigned char)async_camera_bit_draw;
  164. printf("sync_camera_bit_draw : %d async_camera_bit_draw:%d\n",stCameraCfgSend.sync_camera_bit_draw,stCameraCfgSend.async_camera_bit_draw);
  165. break;
  166. case 'p':
  167. if (sscanf(optarg, "%hhu-%hhu-%hhu-%hhu-%hhu-%hhu-%hhu-%hhu",
  168. &stCameraCfgSend.async_camera_pos[0], &stCameraCfgSend.async_camera_pos[1],&stCameraCfgSend.async_camera_pos[2],
  169. &stCameraCfgSend.async_camera_pos[3],&stCameraCfgSend.async_camera_pos[4],&stCameraCfgSend.async_camera_pos[5]
  170. ,&stCameraCfgSend.async_camera_pos[6],&stCameraCfgSend.async_camera_pos[7]) != 8) {
  171. print_usage();
  172. return false;
  173. }
  174. printf("pos:[0]:%hhu [1]:%hhu [2]:%hhu [3]:%hhu [4]:%hhu [5]:%hhu [6]:%hhu [7]:%hhu \n",stCameraCfgSend.async_camera_pos[0],stCameraCfgSend.async_camera_pos[1],stCameraCfgSend.async_camera_pos[2],
  175. stCameraCfgSend.async_camera_pos[3],stCameraCfgSend.async_camera_pos[4],stCameraCfgSend.async_camera_pos[5],stCameraCfgSend.async_camera_pos[6],stCameraCfgSend.async_camera_pos[7]);
  176. break;
  177. case 'c':
  178. g_camera_dev = optarg;
  179. break;
  180. case 'h':
  181. print_usage();
  182. exit(EXIT_SUCCESS);
  183. break;
  184. default:
  185. print_usage();
  186. return false;
  187. }
  188. }
  189. return true;
  190. }
  191. /*demo程序主函数,分别打开n个窗口,并通过反复分别调用GetImageCvMat和GetImagePtr接口获取图像和时间戳在窗口中显示*/
  192. int main(int argc, char *argv[]) {
  193. camera_context_t ctx[8] = {};
  194. stCameraCfgSend.async_camera_num = 0;
  195. stCameraCfgSend.async_freq = 0;
  196. stCameraCfgSend.async_camera_bit_draw = 0;
  197. stCameraCfgSend.sync_camera_num = 8;
  198. stCameraCfgSend.sync_freq = 30;
  199. stCameraCfgSend.sync_camera_bit_draw = 0xff;
  200. if (!parse_cmdline(argc, argv)) {
  201. return -1;
  202. }
  203. char dev_node_tmp = dev_node[10];
  204. for(int i = 0; i < camera_num; i++){
  205. dev_node[10] = dev_node_tmp + i;
  206. ctx[i].dev_node = dev_node;
  207. ctx[i].camera_fmt_str = camera_fmt_str;
  208. ctx[i].output_fmt_str = output_fmt_str;
  209. ctx[i].cam_w = cam_w;
  210. ctx[i].cam_h = cam_h;
  211. ctx[i].out_w = out_w;
  212. ctx[i].out_h = out_h;
  213. }
  214. miivii::MvGmslCamera mvcam(ctx, camera_num, stCameraCfgSend);
  215. std::string windowName("DisplayCamera ");
  216. for (uint32_t i = 0; i < camera_num; i++) {
  217. cv::namedWindow(windowName + std::to_string(i), cv::WindowFlags::WINDOW_AUTOSIZE);
  218. cv::moveWindow(windowName + std::to_string(i), 200 * i, 200 * i);
  219. }
  220. cv::Mat outMat[camera_num];
  221. uint8_t *outbuf[camera_num];
  222. cv::Mat imgbuf[camera_num];
  223. signal(SIGINT, &handler);
  224. bool quit = false;
  225. uint64_t timestamp;
  226. while (!quit) {
  227. if (exitRequested) {
  228. quit = true;
  229. break;
  230. }
  231. uint8_t camera_no = dev_node[10] - 0x30;
  232. /*use cv data to get image*/
  233. if (mvcam.GetImageCvMat(outMat, timestamp, camera_no, g_camera_dev)) {
  234. for (uint32_t i = 0; i < camera_num; i++) {
  235. if ( ctx[i].output_fmt_str == "UYVY") {
  236. cv::cvtColor(outMat[i], outMat[i], cv::COLOR_YUV2BGR_UYVY);
  237. cv::imshow(windowName + std::to_string(i), outMat[i]);
  238. } else if (ctx[i].output_fmt_str == "ABGR32") {
  239. cv::cvtColor(outMat[i], outMat[i], cv::COLOR_RGBA2BGR);
  240. cv::imshow(windowName + std::to_string(i), outMat[i]);
  241. } else if (ctx[i].output_fmt_str == "BGRA32") {
  242. cv::cvtColor(outMat[i], outMat[i], cv::COLOR_BGRA2BGR);
  243. cv::imshow(windowName + std::to_string(i), outMat[i]);
  244. }
  245. std::cout << "cv_" <<std::endl;
  246. CheckTimeStampLog(timestamp,dev_node_tmp - 0x30 + i);
  247. }
  248. } else {
  249. std::cerr << "Can't get image form camera." << std::endl;
  250. }
  251. if (cv::waitKey(1) == 27) {// Wait for 'esc' key press to exit
  252. break;
  253. }
  254. /*use raw data to get image*/
  255. if (mvcam.GetImagePtr(outbuf, timestamp, camera_no, g_camera_dev)) {
  256. for (uint32_t i = 0; i < camera_num; i++) {
  257. if ( ctx[i].output_fmt_str == "UYVY") {
  258. imgbuf[i] = cv::Mat(out_h, out_w, CV_8UC2, outbuf[i]);
  259. cv::Mat mrgba(out_h, out_w, CV_8UC3);
  260. cv::cvtColor(imgbuf[i], mrgba, cv::COLOR_YUV2BGR_UYVY);
  261. cv::imshow(windowName + std::to_string(i), mrgba);
  262. } else if (ctx[i].output_fmt_str == "ABGR32") {
  263. imgbuf[i] = cv::Mat(out_h, out_w , CV_8UC4, outbuf[i]);
  264. cv::cvtColor(imgbuf[i], imgbuf[i], cv::COLOR_RGBA2BGR);
  265. cv::imshow(windowName + std::to_string(i), imgbuf[i]);
  266. } else if (ctx[i].output_fmt_str == "BGRA32") {
  267. imgbuf[i] = cv::Mat(out_h, out_w , CV_8UC4, outbuf[i]);
  268. cv::cvtColor(imgbuf[i], imgbuf[i], cv::COLOR_BGRA2BGR);
  269. cv::imshow(windowName + std::to_string(i), imgbuf[i]);
  270. }
  271. std::cout << "mvcam" << std::endl;
  272. CheckTimeStampLog(timestamp,dev_node_tmp - 0x30 + i);
  273. }
  274. } else {
  275. std::cerr << "Can't get image form camera." << std::endl;
  276. }
  277. if (cv::waitKey(1) == 27) {// Wait for 'esc' key press to exit
  278. break;
  279. }
  280. }
  281. return 0;
  282. }