开发环境:
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