通过Tengine ssd 处理usb camera 实时图像

开发环境:

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.配置文件

cd ~/tengine
 
cp makefile.config.example makefile.config

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

  3. 编译    

cd ~/tengine
make

 4. 验证

./build/tests/bin/bench_mobilenet -r1

二.  运行自带的ssd example

 1. 编译example

cd ~/tengine/examples
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)

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

  编译

mkdir build
cd build
../linux_build.sh
make -j4 

2. 运行ssd 

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

  • MobileNetSSD_deploy.caffemodel
  • MobileNetSSD_deploy.prototxt

 执行

cd example/build/mobilenet_ssd

./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

/*
 *  V4L2 video capture example
 *
 *  This program can be used and distributed without restrictions.
 *
 *      This program is provided with the V4L2 API
 * see https://linuxtv.org/docs.php for more information
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <iomanip>
#include <vector>
#include <getopt.h>             /* getopt_long() */

#include <fcntl.h>              /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <inttypes.h>

#include <linux/videodev2.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>

#include "tengine_c_api.h"
#include "common.hpp"


#define DEF_PROTO "models/MobileNetSSD_deploy.prototxt"
#define DEF_MODEL "models/MobileNetSSD_deploy.caffemodel"
#define DEF_IMAGE "tests/images/ssd_dog.jpg"

#define CLEAR(x) memset(&(x), 0, sizeof(x))
#define COLS (640)
#define ROWS (480)
#define SSD_IMG_H (300)
#define SSD_IMG_W (300)
using namespace cv;

enum io_method {
        IO_METHOD_READ,
        IO_METHOD_MMAP,
        IO_METHOD_USERPTR,
};

struct buffer {
        void   *start;
        size_t  length;
};

typedef struct buffer* PBUF;

static char            *dev_name;
static enum io_method   io = IO_METHOD_MMAP;
static int              fd = -1;
struct buffer          *buffers;
static unsigned int     n_buffers;
static int              out_buf;
static int              force_format;
static int              frame_count = 70;

static std::string proto_file;
static std::string model_file;
static std::string image_file;
static std::string save_name="save.jpg";
const char *model_name = "mssd_300";
    
cv::Mat yuvImg(ROWS , COLS, CV_8UC2);
cv::Mat rgbImg(ROWS, COLS,CV_8UC3);
cv::Mat resizeImg(SSD_IMG_W, SSD_IMG_H,CV_8UC3);
cv::Mat floatImg(SSD_IMG_W, SSD_IMG_H, CV_32FC3);

static int fpsTick();

struct Box
{
    float x0;
    float y0;
    float x1;
    float y1;
    int class_idx;
    float score;
};

void get_input_data_ssd(std::string& image_file, float* input_data, int img_h,  int img_w)
{
    cv::Mat img = cv::imread(image_file);

    if (img.empty())
    {
        std::cerr << "Failed to read image file " << image_file << ".\n";
        return;
    }
   
    cv::resize(img, img, cv::Size(img_h, img_w));
    img.convertTo(img, CV_32FC3);
    float *img_data = (float *)img.data;
    int hw = img_h * img_w;

    float mean[3]={127.5,127.5,127.5};
    for (int h = 0; h < img_h; h++)
    {
        for (int w = 0; w < img_w; w++)
        {
            for (int c = 0; c < 3; c++)
            {
                input_data[c * hw + h * img_w + w] = 0.007843* (*img_data - mean[c]);
                img_data++;
            }
        }
    }
}

