Realtime uvc camera by Tengine ssd - www.deltavision.io

开发环境:

Rock960开发板

Ubuntu16.04

deltavision usb camera

 

一 Tengine安装

    下载Tengine代码: https://github.com/OAID/Tengine

     安装文档:doc/install.md    

   1. 依赖库

  • caffe依赖库
sudo apt install libprotobuf-dev protobuf-compiler libboost-all-dev libgoogle-glog-dev
  • opencv
sudo apt install libopencv-dev

  2.配置文件

 
  1. cd ~/tengine

  2.  
  3. cp makefile.config.example makefile.config

   因为直接在rock960上开发,直接可以使用默认配置

  3. 编译    

 
  1. cd ~/tengine

  2. make

 4. 验证

./build/tests/bin/bench_mobilenet -r1

二.  运行自带的ssd example

 1. 编译example

 
  1. cd ~/tengine/examples

  2. vim linux_build.sh

修改cmake,“/home/usr/tengine”是tengine 所在目录,“/usr/lib/aarch64-linux-gnu” 是protobuf库的所在目录

修改 examples/mobilenet_ssd/CMakeLists.txt, 添加一句 set( TENGINE_DIR /home/rock/Tengine)

 
  1. cmake -DPROTOBUF_DIR=/usr/lib/aarch64-linux-gnu -DTENGINE_DIR=/home/usr/tengine \

  2. ..

  编译

 
  1. mkdir build

  2. cd build

  3. ../linux_build.sh

  4. make -j4

2. 运行ssd 

  把官方提供的模型,放在 ${Tengine_ROOT}/models/

  • MobileNetSSD_deploy.caffemodel
  • MobileNetSSD_deploy.prototxt

 执行

 
  1. cd example/build/mobilenet_ssd

  2.  
  3. ./MSSD -p ../../../models/MobileNetSSD_deploy.prototxt -m ../../../models/MobileNetSSD_deploy.caffemodel -i img.jpg

三 . 从usb camera 获取图像并处理

   读取usb camera 的方法参考:https://mp.csdn.net/postedit/85252440

   1. 复制 mobilenet_ssd目录,命名为mobilenet_ssd_camera

      修改  examples/CMakeLists.txt文件, 添加一句

