Camera.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include "find_object/Camera.h"
29 #include "find_object/Settings.h"
31 #include "find_object/QtOpenCV.h"
32 
33 #include <stdio.h>
34 #include <opencv2/imgproc/imgproc.hpp>
35 #if CV_MAJOR_VERSION > 3
36 #include <opencv2/videoio/videoio_c.h>
37 #endif
38 #include <QtCore/QFile>
39 #include "utilite/UDirectory.h"
40 #include "CameraTcpServer.h"
41 
42 namespace find_object {
43 
44 Camera::Camera(QObject * parent) :
45  QObject(parent),
46  currentImageIndex_(0),
47  cameraTcpServer_(0)
48 {
49  qRegisterMetaType<cv::Mat>("cv::Mat");
50  connect(&cameraTimer_, SIGNAL(timeout()), this, SLOT(takeImage()));
51 }
52 
54 {
55  this->stop();
56 }
57 
59 {
60  stopTimer();
61  capture_.release();
62  images_.clear();
65  {
66  cameraTcpServer_->close();
67  delete cameraTcpServer_;
68  cameraTcpServer_ = 0;
69  }
70 }
71 
73 {
74  stopTimer();
75 }
76 
78 {
79  if(images_.size())
80  {
81  return images_.size();
82  }
83  else if(capture_.isOpened())
84  {
85  return (int)capture_.get(CV_CAP_PROP_FRAME_COUNT);
86  }
87  return 0;
88 }
89 
91 {
92  if(images_.size())
93  {
94  return currentImageIndex_;
95  }
96  else if(capture_.isOpened())
97  {
98  return (int)capture_.get(CV_CAP_PROP_POS_FRAMES);
99  }
100  return 0;
101 }
102 
103 void Camera::moveToFrame(int frame)
104 {
105  if(frame < images_.size())
106  {
107  currentImageIndex_ = frame;
108  }
109  else if(capture_.isOpened() && frame < (int)capture_.get(CV_CAP_PROP_FRAME_COUNT))
110  {
111  capture_.set(CV_CAP_PROP_POS_FRAMES, frame);
112  }
113 }
114 
116 {
117  if(cameraTcpServer_)
118  {
119  return cameraTcpServer_->getPort();
120  }
121  return 0;
122 }
123 
125 {
126  cv::Mat img;
127  if(capture_.isOpened())
128  {
129  capture_.read(img);// capture a frame
130  }
131  else if(!images_.empty())
132  {
133  if(currentImageIndex_ < (unsigned int)images_.size())
134  {
135  img = cv::imread(images_[currentImageIndex_++]);
136  }
137  }
138  else if(cameraTcpServer_)
139  {
140  img = cameraTcpServer_->getImage();
141  if(cameraTcpServer_->imagesBuffered() > 0 && Settings::getCamera_9queueSize() == 0)
142  {
143  UWARN("%d images buffered so far...", cameraTcpServer_->imagesBuffered());
144  }
145  }
146 
147  if(img.empty())
148  {
149  if(cameraTcpServer_)
150  {
152  {
153  cameraTcpServer_->waitForNewConnection(100);
154  }
155  }
156  else
157  {
158  // In case of a directory of images or a video
159  this->stop();
160  Q_EMIT finished(); // notify that there are no more images
161  }
162  }
163  else
164  {
165  //resize
166  if( Settings::getCamera_2imageWidth() &&
167  Settings::getCamera_3imageHeight() &&
168  Settings::getCamera_2imageWidth() != img.cols &&
169  Settings::getCamera_3imageHeight() != img.rows)
170  {
171  cv::Mat resampled;
172  cv::resize(img, resampled, cv::Size(Settings::getCamera_2imageWidth(), Settings::getCamera_3imageHeight()));
173  Q_EMIT imageReceived(resampled);
174  }
175  else if(capture_.isOpened())
176  {
177  Q_EMIT imageReceived(img.clone()); // clone required with VideoCapture::read()
178  }
179  else
180  {
181  Q_EMIT imageReceived(img); // clone not required with cv::imread()
182  }
183  }
184 }
185 
187 {
188  if(!capture_.isOpened() && images_.empty() && cameraTcpServer_ == 0)
189  {
190  if(Settings::getCamera_6useTcpCamera())
191  {
192  cameraTcpServer_ = new CameraTcpServer(Settings::getCamera_8port(), this);
193  if(!cameraTcpServer_->isListening())
194  {
195  UWARN("CameraTCP: Cannot listen to port %d", cameraTcpServer_->getPort());
196  delete cameraTcpServer_;
197  cameraTcpServer_ = 0;
198  }
199  else
200  {
201  UINFO("CameraTCP: listening to port %d (IP=%s)",
203  cameraTcpServer_->getHostAddress().toString().toStdString().c_str());
204  }
205  }
206  else
207  {
208  QString path = Settings::getCamera_5mediaPath();
209  if(UDirectory::exists(path.toStdString()))
210  {
211  //Images directory
212  QString ext = Settings::getGeneral_imageFormats();
213  ext.remove('*');
214  ext.remove('.');
215  UDirectory dir(path.toStdString(), ext.toStdString()); // this will load fileNames matching the extensions (in natural order)
216  const std::list<std::string> & fileNames = dir.getFileNames();
217  currentImageIndex_ = 0;
218  images_.clear();
219  // Modify to have full path
220  for(std::list<std::string>::const_iterator iter = fileNames.begin(); iter!=fileNames.end(); ++iter)
221  {
222  images_.append(path.toStdString() + UDirectory::separator() + *iter);
223  }
224  UINFO("Camera: Reading %d images from directory \"%s\"...", (int)images_.size(), path.toStdString().c_str());
225  if(images_.isEmpty())
226  {
227  UWARN("Camera: Directory \"%s\" is empty (no images matching the \"%s\" extensions). "
228  "If you want to disable loading automatically this directory, "
229  "clear the Camera/mediaPath parameter. By default, webcam will be used instead of the directory.",
230  path.toStdString().c_str(),
231  ext.toStdString().c_str());
232  }
233  }
234  else if(!path.isEmpty())
235  {
236  //Video file
237  capture_.open(path.toStdString().c_str());
238  if(!capture_.isOpened())
239  {
240  UWARN("Camera: Cannot open file \"%s\". If you want to disable loading "
241  "automatically this video file, clear the Camera/mediaPath parameter. "
242  "By default, webcam will be used instead of the file.", path.toStdString().c_str());
243  }
244  else
245  {
246  UINFO("Camera: Reading from video file \"%s\"...", path.toStdString().c_str());
247  }
248  }
249  if(!capture_.isOpened() && images_.empty())
250  {
251  //set camera device
252  capture_.open(Settings::getCamera_1deviceId());
253  if(Settings::getCamera_2imageWidth() && Settings::getCamera_3imageHeight())
254  {
255  capture_.set(CV_CAP_PROP_FRAME_WIDTH, double(Settings::getCamera_2imageWidth()));
256  capture_.set(CV_CAP_PROP_FRAME_HEIGHT, double(Settings::getCamera_3imageHeight()));
257  }
258  UINFO("Camera: Reading from camera device %d...", Settings::getCamera_1deviceId());
259  }
260  }
261  }
262  if(!capture_.isOpened() && images_.empty() && cameraTcpServer_ == 0)
263  {
264  UERROR("Camera: Failed to open a capture object!");
265  return false;
266  }
267 
268  startTimer();
269  return true;
270 }
271 
273 {
274  updateImageRate();
275  cameraTimer_.start();
276 }
277 
279 {
280  cameraTimer_.stop();
281 }
282 
284 {
285  if(Settings::getCamera_4imageRate())
286  {
287  cameraTimer_.setInterval((int)(1000.0/Settings::getCamera_4imageRate()));
288  }
289  else
290  {
291  cameraTimer_.setInterval(0);
292  }
293 }
294 
295 } // namespace find_object
296 
QHostAddress getHostAddress() const
virtual void takeImage()
Definition: Camera.cpp:124
virtual bool start()
Definition: Camera.cpp:186
QTimer cameraTimer_
Definition: Camera.h:73
static std::string separator()
Definition: UDirectory.cpp:365
const std::list< std::string > & getFileNames() const
Definition: UDirectory.h:125
void imageReceived(const cv::Mat &image)
void moveToFrame(int frame)
Definition: Camera.cpp:103
virtual void updateImageRate()
Definition: Camera.cpp:283
int getTotalFrames()
Definition: Camera.cpp:77
unsigned int currentImageIndex_
Definition: Camera.h:75
virtual void stop()
Definition: Camera.cpp:58
Camera(QObject *parent=0)
Definition: Camera.cpp:44
CameraTcpServer * cameraTcpServer_
Definition: Camera.h:76
#define UERROR(...)
ULogger class and convenient macros.
#define UWARN(...)
cv::VideoCapture capture_
Definition: Camera.h:72
static bool exists(const std::string &dirPath)
Definition: UDirectory.cpp:238
int getCurrentFrameIndex()
Definition: Camera.cpp:90
QList< std::string > images_
Definition: Camera.h:74
virtual ~Camera()
Definition: Camera.cpp:53
#define UINFO(...)


find_object_2d
Author(s): Mathieu Labbe
autogenerated on Mon Dec 12 2022 03:20:09