void post_process_ssd(std::string& image_file,float threshold,float* outdata,int num,std::string& save_name)
{
    std::cout<<"post_process_ssd\n";
    const char* class_names[] = {"background",
                            "aeroplane", "bicycle", "bird", "boat",
                            "bottle", "bus", "car", "cat", "chair",
                            "cow", "diningtable", "dog", "horse",
                            "motorbike", "person", "pottedplant",
                            "sheep", "sofa", "train", "tvmonitor"};

    //cv::Mat img = cv::imread(image_file);
    int raw_h = rgbImg.size().height;
    int raw_w = rgbImg.size().width;
    std::vector<Box> boxes;
    int line_width=raw_w*0.005;
    printf("detect ruesult num: %d \n",num);
    for (int i=0;i<num;i++)
    {
        if(outdata[1]>=threshold)
        {
            Box box;
            box.class_idx=outdata[0];
            box.score=outdata[1];
            box.x0=outdata[2]*raw_w;
            box.y0=outdata[3]*raw_h;
            box.x1=outdata[4]*raw_w;
            box.y1=outdata[5]*raw_h;
            boxes.push_back(box);
            printf("%s\t:%.0f%%\n", class_names[box.class_idx], box.score * 100);
            printf("BOX:( %g , %g ),( %g , %g )\n",box.x0,box.y0,box.x1,box.y1);
        }
        outdata+=6;
    }
    for(int i=0;i<(int)boxes.size();i++)
    {
        Box box=boxes[i];
        cv::rectangle(rgbImg, cv::Rect(box.x0, box.y0,(box.x1-box.x0),(box.y1-box.y0)),cv::Scalar(255, 255, 0),line_width);
        std::ostringstream score_str;
        score_str<<box.score;
        std::string label = std::string(class_names[box.class_idx]) + ": " + score_str.str();
        int baseLine = 0;
        cv::Size label_size = cv::getTextSize(label, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
        cv::rectangle(rgbImg, cv::Rect(cv::Point(box.x0,box.y0- label_size.height),
                                  cv::Size(label_size.width, label_size.height + baseLine)),
                      cv::Scalar(255, 255, 0), CV_FILLED);
        cv::putText(rgbImg, label, cv::Point(box.x0, box.y0),
                    cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
    }
    cv::imshow("opencv",rgbImg);
    waitKey(1);
    std::cout<<"======================================\n";
    std::cout<<"[DETECTED IMAGE SAVED]:\t"<< save_name<<"\n";
    std::cout<<"======================================\n";


}

static void errno_exit(const char *s)
{
        fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
        exit(EXIT_FAILURE);
}

static int xioctl(int fh, int request, void *arg)
{
        int r;

        do {
                r = ioctl(fh, request, arg);
        } while (-1 == r && EINTR == errno);

        return r;
}

static void process_image(const void *p, int size,float *input_data,int img_w,  int img_h)
{
    std::cout<<"process_image\n";
    //int fps = fpsTick();
    
    memcpy(yuvImg.data, p, COLS*ROWS*2);
    cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_YUYV);
    
    cv::resize(rgbImg, resizeImg, cv::Size(img_w, img_h));
    resizeImg.convertTo(floatImg, CV_32FC3);
    float *img_data = (float *)floatImg.data;
    int hw = img_h * img_w;

    float mean[3]={127.5,127.5,127.5};
    for (int h = 0; h < img_h; h++)
    {
        for (int w = 0; w < img_w; w++)
        {
            for (int c = 0; c < 3; c++)
            {
                input_data[c * hw + h * img_w + w] = 0.007843* (*img_data - mean[c]);
                img_data++;
            }
        }
    }
    
    //cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_YUYV);
    
    //char title[10];
    //sprintf(title, "fps:%d", fps);
    //cv::imshow("opencv",rgbImg);
    //waitKey(1);
    
    /*
    static int frame_number = 0;
    char fn[256];
    sprintf(fn, "%d.raw", frame_number);
    frame_number++;

    uint8_t *pixel = (uint8_t *) rgbImg.data;
    size = COLS*ROWS*3;
    int found = 0;
    for (int i=0; i < size; i++) {
        if (pixel[i] != 0) {
        found = 1;
        break;
        }
    }

    if (found) {
        FILE *f = fopen(fn, "wb");
        if (f == NULL) { printf("Error opening file\n"); exit(EXIT_FAILURE); }
        fwrite(pixel, size, 1, f);
        fclose(f);

        fprintf(stdout, "%s\n", fn);
        fflush(stdout);
    } else {
        fprintf(stdout, "empty image");
    }
    */
    
}

static int read_frame(float *input_data,int img_w,  int img_h)
{
        struct v4l2_buffer buf;
        unsigned int i;
        static uint64_t timestamp;
        uint64_t stamp =0;

        switch (io) {
        case IO_METHOD_READ:
                if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
                        switch (errno) {
                        case EAGAIN:
                                return 0;

                        case EIO:
                                /* Could ignore EIO, see spec. */

                                /* fall through */

                        default:
                                errno_exit("read");
                        }
                }

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

        case IO_METHOD_MMAP:
                CLEAR(buf);

                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory = V4L2_MEMORY_MMAP;

                if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
                        switch (errno) {
                        case EAGAIN:
                                return 0;

                        case EIO:
                                /* Could ignore EIO, see spec. */

                                /* fall through */

                        default:
                                errno_exit("VIDIOC_DQBUF");
                        }
                }
                stamp = buf.timestamp.tv_sec*1000000+buf.timestamp.tv_usec;
                //printf("timestamp :%ld", timestamp);
                if(timestamp == stamp){
                    break;
                }
                
                assert(buf.index < n_buffers);

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

                if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
                        errno_exit("VIDIOC_QBUF");
                break;

        case IO_METHOD_USERPTR:
                CLEAR(buf);

                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory = V4L2_MEMORY_USERPTR;

                if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
                    
                        switch (errno) {
                        case EAGAIN:
                                return 0;

                        case EIO:
                                /* Could ignore EIO, see spec. */

                                /* fall through */

                        default:
                                errno_exit("VIDIOC_DQBUF");
                        }
                }

                for (i = 0; i < n_buffers; ++i)
                        if (buf.m.userptr == (unsigned long)buffers[i].start
                            && buf.length == buffers[i].length)
                                break;

                assert(i < n_buffers);

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

                if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
                        errno_exit("VIDIOC_QBUF");
                break;
        }

        return 1;
}

