JeVois  1.21
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
jevois-camtest.C
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
18#include <jevois/Core/Camera.H>
19#include <jevois/Debug/Log.H>
20#include <string.h>
21#include <linux/videodev2.h>
22#include <opencv2/core/core.hpp>
23#include <opencv2/imgproc/imgproc.hpp>
24
25#ifdef JEVOIS_PLATFORM
26#include <opencv2/imgcodecs.hpp>
27#else
28// On older opencv, imwrite is in highgui:
29#include <opencv2/highgui/highgui.hpp>
30#endif
31
32// Comment this out to use the jevois::Camera driver instead of low-level V4L2 code:
33#define USE_RAW_CAMERA
34
35#ifdef USE_RAW_CAMERA
36#define NB_BUFFER 4
37#include <jevois/Util/Utils.H>
38#include <sys/mman.h>
39#include <sys/types.h>
40#include <sys/stat.h>
41#include <fcntl.h>
42#endif
43
44//! Grabs video frames from the camera, and write them to disk as PNG files
45int main(int argc, char const* argv[])
46{
47 jevois::logLevel = LOG_DEBUG;
48
49 if (argc != 5) LFATAL("USAGE: jevois_camtest <YUYV|BAYER|RGB565> <width> <height> <fps>");
50
52 if (strcmp(argv[1], "BAYER") == 0) m.cfmt = V4L2_PIX_FMT_SRGGB8;
53 else if (strcmp(argv[1], "YUYV") == 0) m.cfmt = V4L2_PIX_FMT_YUYV;
54 else if (strcmp(argv[1], "RGB565") == 0) m.cfmt = V4L2_PIX_FMT_RGB565;
55 else LFATAL("Invalid format, should be BAYER, YUYV or RGB565");
56
57 m.cw = std::atoi(argv[2]);
58 m.ch = std::atoi(argv[3]);
59 m.cfps = std::atof(argv[4]);
60
61#ifdef USE_RAW_CAMERA
62 // Simplest V4L2 capture code, taken from http://staticwave.ca/source/uvccapture/
63 int fd; if ((fd = open ("/dev/video0", O_RDWR)) == -1) LFATAL("ERROR opening V4L interface");
64
65 // See what kinds of inputs we have and select the first one that is a camera:
66 int camidx = -1; struct v4l2_input inp = { };
67 while (true)
68 {
69 try { XIOCTL(fd, VIDIOC_ENUMINPUT, &inp); } catch (...) { break; }
70 if (inp.type == V4L2_INPUT_TYPE_CAMERA)
71 {
72 if (camidx == -1) camidx = inp.index;
73 LINFO("Input " << inp.index << " [" << inp.name << "] is a camera sensor");
74 } else LINFO("Input " << inp.index << " [" << inp.name << "] is a NOT camera sensor");
75 ++inp.index;
76 }
77 if (camidx == -1) LFATAL("No valid camera input found");
78
79 // Select the camera input, this seems to be required by VFE for the camera to power on:
80 XIOCTL(fd, VIDIOC_S_INPUT, &camidx);
81
82 // Check capabilities:
83 struct v4l2_capability cap = { };
84 XIOCTL(fd, VIDIOC_QUERYCAP, &cap);
85 if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) LFATAL("Video capture not supported");
86 if (!(cap.capabilities & V4L2_CAP_STREAMING)) LFATAL("Cameradoes not support streaming i/o");
87
88 /* set format in */
89 struct v4l2_format fmt = { };
90 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
91 fmt.fmt.pix.width = m.cw;
92 fmt.fmt.pix.height = m.ch;
93 fmt.fmt.pix.pixelformat = m.cfmt;
94 fmt.fmt.pix.field = V4L2_FIELD_ANY;
95 XIOCTL(fd, VIDIOC_S_FMT, &fmt);
96
97 if ((fmt.fmt.pix.width != m.cw) || (fmt.fmt.pix.height != m.ch)) LFATAL("Format asked unavailable");
98
99 /* request buffers */
100 struct v4l2_requestbuffers rb = { };
101 rb.count = NB_BUFFER;
102 rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
103 rb.memory = V4L2_MEMORY_MMAP;
104 XIOCTL(fd, VIDIOC_REQBUFS, &rb);
105
106 /* map the buffers */
107 void * mem[NB_BUFFER];
108 for (int i = 0; i < NB_BUFFER; i++) {
109 struct v4l2_buffer buf = { };
110 buf.index = i;
111 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 buf.memory = V4L2_MEMORY_MMAP;
113 XIOCTL(fd, VIDIOC_QUERYBUF, &buf);
114
115 mem[i] = mmap(0 /* start anywhere */, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
116 if (mem[i] == MAP_FAILED) LFATAL("Unable to map buffer");
117 }
118
119 /* Queue the buffers. */
120 for (int i = 0; i < NB_BUFFER; ++i) {
121 struct v4l2_buffer buf = { };
122 buf.index = i;
123 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
124 buf.memory = V4L2_MEMORY_MMAP;
125 XIOCTL(fd, VIDIOC_QBUF, &buf);
126 }
127
128 // start streaming
129 int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
130 XIOCTL(fd, VIDIOC_STREAMON, &type);
131 LINFO("Grab start...");
132 for (int i = 0; i < 100; ++i)
133 {
134 struct v4l2_buffer buf = { };
135 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
136 buf.memory = V4L2_MEMORY_MMAP;
137 XIOCTL(fd, VIDIOC_DQBUF, &buf);
138
139 if (i >= 30)
140 {
141 // FIXME we only support YUYV here for now
142 cv::Mat imgbgr;
143 cv::Mat imgcv(m.ch, m.cw, CV_8UC2, mem[buf.index]);
144 cv::cvtColor(imgcv, imgbgr, cv::COLOR_YUV2BGR_YUYV);
145 cv::imwrite(std::string("camtest") + std::to_string(i-30) + ".png", imgbgr);
146 }
147
148 XIOCTL(fd, VIDIOC_QBUF, &buf);
149 }
150 LINFO("All done!");
151
152 // should cleanup, unmap, close, etc
153
154#else // USE_RAW_CAMERA
155 std::shared_ptr<jevois::Camera> cam(new jevois::Camera("/dev/video0"));
156 cam->setFormat(m);
157 LINFO("Stream On");
158 cam->streamOn();
159
160 // First grab a few trash frames to let the auto exposure, gain, white balance, etc stabilize:
161 LINFO("Trashing a few frames...");
163 for (int i = 0; i < 30; ++i) { cam->get(img); cam->done(img); }
164
165 // Now grab a few that we convert and save to disk:
166 LINFO("Grab start...");
167 for (int i = 0; i < 10; ++i)
168 {
169 cam->get(img);
170
171 cv::Mat imgbgr;
172 switch (m.cfmt)
173 {
174 case V4L2_PIX_FMT_SRGGB8:
175 {
176 cv::Mat imgcv(img.height, img.width, CV_8UC1, img.buf->data());
177 cv::cvtColor(imgcv, imgbgr, cv::COLOR_BayerBG2BGR);
178 }
179 break;
180
181 case V4L2_PIX_FMT_YUYV:
182 {
183 cv::Mat imgcv(img.height, img.width, CV_8UC2, img.buf->data());
184 cv::cvtColor(imgcv, imgbgr, cv::COLOR_YUV2BGR_YUYV);
185 }
186 break;
187
188 case V4L2_PIX_FMT_RGB565:
189 {
190 cv::Mat imgcv(img.height, img.width, CV_8UC2, img.buf->data());
191 cv::cvtColor(imgcv, imgbgr, cv::COLOR_BGR5652BGR);
192 }
193 break;
194 }
195
196 cam->done(img);
197 cv::imwrite(std::string("camtest") + std::to_string(i) + ".png", imgbgr);
198 }
199
200 LINFO("All done!");
201 cam->streamOff();
202 cam.reset();
203
204#endif // USE_RAW_CAMERA
205
206 // Terminate logger:
208
209 return 0;
210}
JeVois camera driver class - grabs frames from a Video4Linux camera sensor.
Definition Camera.H:63
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition RawImage.H:111
unsigned int width
Image width in pixels.
Definition RawImage.H:145
unsigned int height
Image height in pixels.
Definition RawImage.H:146
std::shared_ptr< VideoBuf > buf
The pixel data buffer.
Definition RawImage.H:149
int logLevel
Current log level.
Definition Log.C:29
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
Definition Log.H:230
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
Definition Log.H:194
#define XIOCTL(dev, req, mem)
Helper macro to execute an ioctl, ignore interruptions, and, if error, issue a fatal message and thro...
Definition Utils.H:205
#define NB_BUFFER
int main(int argc, char const *argv[])
Grabs video frames from the camera, and write them to disk as PNG files.
void logEnd()
Terminate log service.
Definition Log.C:145
Simple struct to hold video mapping definitions for the processing Engine.
unsigned int cfmt
camera pixel format
float cfps
camera frame rate in frames/sec
unsigned int cw
camera width
unsigned int ch
camera height