appkit  1.5.1
RoadNarrows Robotics Application Kit
CameraCv.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Application Tool Kit
4 //
5 // Library: librnr_cam
6 //
7 // File: CameraCv.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2014-06-18 14:51:56 -0600 (Wed, 18 Jun 2014) $
12  * $Rev: 3667 $
13  *
14  * \brief OpenCv video and still image camera class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  * \author Daniel Packard (daniel@roadnarrows.com)
18  *
19  * \par Copyright
20  * \h_copy 2012-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Permission is hereby granted, without written agreement and without
28  * license or royalty fees, to use, copy, modify, and distribute this
29  * software and its documentation for any purpose, provided that
30  * (1) The above copyright notice and the following two paragraphs
31  * appear in all copies of the source code and (2) redistributions
32  * including binaries reproduces these notices in the supporting
33  * documentation. Substantial modifications to this software may be
34  * copyrighted by their authors and need not follow the licensing terms
35  * described here, provided that the new terms are clearly indicated in
36  * all files where they apply.
37  *
38  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
39  * OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
40  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
41  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
42  * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
43  * THE POSSIBILITY OF SUCH DAMAGE.
44  *
45  * THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
46  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
47  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
48  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
49  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
50  *
51  * @EulaEnd@
52  */
53 ////////////////////////////////////////////////////////////////////////////////
54 
55 #include <unistd.h>
56 #include <stdio.h>
57 
58 #include "rnr/rnrconfig.h"
59 #include "rnr/log.h"
60 
61 #include "rnr/appkit/Camera.h"
62 #include "rnr/appkit/CameraCv.h"
63 
64 #include "opencv/cv.h"
65 #include "opencv/highgui.h"
66 
67 
68 using namespace std;
69 using namespace rnr;
70 using namespace cv;
71 
72 
73 //-----------------------------------------------------------------------------
74 // OpenCv Derived Camera Class
75 //-----------------------------------------------------------------------------
76 
77 CameraCv::CameraCv(const std::string &strVideoDevName,
78  const CamRes &resVideo,
79  const CamRes &resImage) :
80  Camera(strVideoDevName, resVideo, resImage)
81 {
82 }
83 
85 {
86  stopVideo();
87 }
88 
89 int CameraCv::startVideo(const CamRes &resVideo)
90 {
91  CamRes res = resVideo;
92  Mat img;
93 
94  // default is the current video resolution
95  if( isEqResolution(res, CamResDft) )
96  {
97  res = m_resVideo;
98  }
99 
100  errno = 0;
101 
102  // start video
103  if( !isCameraRunning() )
104  {
105  // start OpenCV video capture
106  if( !m_capture.open(m_nVideoIndex) )
107  {
108  LOGSYSERROR("%s: Could not open video device.",
109  m_strVideoDevName.c_str());
110  m_bFatal = true;
111  return RC_ERROR;
112  }
113  }
114 
115  m_bCameraRunning = true;
116 
117  // always set video resolution else camera may default to an alternate size
119 
120  //
121  // Grab a frame into internal buffer to get the actual resolution.
122  //
123  if( grabFrame(img) < 0 )
124  {
125  LOGERROR("Cannot determine captured image size, using defaults");
127  }
128 
129  // set actual resolution
130  else
131  {
132  m_resVideo.width = img.cols;
133  m_resVideo.height = img.rows;
134  }
135 
136  // update current to match video
138 
139  LOGDIAG3("Capturing %dx%d video.", m_resVideo.width, m_resVideo.height);
140 
141  return OK;
142 }
143 
145 {
146  if( !isCameraRunning() )
147  {
148  LOGDIAG3("Video capture already stoped.");
149  return OK;
150  }
151 
152  // capture frame will be released here also
153  m_capture.release();
154 
155  m_bCameraRunning = false;
156 
157  LOGDIAG3("Video capturing stopped.");
158 }
159 
160 int CameraCv::grabFrame(Mat &frame)
161 {
162  if( !isCameraRunning() )
163  {
164  LOGERROR("No video capture object.");
165  return RC_ERROR;
166  }
167 
168  // grab a frame into internal buffer
169  else if( !m_capture.grab() )
170  {
171  LOGERROR("Frame grab() failed.");
172  return RC_ERROR;
173  }
174 
175  // convert grabbed frame to RGB image (not saved)
176  else if( !m_capture.retrieve(frame) )
177  {
178  LOGERROR("Frame retrieve() failed.");
179  return RC_ERROR;
180  }
181 
182  else
183  {
184  return OK;
185  }
186 }
187 
188 int CameraCv::clickImage(Mat &img, const CamRes &resImage)
189 {
190  CamRes resVideoPrev = m_resVideo;
191  bool bCamWasRunning = isCameraRunning();
192  CamRes res = resImage;
193  int rc;
194 
195  m_bTakingImage = true;
196 
197  // default is the current image resolution
198  if( isEqResolution(res, CamResDft) )
199  {
200  res = m_resImage;
201  }
202 
203  //
204  // Camera not running - start camera at image resolution.
205  //
206  if( !isCameraRunning() )
207  {
208  if( (rc = startVideo(res)) < 0 )
209  {
210  m_bTakingImage = false;
211  return RC_ERROR;
212  }
213  }
214 
215  //
216  // Camera already running, but at a different resolution. Set camera at image
217  // resolution.
218  //
219  else if( !isEqResolution(res, m_resCurrent) )
220  {
221  setCameraResolution(res);
222  }
223 
225 
226  //
227  // Grab a video frame.
228  //
229  if( grabFrame(img) < 0 )
230  {
231  LOGERROR("Cannot grab a snap shot.");
232  m_bTakingImage = false;
233  return RC_ERROR;
234  }
235 
236  //
237  // Success
238  //
239  m_resImage.width = img.cols;
240  m_resImage.height = img.rows;
241 
242  LOGDIAG3("Took a %dx%d still image.", m_resImage.width, m_resImage.height);
243 
244  m_bTakingImage = false;
245 
246  m_resVideo = resVideoPrev;
247 
249  {
251  }
252 
253  if( !bCamWasRunning )
254  {
255  stopVideo();
256  }
257 
258  return OK;
259 }
260 
262 {
263 }
264 
266 {
267  m_capture.set(CV_CAP_PROP_FRAME_WIDTH, res.width);
268  m_capture.set(CV_CAP_PROP_FRAME_HEIGHT, res.height);
269 
270  m_resCurrent = res;
271 
272  return m_resCurrent;
273 }
static bool isEqResolution(const CamRes &res1, const CamRes &res2)
Check is two camera resolutions are equal.
Definition: Camera.h:257
virtual void autoFocus()
Auto-focus camera.
Definition: CameraCv.cxx:261
CamRes m_resCurrent
current camera resolution
Definition: Camera.h:295
virtual int startVideo(const CamRes &resVideo=CamResDft)
Start the camera streaming video.
Definition: CameraCv.cxx:89
Video and still image camera base class.
const CamRes CamResDft
default resolution
Definition: Camera.h:89
virtual CamRes setCameraResolution(const CamRes &res)
Set the camera resolution in either video or still image mode.
Definition: Camera.h:309
bool m_bTakingImage
taking an image is [not] finished
Definition: Camera.h:299
CamRes m_resVideo
current video resolution
Definition: Camera.h:296
bool m_bCameraRunning
camera is [not] on and running video
Definition: Camera.h:298
Camera base class.
Definition: Camera.h:125
virtual ~CameraCv()
Destructor.
Definition: CameraCv.cxx:84
OpenCv video and still image camera class.
virtual int clickImage(cv::Mat &img, const CamRes &resImage=CamResDft)
Take a still image.
Definition: CameraCv.cxx:188
const CamRes CamResQVGA
Quarter VGA 320 x 240 res.
Definition: Camera.h:90
virtual CamRes setCameraResolution(const CamRes &res)
Set the camera resolution in either video or still image mode.
Definition: CameraCv.cxx:265
virtual int stopVideo()
Stop the camera from streaming video.
Definition: CameraCv.cxx:144
Camera resolution structure.
Definition: Camera.h:79
virtual int stopVideo()
Stop the camera from streaming video.
Definition: Camera.h:179
virtual int grabFrame(cv::Mat &frame)
Grab a image frame from the video stream.
Definition: Camera.h:193
int width
width in pixels
Definition: Camera.h:81
int height
height in pixels
Definition: Camera.h:82
int m_nVideoIndex
video index
Definition: Camera.h:294
CamRes m_resImage
current still image resolution
Definition: Camera.h:297
std::string m_strVideoDevName
video device name
Definition: Camera.h:293
virtual int startVideo(const CamRes &resVideo=CamResDft)
Start the camera streaming video.
Definition: Camera.h:152
virtual int grabFrame(cv::Mat &frame)
Grab a image frame from the video stream.
Definition: CameraCv.cxx:160
bool isCameraRunning() const
Test if the camera is on and running.
Definition: Camera.h:224
RoadNarrows Robotics.
Definition: Camera.h:74
bool m_bFatal
camera instance is in a fatal state
Definition: Camera.h:300