static void mainloop(void)
{
        unsigned int count;

        count = frame_count;
        

            // init tengine
        init_tengine_library();
        if (request_tengine_version("0.1") < 0)
            return ;
        if (load_model(model_name, "caffe", proto_file.c_str(), model_file.c_str()) < 0)
            return ;
        std::cout << "load model done!\n";
    
        // create graph
        graph_t graph = create_runtime_graph("graph", model_name, NULL);
        if (!check_graph_valid(graph))
        {
            std::cout << "create graph0 failed\n";
            return ;
        }

        
        int repeat_count = 1;
        const char *repeat = std::getenv("REPEAT_COUNT");

        if (repeat)
            repeat_count = std::strtoul(repeat, NULL, 10);
        
        int node_idx=0;
        int tensor_idx=0;
        tensor_t input_tensor = get_graph_input_tensor(graph, node_idx, tensor_idx);
        if(!check_tensor_valid(input_tensor))
        {
            printf("Get input node failed : node_idx: %d, tensor_idx: %d\n",node_idx,tensor_idx);
            return;
        }

        
        // input
        int img_h = 300;
        int img_w = 300;
        int img_size = img_h * img_w * 3;
        float *input_data = (float *)malloc(sizeof(float) * img_size);
        int dims[] = {1, 3, img_h, img_w};
        set_tensor_shape(input_tensor, dims, 4);
        
        prerun_graph(graph);
    
        while (1) {
           printf("Reading frame\n");
                for (;;) {
                        fd_set fds;
                        struct timeval tv;
                        int r;

                        FD_ZERO(&fds);
                        FD_SET(fd, &fds);

                        /* Timeout. */
                        tv.tv_sec = 2;
                        tv.tv_usec = 0;

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

                        if (-1 == r) {
                                if (EINTR == errno)
                                        continue;
                                errno_exit("select");
                        }

                        if (0 == r) {
                                fprintf(stderr, "select timeout\n");
                                exit(EXIT_FAILURE);
                        }
                        
                        
                        if (read_frame(input_data,img_w, img_h))
                        {
                            std::cout<<"run_graph\n";
                            /* EAGAIN - continue select loop. */
                            set_tensor_buffer(input_tensor, input_data, img_size * 4);
                            run_graph(graph, 1);

                            //gettimeofday(&t1, NULL);
                            //float mytime = (float)((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec)) / 1000;
                            //total_time += mytime;

                            //std::cout << "--------------------------------------\n";
                            //std::cout << "repeat " << repeat_count << " times, avg time per run is " << total_time / repeat_count << " ms\n";
                            
                            tensor_t out_tensor = get_graph_output_tensor(graph, 0,0);//"detection_out");
                            int out_dim[4];
                            get_tensor_shape( out_tensor, out_dim, 4);

                            float *outdata = (float *)get_tensor_buffer(out_tensor);
                            int num=out_dim[1];
                            float show_threshold=0.5;
                            
                            post_process_ssd(image_file,show_threshold, outdata, num,save_name);
                            put_graph_tensor(out_tensor);
                            
                            
                            std::cout<<"run end\n";
                            
                            break;
                        }

                }
                
        }
        
        postrun_graph(graph);
        
        free(input_data);
        
        put_graph_tensor(input_tensor);
        
        

        destroy_runtime_graph(graph);
        remove_model(model_name);

        return;
}