add_subdirectory(mobilenet_ssd_camera)

   2. 修改 mobilenet_ssd_camera/mssd.cpp

 
  1. /*

  2. * V4L2 video capture example

  3. *

  4. * This program can be used and distributed without restrictions.

  5. *

  6. * This program is provided with the V4L2 API

  7. * see https://linuxtv.org/docs.php for more information

  8. */

  9.  
  10. #include <stdio.h>

  11. #include <stdlib.h>

  12. #include <string.h>

  13. #include <assert.h>

  14. #include <iomanip>

  15. #include <vector>

  16. #include <getopt.h> /* getopt_long() */

  17.  
  18. #include <fcntl.h> /* low-level i/o */

  19. #include <unistd.h>

  20. #include <errno.h>

  21. #include <sys/stat.h>

  22. #include <sys/types.h>

  23. #include <sys/time.h>

  24. #include <sys/mman.h>

  25. #include <sys/ioctl.h>

  26. #include <inttypes.h>

  27.  
  28. #include <linux/videodev2.h>

  29. #include <iostream>

  30. #include <opencv2/opencv.hpp>

  31. #include <opencv2/core/core.hpp>

  32. #include "opencv2/imgproc/imgproc.hpp"

  33. #include <opencv2/highgui/highgui.hpp>

  34.  
  35. #include "tengine_c_api.h"

  36. #include "common.hpp"

  37.  
  38.  
  39. #define DEF_PROTO "models/MobileNetSSD_deploy.prototxt"

  40. #define DEF_MODEL "models/MobileNetSSD_deploy.caffemodel"

  41. #define DEF_IMAGE "tests/images/ssd_dog.jpg"

  42.  
  43. #define CLEAR(x) memset(&(x), 0, sizeof(x))

  44. #define COLS (640)

  45. #define ROWS (480)

  46. #define SSD_IMG_H (300)

  47. #define SSD_IMG_W (300)

  48. using namespace cv;

  49.  
  50. enum io_method {

  51. IO_METHOD_READ,

  52. IO_METHOD_MMAP,

  53. IO_METHOD_USERPTR,

  54. };

  55.  
  56. struct buffer {

  57. void *start;

  58. size_t length;

  59. };

  60.  
  61. typedef struct buffer* PBUF;

  62.  
  63. static char *dev_name;

  64. static enum io_method io = IO_METHOD_MMAP;

  65. static int fd = -1;

  66. struct buffer *buffers;

  67. static unsigned int n_buffers;

  68. static int out_buf;

  69. static int force_format;

  70. static int frame_count = 70;

  71.  
  72. static std::string proto_file;

  73. static std::string model_file;

  74. static std::string image_file;

  75. static std::string save_name="save.jpg";

  76. const char *model_name = "mssd_300";

  77.  
  78. cv::Mat yuvImg(ROWS , COLS, CV_8UC2);

  79. cv::Mat rgbImg(ROWS, COLS,CV_8UC3);

  80. cv::Mat resizeImg(SSD_IMG_W, SSD_IMG_H,CV_8UC3);

  81. cv::Mat floatImg(SSD_IMG_W, SSD_IMG_H, CV_32FC3);

  82.  
  83. static int fpsTick();

  84.  
  85. struct Box

  86. {

  87. float x0;

  88. float y0;

  89. float x1;

  90. float y1;

  91. int class_idx;

  92. float score;

  93. };

  94.  
  95. void get_input_data_ssd(std::string& image_file, float* input_data, int img_h, int img_w)

  96. {

  97. cv::Mat img = cv::imread(image_file);

  98.  
  99. if (img.empty())

  100. {

  101. std::cerr << "Failed to read image file " << image_file << ".\n";

  102. return;

  103. }

  104.  
  105. cv::resize(img, img, cv::Size(img_h, img_w));

  106. img.convertTo(img, CV_32FC3);

  107. float *img_data = (float *)img.data;

  108. int hw = img_h * img_w;

  109.  
  110. float mean[3]={127.5,127.5,127.5};

  111. for (int h = 0; h < img_h; h++)

  112. {

  113. for (int w = 0; w < img_w; w++)

  114. {

  115. for (int c = 0; c < 3; c++)

  116. {

  117. input_data[c * hw + h * img_w + w] = 0.007843* (*img_data - mean[c]);

  118. img_data++;

  119. }

  120. }

  121. }

  122. }

  123.  
  124. void post_process_ssd(std::string& image_file,float threshold,float* outdata,int num,std::string& save_name)

  125. {

  126. std::cout<<"post_process_ssd\n";

  127. const char* class_names[] = {"background",

  128. "aeroplane", "bicycle", "bird", "boat",

  129. "bottle", "bus", "car", "cat", "chair",

  130. "cow", "diningtable", "dog", "horse",

  131. "motorbike", "person", "pottedplant",

  132. "sheep", "sofa", "train", "tvmonitor"};

  133.  
  134. //cv::Mat img = cv::imread(image_file);

  135. int raw_h = rgbImg.size().height;

  136. int raw_w = rgbImg.size().width;

  137. std::vector<Box> boxes;

  138. int line_width=raw_w*0.005;

  139. printf("detect ruesult num: %d \n",num);

  140. for (int i=0;i<num;i++)

  141. {

  142. if(outdata[1]>=threshold)

  143. {

  144. Box box;

  145. box.class_idx=outdata[0];

  146. box.score=outdata[1];

  147. box.x0=outdata[2]*raw_w;

  148. box.y0=outdata[3]*raw_h;

  149. box.x1=outdata[4]*raw_w;

  150. box.y1=outdata[5]*raw_h;

  151. boxes.push_back(box);

  152. printf("%s\t:%.0f%%\n", class_names[box.class_idx], box.score * 100);

  153. printf("BOX:( %g , %g ),( %g , %g )\n",box.x0,box.y0,box.x1,box.y1);

  154. }

  155. outdata+=6;

  156. }

  157. for(int i=0;i<(int)boxes.size();i++)

  158. {

  159. Box box=boxes[i];

  160. cv::rectangle(rgbImg, cv::Rect(box.x0, box.y0,(box.x1-box.x0),(box.y1-box.y0)),cv::Scalar(255, 255, 0),line_width);

  161. std::ostringstream score_str;

  162. score_str<<box.score;

  163. std::string label = std::string(class_names[box.class_idx]) + ": " + score_str.str();

  164. int baseLine = 0;

  165. cv::Size label_size = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);

  166. cv::rectangle(rgbImg, cv::Rect(cv::Point(box.x0,box.y0- label_size.height),

  167. cv::Size(label_size.width, label_size.height + baseLine)),

  168. cv::Scalar(255, 255, 0), CV_FILLED);

  169. cv::putText(rgbImg, label, cv::Point(box.x0, box.y0),

  170. cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));

  171. }

  172. cv::imshow("opencv",rgbImg);

  173. waitKey(1);

  174. std::cout<<"======================================\n";

  175. std::cout<<"[DETECTED IMAGE SAVED]:\t"<< save_name<<"\n";

  176. std::cout<<"======================================\n";

  177.  
  178.  
  179. }

  180.  
  181. static void errno_exit(const char *s)

  182. {

  183. fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));

  184. exit(EXIT_FAILURE);

  185. }

  186.  
  187. static int xioctl(int fh, int request, void *arg)

  188. {

  189. int r;

  190.  
  191. do {

  192. r = ioctl(fh, request, arg);

  193. } while (-1 == r && EINTR == errno);

  194.  
  195. return r;

  196. }

  197.  
  198. static void process_image(const void *p, int size,float *input_data,int img_w, int img_h)

  199. {

  200. std::cout<<"process_image\n";

  201. //int fps = fpsTick();

  202.  
  203. memcpy(yuvImg.data, p, COLS*ROWS*2);

  204. cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_YUYV);

  205.  
  206. cv::resize(rgbImg, resizeImg, cv::Size(img_w, img_h));

  207. resizeImg.convertTo(floatImg, CV_32FC3);

  208. float *img_data = (float *)floatImg.data;

  209. int hw = img_h * img_w;

  210.  
  211. float mean[3]={127.5,127.5,127.5};

  212. for (int h = 0; h < img_h; h++)

  213. {

  214. for (int w = 0; w < img_w; w++)

  215. {

  216. for (int c = 0; c < 3; c++)

  217. {

  218. input_data[c * hw + h * img_w + w] = 0.007843* (*img_data - mean[c]);

  219. img_data++;

  220. }

  221. }

  222. }

  223.  
  224. //cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_YUYV);

  225.  
  226. //char title[10];

  227. //sprintf(title, "fps:%d", fps);

  228. //cv::imshow("opencv",rgbImg);

  229. //waitKey(1);

  230.  
  231. /*

  232. static int frame_number = 0;

  233. char fn[256];

  234. sprintf(fn, "%d.raw", frame_number);

  235. frame_number++;

  236.  
  237. uint8_t *pixel = (uint8_t *) rgbImg.data;

  238. size = COLS*ROWS*3;

  239. int found = 0;

  240. for (int i=0; i < size; i++) {

  241. if (pixel[i] != 0) {

  242. found = 1;

  243. break;

  244. }

  245. }

  246.  
  247. if (found) {

  248. FILE *f = fopen(fn, "wb");

  249. if (f == NULL) { printf("Error opening file\n"); exit(EXIT_FAILURE); }

  250. fwrite(pixel, size, 1, f);

  251. fclose(f);

  252.  
  253. fprintf(stdout, "%s\n", fn);

  254. fflush(stdout);

  255. } else {

  256. fprintf(stdout, "empty image");

  257. }

  258. */

  259.  
  260. }

  261.  
  262. static int read_frame(float *input_data,int img_w, int img_h)

  263. {

  264. struct v4l2_buffer buf;

  265. unsigned int i;

  266. static uint64_t timestamp;

  267. uint64_t stamp =0;

  268.  
  269. switch (io) {

  270. case IO_METHOD_READ:

  271. if (-1 == read(fd, buffers[0].start, buffers[0].length)) {

  272. switch (errno) {

  273. case EAGAIN:

  274. return 0;

  275.  
  276. case EIO:

  277. /* Could ignore EIO, see spec. */

  278.  
  279. /* fall through */

  280.  
  281. default:

  282. errno_exit("read");

  283. }

  284. }

  285.  
  286. process_image(buffers[0].start, buffers[0].length,input_data, img_w, img_h);

  287. break;

  288.  
  289. case IO_METHOD_MMAP:

  290. CLEAR(buf);

  291.  
  292. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  293. buf.memory = V4L2_MEMORY_MMAP;

  294.  
  295. if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {

  296. switch (errno) {

  297. case EAGAIN:

  298. return 0;

  299.  
  300. case EIO:

  301. /* Could ignore EIO, see spec. */

  302.  
  303. /* fall through */

  304.  
  305. default:

  306. errno_exit("VIDIOC_DQBUF");

  307. }

  308. }

  309. stamp = buf.timestamp.tv_sec*1000000+buf.timestamp.tv_usec;

  310. //printf("timestamp :%ld", timestamp);

  311. if(timestamp == stamp){

  312. break;

  313. }

  314.  
  315. assert(buf.index < n_buffers);

  316.  
  317. process_image(buffers[buf.index].start, buf.bytesused, input_data, img_w, img_h);

  318.  
  319. if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))

  320. errno_exit("VIDIOC_QBUF");

  321. break;

  322.  
  323. case IO_METHOD_USERPTR:

  324. CLEAR(buf);

  325.  
  326. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  327. buf.memory = V4L2_MEMORY_USERPTR;

  328.  
  329. if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {

  330.  
  331. switch (errno) {

  332. case EAGAIN:

  333. return 0;

  334.  
  335. case EIO:

  336. /* Could ignore EIO, see spec. */

  337.  
  338. /* fall through */

  339.  
  340. default:

  341. errno_exit("VIDIOC_DQBUF");

  342. }

  343. }

  344.  
  345. for (i = 0; i < n_buffers; ++i)

  346. if (buf.m.userptr == (unsigned long)buffers[i].start

  347. && buf.length == buffers[i].length)

  348. break;

  349.  
  350. assert(i < n_buffers);

  351.  
  352. process_image((void *)buf.m.userptr, buf.bytesused, input_data, img_w, img_h);

  353.  
  354. if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))

  355. errno_exit("VIDIOC_QBUF");

  356. break;

  357. }

  358.  
  359. return 1;

  360. }

  361.  
  362. static void mainloop(void)

  363. {

  364. unsigned int count;

  365.  
  366. count = frame_count;

  367.  
  368.  
  369. // init tengine

  370. init_tengine_library();

  371. if (request_tengine_version("0.1") < 0)

  372. return ;

  373. if (load_model(model_name, "caffe", proto_file.c_str(), model_file.c_str()) < 0)

  374. return ;

  375. std::cout << "load model done!\n";

  376.  
  377. // create graph

  378. graph_t graph = create_runtime_graph("graph", model_name, NULL);

  379. if (!check_graph_valid(graph))

  380. {

  381. std::cout << "create graph0 failed\n";

  382. return ;

  383. }

  384.  
  385.  
  386. int repeat_count = 1;

  387. const char *repeat = std::getenv("REPEAT_COUNT");

  388.  
  389. if (repeat)

  390. repeat_count = std::strtoul(repeat, NULL, 10);

  391.  
  392. int node_idx=0;

  393. int tensor_idx=0;

  394. tensor_t input_tensor = get_graph_input_tensor(graph, node_idx, tensor_idx);

  395. if(!check_tensor_valid(input_tensor))

  396. {

  397. printf("Get input node failed : node_idx: %d, tensor_idx: %d\n",node_idx,tensor_idx);

  398. return;

  399. }

  400.  
  401.  
  402. // input

  403. int img_h = 300;

  404. int img_w = 300;

  405. int img_size = img_h * img_w * 3;

  406. float *input_data = (float *)malloc(sizeof(float) * img_size);

  407. int dims[] = {1, 3, img_h, img_w};

  408. set_tensor_shape(input_tensor, dims, 4);

  409.  
  410. prerun_graph(graph);

  411.  
  412. while (1) {

  413. printf("Reading frame\n");

  414. for (;;) {

  415. fd_set fds;

  416. struct timeval tv;

  417. int r;

  418.  
  419. FD_ZERO(&fds);

  420. FD_SET(fd, &fds);

  421.  
  422. /* Timeout. */

  423. tv.tv_sec = 2;

  424. tv.tv_usec = 0;

  425.  
  426. r = select(fd + 1, &fds, NULL, NULL, &tv);

  427.  
  428. if (-1 == r) {

  429. if (EINTR == errno)

  430. continue;

  431. errno_exit("select");

  432. }

  433.  
  434. if (0 == r) {

  435. fprintf(stderr, "select timeout\n");

  436. exit(EXIT_FAILURE);

  437. }

  438.  
  439.  
  440. if (read_frame(input_data,img_w, img_h))

  441. {

  442. std::cout<<"run_graph\n";

  443. /* EAGAIN - continue select loop. */

  444. set_tensor_buffer(input_tensor, input_data, img_size * 4);

  445. run_graph(graph, 1);

  446.  
  447. //gettimeofday(&t1, NULL);

  448. //float mytime = (float)((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec)) / 1000;

  449. //total_time += mytime;

  450.  
  451. //std::cout << "--------------------------------------\n";

  452. //std::cout << "repeat " << repeat_count << " times, avg time per run is " << total_time / repeat_count << " ms\n";

  453.  
  454. tensor_t out_tensor = get_graph_output_tensor(graph, 0,0);//"detection_out");

  455. int out_dim[4];

  456. get_tensor_shape( out_tensor, out_dim, 4);

  457.  
  458. float *outdata = (float *)get_tensor_buffer(out_tensor);

  459. int num=out_dim[1];

  460. float show_threshold=0.5;

  461.  
  462. post_process_ssd(image_file,show_threshold, outdata, num,save_name);

  463. put_graph_tensor(out_tensor);

  464.  
  465.  
  466. std::cout<<"run end\n";

  467.  
  468. break;

  469. }

  470.  
  471. }

  472.  
  473. }

  474.  
  475. postrun_graph(graph);

  476.  
  477. free(input_data);

  478.  
  479. put_graph_tensor(input_tensor);

  480.  
  481.  
  482.  
  483. destroy_runtime_graph(graph);

  484. remove_model(model_name);

  485.  
  486. return;

  487. }

  488.  
  489. static void stop_capturing(void)

  490. {

  491. enum v4l2_buf_type type;

  492.  
  493. switch (io) {

  494. case IO_METHOD_READ:

  495. /* Nothing to do. */

  496. break;

  497.  
  498. case IO_METHOD_MMAP:

  499. case IO_METHOD_USERPTR:

  500. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  501. if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))

  502. errno_exit("VIDIOC_STREAMOFF");

  503. break;

  504. }

  505. }

  506.  
  507. static void start_capturing(void)

  508. {

  509. unsigned int i;

  510. enum v4l2_buf_type type;

  511.  
  512. switch (io) {

  513. case IO_METHOD_READ:

  514. /* Nothing to do. */

  515. break;

  516.  
  517. case IO_METHOD_MMAP:

  518. for (i = 0; i < n_buffers; ++i) {

  519. struct v4l2_buffer buf;

  520.  
  521. CLEAR(buf);

  522. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  523. buf.memory = V4L2_MEMORY_MMAP;

  524. buf.index = i;

  525.  
  526. if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))

  527. errno_exit("VIDIOC_QBUF");

  528. }

  529. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  530. if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))

  531. errno_exit("VIDIOC_STREAMON");

  532. break;

  533.  
  534. case IO_METHOD_USERPTR:

  535. for (i = 0; i < n_buffers; ++i) {

  536. struct v4l2_buffer buf;

  537.  
  538. CLEAR(buf);

  539. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  540. buf.memory = V4L2_MEMORY_USERPTR;

  541. buf.index = i;

  542. buf.m.userptr = (unsigned long)buffers[i].start;

  543. buf.length = buffers[i].length;

  544.  
  545. if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))

  546. errno_exit("VIDIOC_QBUF");

  547. }

  548. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  549. if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))

  550. errno_exit("VIDIOC_STREAMON");

  551. break;

  552. }

  553. }

  554.  
  555. static void uninit_device(void)

  556. {

  557. unsigned int i;

  558.  
  559. switch (io) {

  560. case IO_METHOD_READ:

  561. free(buffers[0].start);

  562. break;

  563.  
  564. case IO_METHOD_MMAP:

  565. for (i = 0; i < n_buffers; ++i)

  566. if (-1 == munmap(buffers[i].start, buffers[i].length))

  567. errno_exit("munmap");

  568. break;

  569.  
  570. case IO_METHOD_USERPTR:

  571. for (i = 0; i < n_buffers; ++i)

  572. free(buffers[i].start);

  573. break;

  574. }

  575.  
  576. free(buffers);

  577. }

  578.  
  579. static void init_read(unsigned int buffer_size)

  580. {

  581. buffers = (PBUF)calloc(1, sizeof(*buffers));

  582.  
  583. if (!buffers) {

  584. fprintf(stderr, "Out of memory\n");

  585. exit(EXIT_FAILURE);

  586. }

  587.  
  588. buffers[0].length = buffer_size;

  589. buffers[0].start = malloc(buffer_size);

  590.  
  591. if (!buffers[0].start) {

  592. fprintf(stderr, "Out of memory\n");

  593. exit(EXIT_FAILURE);

  594. }

  595. }

  596.  
  597. static void init_mmap(void)

  598. {

  599. struct v4l2_requestbuffers req;

  600.  
  601. CLEAR(req);

  602.  
  603. req.count = 4;

  604. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  605. req.memory = V4L2_MEMORY_MMAP;

  606.  
  607. if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {

  608. if (EINVAL == errno) {

  609. fprintf(stderr, "%s does not support "

  610. "memory mapping\n", dev_name);

  611. exit(EXIT_FAILURE);

  612. } else {

  613. errno_exit("VIDIOC_REQBUFS");

  614. }

  615. }

  616.  
  617. if (req.count < 2) {

  618. fprintf(stderr, "Insufficient buffer memory on %s\n",

  619. dev_name);

  620. exit(EXIT_FAILURE);

  621. }

  622.  
  623. buffers = (PBUF)calloc(req.count, sizeof(*buffers));

  624.  
  625. if (!buffers) {

  626. fprintf(stderr, "Out of memory\n");

  627. exit(EXIT_FAILURE);

  628. }

  629.  
  630. for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {

  631. struct v4l2_buffer buf;

  632.  
  633. CLEAR(buf);

  634.  
  635. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  636. buf.memory = V4L2_MEMORY_MMAP;

  637. buf.index = n_buffers;

  638.  
  639. if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))

  640. errno_exit("VIDIOC_QUERYBUF");

  641.  
  642. buffers[n_buffers].length = buf.length;

  643. buffers[n_buffers].start =

  644. mmap(NULL /* start anywhere */,

  645. buf.length,

  646. PROT_READ | PROT_WRITE /* required */,

  647. MAP_SHARED /* recommended */,

  648. fd, buf.m.offset);

  649.  
  650. if (MAP_FAILED == buffers[n_buffers].start)

  651. errno_exit("mmap");

  652. }

  653. }

  654.  
  655. static void init_userp(unsigned int buffer_size)

  656. {

  657. struct v4l2_requestbuffers req;

  658.  
  659. CLEAR(req);

  660.  
  661. req.count = 4;

  662. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  663. req.memory = V4L2_MEMORY_USERPTR;

  664.  
  665. if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {

  666. if (EINVAL == errno) {

  667. fprintf(stderr, "%s does not support "

  668. "user pointer i/o\n", dev_name);

  669. exit(EXIT_FAILURE);

  670. } else {

  671. errno_exit("VIDIOC_REQBUFS");

  672. }

  673. }

  674.  
  675. buffers = (PBUF)calloc(4, sizeof(*buffers));

  676.  
  677. if (!buffers) {

  678. fprintf(stderr, "Out of memory\n");

  679. exit(EXIT_FAILURE);

  680. }

  681.  
  682. for (n_buffers = 0; n_buffers < 4; ++n_buffers) {

  683. buffers[n_buffers].length = buffer_size;

  684. buffers[n_buffers].start = malloc(buffer_size);

  685.  
  686. if (!buffers[n_buffers].start) {

  687. fprintf(stderr, "Out of memory\n");

  688. exit(EXIT_FAILURE);

  689. }

  690. }

  691. }

  692.  
  693. static void init_device(void)

  694. {

  695. struct v4l2_capability cap;

  696. struct v4l2_cropcap cropcap;

  697. struct v4l2_crop crop;

  698. struct v4l2_format fmt;

  699. unsigned int min;

  700.  
  701. if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {

  702. if (EINVAL == errno) {

  703. fprintf(stderr, "%s is no V4L2 device\n",

  704. dev_name);

  705. exit(EXIT_FAILURE);

  706. } else {

  707. errno_exit("VIDIOC_QUERYCAP");

  708. }

  709. }

  710.  
  711. if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {

  712. fprintf(stderr, "%s is no video capture device\n",

  713. dev_name);

  714. exit(EXIT_FAILURE);

  715. }

  716.  
  717. switch (io) {

  718. case IO_METHOD_READ:

  719. if (!(cap.capabilities & V4L2_CAP_READWRITE)) {

  720. fprintf(stderr, "%s does not support read i/o\n",

  721. dev_name);

  722. exit(EXIT_FAILURE);

  723. }

  724. break;

  725.  
  726. case IO_METHOD_MMAP:

  727. case IO_METHOD_USERPTR:

  728. if (!(cap.capabilities & V4L2_CAP_STREAMING)) {

  729. fprintf(stderr, "%s does not support streaming i/o\n",

  730. dev_name);

  731. exit(EXIT_FAILURE);

  732. }

  733. break;

  734. }

  735.  
  736.  
  737. /* Select video input, video standard and tune here. */

  738.  
  739. struct v4l2_format format = {0};

  740. format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  741. format.fmt.pix.width = COLS;

  742. format.fmt.pix.height = ROWS;

  743. format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

  744. format.fmt.pix.field = V4L2_FIELD_NONE;

  745. int retval = xioctl(fd, VIDIOC_S_FMT, &format);

  746. if (retval == -1) { perror("Setting format\n"); return; }

  747.  
  748.  
  749. //

  750. // CLEAR(cropcap);

  751. //

  752. // cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  753. //

  754. // if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {

  755. // crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  756. // crop.c = cropcap.defrect; /* reset to default */

  757. //

  758. // if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {

  759. // switch (errno) {

  760. // case EINVAL:

  761. // /* Cropping not supported. */

  762. // break;

  763. // default:

  764. // /* Errors ignored. */

  765. // break;

  766. // }

  767. // }

  768. // } else {

  769. // /* Errors ignored. */

  770. // }

  771. //

  772. //

  773. // CLEAR(fmt);

  774. //

  775. // fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  776. // if (force_format) {

  777. // fmt.fmt.pix.width = 640;

  778. // fmt.fmt.pix.height = 480;

  779. // fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

  780. // fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

  781. //

  782. // if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))

  783. // errno_exit("VIDIOC_S_FMT");

  784. //

  785. // /* Note VIDIOC_S_FMT may change width and height. */

  786. // } else {

  787. // /* Preserve original settings as set by v4l2-ctl for example */

  788. // if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))

  789. // errno_exit("VIDIOC_G_FMT");

  790. // }

  791. //

  792. // /* Buggy driver paranoia. */

  793. // min = fmt.fmt.pix.width * 2;

  794. // if (fmt.fmt.pix.bytesperline < min)

  795. // fmt.fmt.pix.bytesperline = min;

  796. // min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;

  797. // if (fmt.fmt.pix.sizeimage < min)

  798. // fmt.fmt.pix.sizeimage = min;

  799. //

  800. switch (io) {

  801. case IO_METHOD_READ:

  802. init_read(fmt.fmt.pix.sizeimage);

  803. break;

  804.  
  805. case IO_METHOD_MMAP:

  806. init_mmap();

  807. break;

  808.  
  809. case IO_METHOD_USERPTR:

  810. init_userp(fmt.fmt.pix.sizeimage);

  811. break;

  812. }

  813. }

  814.  
  815. static void close_device(void)

  816. {

  817. if (-1 == close(fd))

  818. errno_exit("close");

  819.  
  820. fd = -1;

  821. }

  822.  
  823. static void open_device(void)

  824. {

  825. struct stat st;

  826.  
  827. if (-1 == stat(dev_name, &st)) {

  828. fprintf(stderr, "Cannot identify '%s': %d, %s\n",

  829. dev_name, errno, strerror(errno));

  830. exit(EXIT_FAILURE);

  831. }

  832.  
  833. if (!S_ISCHR(st.st_mode)) {

  834. fprintf(stderr, "%s is no device\n", dev_name);

  835. exit(EXIT_FAILURE);

  836. }

  837.  
  838. fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);

  839.  
  840. if (-1 == fd) {

  841. fprintf(stderr, "Cannot open '%s': %d, %s\n",

  842. dev_name, errno, strerror(errno));

  843. exit(EXIT_FAILURE);

  844. }

  845. }

  846.  
  847.  
  848. static int fpsTick()

  849. {

  850.  
  851. static clock_t last=clock();

  852. static clock_t avgDuration = 0;

  853. static float alpha = 1.f/10.f;

  854. static int frameCount = 0;

  855.  
  856. clock_t now = clock();

  857. clock_t delta = now-last;

  858.  
  859. printf("delta clock:%d\n", delta);

  860. last = now;

  861.  
  862.  
  863. frameCount++;

  864.  
  865. int fps = 0;

  866. if(1 == frameCount)

  867. {

  868. avgDuration = delta;

  869. }

  870. else

  871. {

  872. avgDuration = avgDuration * (1.f - alpha) + delta * alpha;

  873. }

  874.  
  875. fps = (1.f * CLOCKS_PER_SEC/ avgDuration);

  876. printf("fps :%d\n", fps);

  877.  
  878.  
  879. }

  880.  
  881. static void usage(FILE *fp, int argc, char **argv)

  882. {

  883. fprintf(fp,

  884. "Usage: %s [options]\n\n"

  885. "Version 1.3\n"

  886. "Options:\n"

  887. "-d | --device name Video device name [%s]\n"

  888. "-h | --help Print this message\n"

  889. "-m | --mmap Use memory mapped buffers [default]\n"

  890. "-r | --read Use read() calls\n"

  891. "-u | --userp Use application allocated buffers\n"

  892. "-o | --output Outputs stream to stdout\n"

  893. "-f | --format Force format to 640x480 YUYV\n"

  894. "-c | --count Number of frames to grab [%i]\n"

  895. "",

  896. argv[0], dev_name, frame_count);

  897. }

  898.  
  899. static const char short_options[] = "d:hmruofc:";

  900.  
  901. static const struct option

  902. long_options[] = {

  903. { "device", required_argument, NULL, 'd' },

  904. { "help", no_argument, NULL, 'h' },

  905. { "mmap", no_argument, NULL, 'm' },

  906. { "read", no_argument, NULL, 'r' },

  907. { "userp", no_argument, NULL, 'u' },

  908. { "output", no_argument, NULL, 'o' },

  909. { "format", no_argument, NULL, 'f' },

  910. { "count", required_argument, NULL, 'c' },

  911. { 0, 0, 0, 0 }

  912. };

  913.  
  914. int main(int argc, char **argv)

  915. {

  916. dev_name = "/dev/video0";

  917.  
  918. for (;;) {

  919. int idx;

  920. int c;

  921.  
  922. c = getopt_long(argc, argv,

  923. short_options, long_options, &idx);

  924.  
  925. if (-1 == c)

  926. break;

  927.  
  928. switch (c) {

  929. case 0: /* getopt_long() flag */

  930. break;

  931.  
  932. case 'd':

  933. dev_name = optarg;

  934. break;

  935.  
  936. case 'h':

  937. usage(stdout, argc, argv);

  938. exit(EXIT_SUCCESS);

  939.  
  940. case 'm':

  941. io = IO_METHOD_MMAP;

  942. break;

  943.  
  944. case 'r':

  945. io = IO_METHOD_READ;

  946. break;

  947.  
  948. case 'u':

  949. io = IO_METHOD_USERPTR;

  950. break;

  951.  
  952. case 'o':

  953. out_buf++;

  954. break;

  955.  
  956. case 'f':

  957. force_format++;

  958. break;

  959.  
  960. case 'c':

  961. errno = 0;

  962. frame_count = strtol(optarg, NULL, 0);

  963. if (errno)

  964. errno_exit(optarg);

  965. break;

  966.  
  967. default:

  968. usage(stderr, argc, argv);

  969. exit(EXIT_FAILURE);

  970. }

  971. }

  972.  
  973.  
  974. //cvNamedWindow("opencv", CV_WINDOW_AUTOSIZE);

  975.  
  976. const std::string root_path = get_root_path();

  977. std::string save_name="save.jpg";

  978. proto_file = root_path + DEF_PROTO;

  979. model_file = root_path + DEF_MODEL;

  980. image_file = root_path + DEF_IMAGE;

  981.  
  982. open_device();

  983. init_device();

  984. start_capturing();

  985. mainloop();

  986. stop_capturing();

  987. uninit_device();

  988. close_device();

  989. fprintf(stderr, "\n");

  990. waitKey(0);

  991. return 0;

  992. }

     3. 重新make

      回到 examples 目录,执行make\

     正常的话, 会生成 examples/build/mobilenet_ssd_camera 目录

   4. 执行

./MSSD -p ../../../models/MobileNetSSD_deploy.prototxt -m ../../../models/MobileNetSSD_deploy.caffemodel 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值