Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
VideoSource_Base.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <bias_config.h>
26 #include "VideoSource_Base.hh"
27 #include <Base/Image/ImageIO.hh>
28 #include <Base/Image/ImageConvert.hh>
29 
30 #include <Image/VideoStream.hh>
31 #include <Image/Camera.hh>
32 
33 
34 #include <Base/Common/BIASpragma.hh>
35 
36 #ifdef __APPLE__
37 # include <sys/types.h> // for fchmod
38 # include <sys/stat.h>
39 #endif
40 
41 // for gcc 4.7
42 #ifndef WIN32
43 #include <unistd.h>
44 #include <sys/stat.h>
45 #endif
46 
47 
48 using namespace BIAS;
49 using namespace std;
50 
51 
52 // for O_APPEND
53 #include <fcntl.h>
54 
56 {
57  Width_ = 0;
58  Height_= 0;
59  ColorChannels_ = 0;
60  DeviceChannel_ = 0;
61  BytesPerPixel_ = 1.0; // assume 8bpp as default
62  CompleteInitialized_ = false;
63  Active_ = false;
64  Grabbing_ = false;
65  DefaultDevice_ = NULL;
66  DirectToDisk_ = false;
67  DtDFd_ = 0;
68  DtDBuffer_ = NULL;
69  DtDBufferSize_ = 0;
70  IsControllable_ = false;
71  Identifier_ = "Uninitialized";
72  WaitForNew_ = true;
73  bExternalTrigger_ = false;
74  minContrast_ = 0; //?
75  maxContrast_ = 100;
76  minGain_=0; //db
77  maxGain_ = 255;
78  minShutter_ = 0; //ms
79  maxShutter_ = 200;
80  minBrightness_ =0; //additive offset in pixel values
81  maxBrightness_ = 200;
82  FramesPerSecond_ = 0;
83 }
84 
85 
87 {
88 
89 }
90 
91 
92 void VideoSource::SetSize(int w, int h, int bytesperpixel)
93 {
94  Width_ = w;
95  Height_ = h;
96  BytesPerPixel_ = float(bytesperpixel);
97  BIASDOUT(D_DCAM, "Width, height:"<<Width_<<"x"<<Height_);
98 }
99 
101 {
102  ColorMode_ = mode;
104  ColorChannels_ = 3;
116  ColorChannels_ = 4;
117  return 0;
118 }
119 
121  if (!Image.IsEmpty())
122  BIASERR("VideoSource::InitImage() should be called with uninitialized image");
123 
125 
126  if (BytesPerPixel_ == 2.0) {
128  }
129  if (Image.GetStorageType() != ImageBase::ST_invalid){
130  if (Image.GetStorageType() != st){
131  BIASERR("invalid storage type");
132  return -1;
133  }
134  }
135 
136 
137  Image.Init(Width_, Height_, ColorChannels_, st);
138  Image.SetColorModel(ColorMode_);
139  return 0;
140 }
141 
142 
144 {
145  if (! CompleteInitialized_) {
146  BIASERR("VideoSource::PreGrab() : Object not completely initialized");
147  return -1;
148  }
149 
150  if (Active_) {
151  BIASERR("VideoSource::PreGrab() : Object already active");
152  return -1;
153  }
154 
155  Active_ = true;
156 
157  return 0;
158 }
159 
161 {
162  Active_ = false;
163  return 0;
164 }
165 
166 // Virtual functions , they should not be called nor implemented
168 {
169  BIASERR("VideoSource_Base::OpenDevice() should not be called directly");
170  return -1;
171 }
172 
173 int VideoSource::OpenDevice(int device)
174 {
175  BIASERR("VideoSource_Base::OpenDevice(int device) should not be called directly");
176  return -1;
177 }
178 
179 int VideoSource::OpenDevice(const char *f)
180 {
181  BIASERR("VideoSource_Base::OpenDevice((const char *filename) should not be called directly");
182  return -1;
183 }
184 
185 int VideoSource::OpenDevice(string Prefix, string Postfix, int DigitCount, int PictureCount,int StartCount)
186 {
187  BIASERR("VideoSource_Base::OpenDevice(string Prefix, string Postfix, int DigitCount, int PictureCount) should not be called directly");
188  return -1;
189 }
190 
191 int VideoSource::OpenDevice(const vector<string> &FileNames)
192 {
193  BIASERR("VideoSource_Base::OpenDevice(vector<string> FileNames) should not be called directly");
194  return -1;
195 }
196 
197 int VideoSource::GetAllDevices(std::vector<std::string> &devices)
198 {
199  BIASERR("VideoSource_Base::GetAllDevices(std::vector<std::string> &devices) should not be called directly");
200  return -1;
201 }
202 
204 {
205  BIASERR("VideoSource_Base::GetCapabilities() should not be called directly");
206  return -1;
207 }
208 
210 {
211  BIASERR("VideoSource_Base::GetCapabilities() should not be called directly");
212  return -1;
213 }
214 
215 
217 {
218  BIASERR("VideoSource_Base::CloseDevice() should not be called directly");
219  return -1;
220 }
221 
223 {
224  BIASERR("VideoSource_Base::GrabSingle() should not be called, please overload");
225  return -1;
226 }
227 
228 
230 {
231  BIASERR("VideoSource_Base::GrabSingle() should not be called, please overload");
232  return -1;
233 }
234 
235 #ifdef BUILD_IMAGE_USHORT
237 {
238  BIASERR("VideoSource::GrabSingle() should not be called, please overload");
239  return -1;
240 }
241 #endif
242 
243 #ifdef BUILD_IMAGE_UINT
245 {
246  BIASERR("VideoSource::GrabSingle() should not be called, please overload");
247  return -1;
248 }
249 #endif
250 
251 #ifdef BUILD_IMAGE_CHAR
253 {
254  BIASERR("VideoSource_Base::GrabSingle() should not be called, please overload");
255  return -1;
256 }
257 #endif
258 
259 #ifdef BUILD_IMAGE_SHORT
261 {
262  BIASERR("VideoSource::GrabSingle() should not be called, please overload");
263  return -1;
264 }
265 #endif
266 
267 #ifdef BUILD_IMAGE_INT
269 {
270  BIASERR("VideoSource_Base::GrabSingle() should not be called, please overload");
271  return -1;
272 }
273 #endif
274 
275 #ifdef BUILD_IMAGE_DOUBLE
277 {
278  BIASERR("VideoSource::GrabSingle() should not be called, please overload");
279  return -1;
280 }
281 #endif
282 
283 int VideoSource::AutoMode(int a, bool b)
284 {
285  BIASERR("VideoSource_Base::AutoMode() should not be called, please overload");
286  return -1;
287 }
288 
289 
290 unsigned int VideoSource::GetFeature(int a)
291 {
292  BIASERR("VideoSource_Base::GetFeature() should not be called, please overload");
293  return 0;
294 }
295 
296  int VideoSource::SetFeature(int a, unsigned int b)
297 {
298  BIASERR("VideoSource_Base::setFeature() should not be called, please overload");
299  return -1;
300 }
301 
302 
303 int VideoSource::SetShutter(float exptime)
304 {
305  BIASERR("VideoSource_Base::SetShutter() should not be called, please overload");
306  return -1;
307 }
308 
310 {
311  BIASERR("VideoSource_Base::SetGain() should not be called, please overload");
312  return -1;
313 }
314 
316 {
317  BIASERR("VideoSource_Base::GetGain() should not be called, please overload");
318  return -1;
319 }
320 
322 {
323  BIASERR("VideoSource_Base::GetShutter() should not be called, please overload");
324  return -1;
325 }
326 int VideoSource::OnePushAuto( int feature) {
327  BIASERR("VideoSource_Base::OnePushAuto() should not be called,please overload");
328  return -1;
329 }
330 int VideoSource::SetWhiteBalance(float rvalue,float bvalue){
331  BIASERR("VideoSource_Base::SetWhiteBalance() should not be called,please overload");
332  return -1;
333 }
334 
335 int VideoSource::GetWhiteBalance(float &rvalue,float &bvalue){
336  BIASERR("VideoSource_Base::SetWhiteBalance() should not be called,please overload");
337  return -1;
338 }
339 
340 
342 {
343  float rGain=0.0, bGain=0.0;
344  int widthHalf, heightHalf;
346  Image<unsigned char> rgbimg;
347 
349  {
350  OpenDevice();
351  }
352 
353  InitImage(img);
354  SetGain(0.0);
355  while(GrabSingle(img)!=0) {
356  // wait for other grab to complete
357  }
358  ImageConvert::ToRGB(img, rgbimg);
359  widthHalf= img.GetWidth()/2;
360  heightHalf = img.GetHeight()/2;
361 
362  unsigned char mean[3];
363  BIASASSERT(img.GetWidth()>=20 && img.GetHeight()>=20);
364  rgbimg.GetROI()->SetCorners(widthHalf-10, heightHalf-10,
365  widthHalf+10, heightHalf+10);
366  rgbimg.GetMeanPixelValue(mean);
367  int iterations = 0;
368 
369  while(iterations < 32)
370  {
371  BIASCDOUT(D_VS_WHITEB,"In videosource, SoftwarewhiteBalance pixel: "
372  <<(int)mean[0]<<","<<(int)mean[1]<<","<<(int)mean[2]<<endl);
373  if(mean[0] < mean[1])
374  rGain +=1.0/32.0;
375  else if(mean[0] > mean[1])
376  rGain -=1.0/32.0;
377 
378  if(mean[2] < mean[1])
379  bGain +=1.0/32.0;
380  else if(mean[2] > mean[1])
381  bGain -=1.0/32.0;
382  BIASCDOUT(D_VS_WHITEB, "rGain,bGain :"<<rGain<<","<<bGain<<endl);
383  SetWhiteBalance(rGain,bGain);
384  GrabSingle(img);
385  ImageConvert::ToRGB(img, rgbimg);
386  rgbimg.SetROI(widthHalf-10, heightHalf-10, widthHalf+10, heightHalf+10);
387  rgbimg.GetMeanPixelValue(mean);
388  iterations++;
389  }
390  return 0;
391 }
392 
393 
394 int VideoSource::SetDirectToDisk(const std::string &filename)
395 {
396  // open file
397 #ifndef WIN32
398 # ifdef __APPLE__
399  DtDFd_ = open(filename.c_str(),O_WRONLY | O_CREAT , 0644);
400 # else // __APPLE__
401  DtDFd_ = open(filename.c_str(),O_WRONLY | O_CREAT | O_DIRECT, 0644);
402 # endif // __APPLE__
403  //DtDFd_ = basic_filebuf::open(filename.c_str(),O_WRONLY | O_CREAT );
404 
405  if (DtDFd_ <0) {
406  BIASERR("Can not open/create file ");
407  perror(filename.c_str());
408  return -1;
409  }
410 
411  fchmod(DtDFd_,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
412 
414  ImageSize_ = (unsigned int)rint(float(ImageSize_) * BytesPerPixel_);
415  unsigned int required_space = ImageSize_ +sizeof(VideoStream::VSImageHeader);
416  // allocate buffer
417  if (DtDBufferSize_ < required_space) {
418  if (DtDBuffer_ != NULL) free(DtDBuffer_);
419  DtDBufferSize_ = 512;
420  while (DtDBufferSize_ < required_space) DtDBufferSize_ +=512;
421  cout <<"New DtDBuffer_ with size "<<DtDBufferSize_ <<endl;
422  char** bufferPointer = &DtDBuffer_;
423 #ifdef __APPLE__
424  int r=0;
425  *bufferPointer = (char *)valloc(DtDBufferSize_);
426 #else // __APPLE__
427  int r = posix_memalign((void**)bufferPointer, 512, DtDBufferSize_);
428 #endif // __APPLE__
429  if (DtDBuffer_ == NULL || r!=0) {
430  BIASERR("Can not posix_memalign()"<<DtDBufferSize_<<" bytes");
431  return -1;
432  }
433  }
434  BIASDOUT(D_DTD, "Width, height, channelcount, BpP: "<<Width_<<"x"<<Height_
435  <<", "<<ColorChannels_<<", "<<BytesPerPixel_);
436  BIASDOUT(D_DTD, "ImageSize: "<<ImageSize_);
437  BIASDOUT(D_DTD, "HeaderSize: "<<sizeof(VideoStream::VSImageHeader));
438  BIASDOUT(D_DTD, "DtDBufferSize: "<<DtDBufferSize_);
439 
440  // set pointer for header and data
443 
444  // prepare and write header
445  VideoStream::VSHeader *header;
446  cout <<"Size of header: "<<sizeof(VideoStream::VSHeader)<<endl;
447  VideoStream::VSHeader** headerPointer = &header;
448 #ifdef __APPLE__
449  int r=0;
450  *headerPointer = (VideoStream::VSHeader*)valloc(sizeof(VideoStream::VSHeader));
451 #else // __APPLE__
452  int r = posix_memalign((void**)headerPointer, 512, sizeof(VideoStream::VSHeader));
453 #endif // __APPLE__
454  if (r!=0){
455  BIASERR("error in poisx_memalign: "<<r);
456  perror("posix_memalign");
457  return -1;
458  }
459  header->Width = Width_;
460  header->Height = Height_;
461  header->ChannelCount = ColorChannels_;
462  header->ColorModel = ColorMode_;
463  header->BytesPerPixel = (int)BytesPerPixel_; // this is wrong for DV
464  if (BytesPerPixel_ == 2.0)
465  header->StorageType=ImageBase::ST_unsignedshortint;
466  else header->StorageType = ImageBase::ST_unsignedchar;
467  header->AlignedSize = DtDBufferSize_;
468 
469  int res = write(DtDFd_, header, sizeof(VideoStream::VSHeader));
470  if (res <0) {
471  BIASERR("Can not write to file with O_DIRECT: ");
472  perror(filename.c_str());
473  return -1;
474  }
475 
476 
477 #else
478  BIASERR("SetDirectToDisk() not implemented for WIN32");
479 #endif
480  DirectToDisk_ = true;
481  return 0;
482 }
483 
484 int VideoSource::WriteDirect_(const unsigned char *data, const BIAS::UUID &uuid,
485  const long int &sec, const long int &usec)
486 {
487 #ifndef WIN32
488  string uidstr;
489  uuid.GetString(uidstr);
490  DtDImageHeader_->tsec = sec;
491  DtDImageHeader_->tusec = usec;
492  memcpy(DtDImageHeader_->uuid, uidstr.c_str(), uidstr.length());
493  memcpy(DtDStartOfImage_, data, ImageSize_);
494 
495  unsigned int chunksize = 20 * 1024;
496  unsigned int numchunks = DtDBufferSize_ / chunksize;
497  unsigned int lastchunksize = DtDBufferSize_ % chunksize;
498  if (lastchunksize>0) numchunks++;
499 
500  cout <<"Chunk size: "<<chunksize<<endl;
501  cout <<"Num chunks: "<<numchunks<<endl;
502  cout <<"Last chunk: "<<lastchunksize<<endl;
503 
504  unsigned int currentchunksize;
505  for (unsigned int c=0; c<numchunks; c++) {
506  currentchunksize = c==(numchunks-1) ? lastchunksize :chunksize ;
507  int res = write(DtDFd_, DtDBuffer_, currentchunksize);
508  if (res <0) {
509  BIASERR("Can not write to file with O_DIRECT: ");
510  return -1;
511  }
512  }
513 #else
514  BIASERR("WriteDirect() not implemented for WIN32");
515 #endif
516  return 0;
517 }
EColorModel
These are the most often used color models.
Definition: ImageBase.hh:127
YUYV422, 2 channels, full luminance Y, subsampled half U,V.
Definition: ImageBase.hh:133
virtual void SetSize(int w, int h, int bytesperpixel=1)
Set image size and number of bytes per pixel (e.g.
Bayer_GRBG, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:145
virtual int SoftwareWhiteBalance()
Set white balance to optimal value in software.
virtual int InitImage(BIAS::ImageBase &Image)
void GetString(std::string &sUUID) const
writes the UUID into a string object
Definition: UUID.cpp:366
(16bit) unsigned integer image storage type
Definition: ImageBase.hh:114
char * DtDBuffer_
512 byte aligned buffer, contains VSImageHeader and image data
BIAS::VideoStream::VSImageHeader * DtDImageHeader_
Pointer to the beginning of DtDBuffer_.
gray values, 1 channel
Definition: ImageBase.hh:130
int SetCorners(unsigned UpperLeftX, unsigned UpperLeftY, unsigned LowerRightX, unsigned LowerRightY)
Sets a rectangular region of interest.
Definition: ROI.cpp:287
bool IsControllable_
Must be initialized be the derived classes.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
char * DtDStartOfImage_
Pointer into DtDBuffer after VSImageHeader.
const char * DefaultDevice_
Device name.
void SetColorModel(EColorModel Model)
Definition: ImageBase.hh:561
virtual int GetWhiteBalance(float &rvalue, float &bvalue)
Get white balance as values in interval [0, 100]. */.
int WriteDirect_(const unsigned char *data, const BIAS::UUID &uuid, const long int &sec, const long int &usec)
Bayer_RGGB, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:143
BIAS::ImageBase::EColorModel ColorMode_
Color mode used by camera.
int DeviceChannel_
Device channel.
bool WaitForNew_
Wait for new frames in GrabSingle()
float BytesPerPixel_
BytesPerPixel cannot be int (e.g. it is 1.5 for YUV420p)
virtual float GetShutter()
Get shutter (exposure time) in seconds.
virtual int SetWhiteBalance(float rvalue, float bvalue)
Set white balance as values in interval [0, 100]. */.
unsigned int GetWidth() const
Definition: ImageBase.hh:312
virtual int SetGain(float g)
Set gain in dB.
YUV420P, 2 channels, full luminance Y, 1 U, 1 V. Y, U and V are grouped together for better compressi...
Definition: ImageBase.hh:135
Todo: Conflict with YUVU model, what does it do?
Definition: ImageBase.hh:154
bool CompleteInitialized_
Complete_initialized_ is set when OpenDevice(), UseChannel() etc. are done.
void GetMeanPixelValue(StorageType mean[])
calculates mean of pixel
Definition: Image.cpp:623
invalid not set image storage type
Definition: ImageBase.hh:111
int Width_
Image format.
color values, 3 channels, order: blue,green,red
Definition: ImageBase.hh:132
Bayer_BGGR, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:146
virtual int SetColorModel(BIAS::ImageBase::EColorModel mode)
Select colormodel to use.
Bayer_GBRG, 1 channel RGB image Bayer tile.
Definition: ImageBase.hh:144
std::string Identifier_
Verbose camera descriptor.
ROI * GetROI()
Returns a pointer to the roi object.
Definition: ImageBase.hh:615
bool Grabbing_
Grabbing flag is set and unset in GrabSingle() methods.
virtual float GetGain()
Get gain in dB.
virtual int OpenDevice()
selects the first available device to open (e.g.
virtual int AutoMode(int a, bool b)
Use this to enable/disable any automatic modes addressed via enumerations.
virtual int SetShutter(float exptime)
Set shutter (exposure time) in seconds.
virtual unsigned int GetFeature(int feature)
This function is used to query features like shutter, zoom, etc.
float FramesPerSecond_
Capturing framerate.
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
int SetDirectToDisk(const std::string &filename)
Enables the very fast direct-to-disk mode.
unsigned int GetHeight() const
Definition: ImageBase.hh:319
double minContrast_
Feature ranges.
virtual int PreGrab()
Do last preparations before grabbing (e.g. start ISO transfer)
UYVY422, 2 channels, full luminance Y, subsampled half U,V inverse order.
Definition: ImageBase.hh:134
The image template class for specific storage types.
Definition: Image.hh:78
bool DirectToDisk_
Write directly to disk.
bool bExternalTrigger_
External trigger flag.
unsigned int DtDBufferSize_
Buffer size must be multiple of 512.
int SetROI(unsigned int UpperLeftX, unsigned int UpperLeftY, unsigned int LowerRightX, unsigned int LowerRightY)
deprecated, use SetROICorners()
Definition: ImageBase.cpp:1033
bool Active_
Active flag is set in PreGrab() und unset in PostGrab()
virtual int SetFeature(int feature, unsigned int value)
This function is used to control features like shutter, zoom, etc.
RGBA, 4 channels, order: red,green,blue,alpha.
Definition: ImageBase.hh:141
virtual int GetAllDevices(std::vector< std::string > &devices)
virtual int GrabSingle(BIAS::Camera< unsigned char > &image)
virtual int PostGrab()
Stop anything started in PreGrab()
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
Definition: ImageBase.cpp:229
virtual int CloseDevice()
unsigned int ImageSize_
Image size, useful for allocating and copying memory.
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
(8bit) unsigned char image storage type
Definition: ImageBase.hh:112
Checks for VideoSource capabilities.
int DtDFd_
File descriptor for direct-to-disk mode.
interface class for producing/storing Universally Unique IDentifiers
Definition: UUID.hh:98
virtual int OnePushAuto(int feature)
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
static int ToRGB(const Image< StorageType > &source, Image< StorageType > &dest)
Create a RGB converted copy of source image in this.
virtual int GetCapabilities(VideoSourceCapabilities &caps)
Use this method to learn something about the capabilities of the source (only useful for V4L sources...
BGRA color values, 4 channels, order: blue,green,red,alpha.
Definition: ImageBase.hh:150