static void stop_capturing(void)
{
        enum v4l2_buf_type type;

        switch (io) {
        case IO_METHOD_READ:
                /* Nothing to do. */
                break;

        case IO_METHOD_MMAP:
        case IO_METHOD_USERPTR:
                type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
                        errno_exit("VIDIOC_STREAMOFF");
                break;
        }
}

static void start_capturing(void)
{
        unsigned int i;
        enum v4l2_buf_type type;

        switch (io) {
        case IO_METHOD_READ:
                /* Nothing to do. */
                break;

        case IO_METHOD_MMAP:
                for (i = 0; i < n_buffers; ++i) {
                        struct v4l2_buffer buf;

                        CLEAR(buf);
                        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                        buf.memory = V4L2_MEMORY_MMAP;
                        buf.index = i;

                        if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
                                errno_exit("VIDIOC_QBUF");
                }
                type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
                        errno_exit("VIDIOC_STREAMON");
                break;

        case IO_METHOD_USERPTR:
                for (i = 0; i < n_buffers; ++i) {
                        struct v4l2_buffer buf;

                        CLEAR(buf);
                        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                        buf.memory = V4L2_MEMORY_USERPTR;
                        buf.index = i;
                        buf.m.userptr = (unsigned long)buffers[i].start;
                        buf.length = buffers[i].length;

                        if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
                                errno_exit("VIDIOC_QBUF");
                }
                type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
                        errno_exit("VIDIOC_STREAMON");
                break;
        }
}

static void uninit_device(void)
{
        unsigned int i;

        switch (io) {
        case IO_METHOD_READ:
                free(buffers[0].start);
                break;

        case IO_METHOD_MMAP:
                for (i = 0; i < n_buffers; ++i)
                        if (-1 == munmap(buffers[i].start, buffers[i].length))
                                errno_exit("munmap");
                break;

        case IO_METHOD_USERPTR:
                for (i = 0; i < n_buffers; ++i)
                        free(buffers[i].start);
                break;
        }

        free(buffers);
}

static void init_read(unsigned int buffer_size)
{
        buffers = (PBUF)calloc(1, sizeof(*buffers));

        if (!buffers) {
                fprintf(stderr, "Out of memory\n");
                exit(EXIT_FAILURE);
        }

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

        if (!buffers[0].start) {
                fprintf(stderr, "Out of memory\n");
                exit(EXIT_FAILURE);
        }
}

static void init_mmap(void)
{
        struct v4l2_requestbuffers req;

        CLEAR(req);

        req.count = 4;
        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req.memory = V4L2_MEMORY_MMAP;

        if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
                if (EINVAL == errno) {
                        fprintf(stderr, "%s does not support "
                                 "memory mapping\n", dev_name);
                        exit(EXIT_FAILURE);
                } else {
                        errno_exit("VIDIOC_REQBUFS");
                }
        }

        if (req.count < 2) {
                fprintf(stderr, "Insufficient buffer memory on %s\n",
                         dev_name);
                exit(EXIT_FAILURE);
        }

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

        if (!buffers) {
                fprintf(stderr, "Out of memory\n");
                exit(EXIT_FAILURE);
        }

        for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
                struct v4l2_buffer buf;

                CLEAR(buf);

                buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                buf.memory      = V4L2_MEMORY_MMAP;
                buf.index       = n_buffers;

                if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
                        errno_exit("VIDIOC_QUERYBUF");

                buffers[n_buffers].length = buf.length;
                buffers[n_buffers].start =
                        mmap(NULL /* start anywhere */,
                              buf.length,
                              PROT_READ | PROT_WRITE /* required */,
                              MAP_SHARED /* recommended */,
                              fd, buf.m.offset);

                if (MAP_FAILED == buffers[n_buffers].start)
                        errno_exit("mmap");
        }
}

static void init_userp(unsigned int buffer_size)
{
        struct v4l2_requestbuffers req;

        CLEAR(req);

        req.count  = 4;
        req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        req.memory = V4L2_MEMORY_USERPTR;

        if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
                if (EINVAL == errno) {
                        fprintf(stderr, "%s does not support "
                                 "user pointer i/o\n", dev_name);
                        exit(EXIT_FAILURE);
                } else {
                        errno_exit("VIDIOC_REQBUFS");
                }
        }

        buffers = (PBUF)calloc(4, sizeof(*buffers));

        if (!buffers) {
                fprintf(stderr, "Out of memory\n");
                exit(EXIT_FAILURE);
        }

        for (n_buffers = 0; n_buffers < 4; ++n_buffers) {
                buffers[n_buffers].length = buffer_size;
                buffers[n_buffers].start = malloc(buffer_size);

                if (!buffers[n_buffers].start) {
                        fprintf(stderr, "Out of memory\n");
                        exit(EXIT_FAILURE);
                }
        }
}

static void init_device(void)
{
        struct v4l2_capability cap;
        struct v4l2_cropcap cropcap;
        struct v4l2_crop crop;
        struct v4l2_format fmt;
        unsigned int min;

        if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
                if (EINVAL == errno) {
                        fprintf(stderr, "%s is no V4L2 device\n",
                                 dev_name);
                        exit(EXIT_FAILURE);
                } else {
                        errno_exit("VIDIOC_QUERYCAP");
                }
        }

        if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
                fprintf(stderr, "%s is no video capture device\n",
                         dev_name);
                exit(EXIT_FAILURE);
        }

        switch (io) {
        case IO_METHOD_READ:
                if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
                        fprintf(stderr, "%s does not support read i/o\n",
                                 dev_name);
                        exit(EXIT_FAILURE);
                }
                break;

        case IO_METHOD_MMAP:
        case IO_METHOD_USERPTR:
                if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
                        fprintf(stderr, "%s does not support streaming i/o\n",
                                 dev_name);
                        exit(EXIT_FAILURE);
                }
                break;
        }


        /* Select video input, video standard and tune here. */

  struct v4l2_format format = {0};
  format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  format.fmt.pix.width = COLS;
  format.fmt.pix.height = ROWS;
  format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  format.fmt.pix.field = V4L2_FIELD_NONE;
  int retval = xioctl(fd, VIDIOC_S_FMT, &format);
  if (retval == -1) { perror("Setting format\n"); return; }


//
//        CLEAR(cropcap);
//
//        cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
//
//        if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
//                crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
//                crop.c = cropcap.defrect; /* reset to default */
//
//                if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
//                        switch (errno) {
//                        case EINVAL:
//                                /* Cropping not supported. */
//                                break;
//                        default:
//                                /* Errors ignored. */
//                                break;
//                        }
//                }
//        } else {
//                /* Errors ignored. */
//        }
//
//
//        CLEAR(fmt);
//
//        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
//        if (force_format) {
//                fmt.fmt.pix.width       = 640;
//                fmt.fmt.pix.height      = 480;
//                fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
//                fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
//
//                if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
//                        errno_exit("VIDIOC_S_FMT");
//
//                /* Note VIDIOC_S_FMT may change width and height. */
//        } else {
//                /* Preserve original settings as set by v4l2-ctl for example */
//                if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt))
//                        errno_exit("VIDIOC_G_FMT");
//        }
//
//        /* Buggy driver paranoia. */
//        min = fmt.fmt.pix.width * 2;
//        if (fmt.fmt.pix.bytesperline < min)
//                fmt.fmt.pix.bytesperline = min;
//        min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
//        if (fmt.fmt.pix.sizeimage < min)
//                fmt.fmt.pix.sizeimage = min;
//
        switch (io) {
        case IO_METHOD_READ:
                init_read(fmt.fmt.pix.sizeimage);
                break;

        case IO_METHOD_MMAP:
                init_mmap();
                break;

        case IO_METHOD_USERPTR:
                init_userp(fmt.fmt.pix.sizeimage);
                break;
        }
}

static void close_device(void)
{
        if (-1 == close(fd))
                errno_exit("close");

        fd = -1;
}

static void open_device(void)
{
        struct stat st;

        if (-1 == stat(dev_name, &st)) {
                fprintf(stderr, "Cannot identify '%s': %d, %s\n",
                         dev_name, errno, strerror(errno));
                exit(EXIT_FAILURE);
        }

        if (!S_ISCHR(st.st_mode)) {
                fprintf(stderr, "%s is no device\n", dev_name);
                exit(EXIT_FAILURE);
        }

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

        if (-1 == fd) {
                fprintf(stderr, "Cannot open '%s': %d, %s\n",
                         dev_name, errno, strerror(errno));
                exit(EXIT_FAILURE);
        }
}


static int fpsTick()
{

    static clock_t last=clock();
    static clock_t avgDuration = 0;
    static float alpha = 1.f/10.f;
    static int frameCount = 0;
    
    clock_t now = clock();
    clock_t delta = now-last;
    
    printf("delta clock:%d\n", delta);
    last = now;
    
    
    frameCount++;
    
    int fps = 0;
    if(1 == frameCount)
    {
        avgDuration = delta;
    }
    else
    {
        avgDuration = avgDuration * (1.f - alpha) + delta * alpha;
    }
    
    fps = (1.f * CLOCKS_PER_SEC/ avgDuration);
    printf("fps :%d\n", fps);
    
    
}

static void usage(FILE *fp, int argc, char **argv)
{
        fprintf(fp,
                 "Usage: %s [options]\n\n"
                 "Version 1.3\n"
                 "Options:\n"
                 "-d | --device name   Video device name [%s]\n"
                 "-h | --help          Print this message\n"
                 "-m | --mmap          Use memory mapped buffers [default]\n"
                 "-r | --read          Use read() calls\n"
                 "-u | --userp         Use application allocated buffers\n"
                 "-o | --output        Outputs stream to stdout\n"
                 "-f | --format        Force format to 640x480 YUYV\n"
                 "-c | --count         Number of frames to grab [%i]\n"
                 "",
                 argv[0], dev_name, frame_count);
}

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

static const struct option
long_options[] = {
        { "device", required_argument, NULL, 'd' },
        { "help",   no_argument,       NULL, 'h' },
        { "mmap",   no_argument,       NULL, 'm' },
        { "read",   no_argument,       NULL, 'r' },
        { "userp",  no_argument,       NULL, 'u' },
        { "output", no_argument,       NULL, 'o' },
        { "format", no_argument,       NULL, 'f' },
        { "count",  required_argument, NULL, 'c' },
        { 0, 0, 0, 0 }
};

int main(int argc, char **argv)
{
        dev_name = "/dev/video0";

        for (;;) {
                int idx;
                int c;

                c = getopt_long(argc, argv,
                                short_options, long_options, &idx);

                if (-1 == c)
                        break;

                switch (c) {
                case 0: /* getopt_long() flag */
                        break;

                case 'd':
                        dev_name = optarg;
                        break;

                case 'h':
                        usage(stdout, argc, argv);
                        exit(EXIT_SUCCESS);

                case 'm':
                        io = IO_METHOD_MMAP;
                        break;

                case 'r':
                        io = IO_METHOD_READ;
                        break;

                case 'u':
                        io = IO_METHOD_USERPTR;
                        break;

                case 'o':
                        out_buf++;
                        break;

                case 'f':
                        force_format++;
                        break;

                case 'c':
                        errno = 0;
                        frame_count = strtol(optarg, NULL, 0);
                        if (errno)
                                errno_exit(optarg);
                        break;

                default:
                        usage(stderr, argc, argv);
                        exit(EXIT_FAILURE);
                }
        }
        
    
        //cvNamedWindow("opencv", CV_WINDOW_AUTOSIZE);
        
        const std::string root_path = get_root_path();
        std::string save_name="save.jpg";
        proto_file = root_path + DEF_PROTO;
        model_file = root_path + DEF_MODEL;
        image_file = root_path + DEF_IMAGE;
    
        open_device();
        init_device();
        start_capturing();
        mainloop();
        stop_capturing();
        uninit_device();
        close_device();
        fprintf(stderr, "\n");
        waitKey(0);
        return 0;
}

     3. 重新make

      回到 examples 目录,执行make\

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

   4. 执行

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值