1 ////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //
41
42 //
43 // The code has been contributed by Justin G. Eskesen on 2010 Jan
44 //
45
46 #include "precomp.hpp"
47
48 #ifdef HAVE_PVAPI
49 #if !defined WIN32 && !defined _WIN32 && !defined _LINUX
50 #define _LINUX
51 #endif
52
53 #if defined(_x64) || defined (__x86_64) || defined (_M_X64)
54 #define _x64 1
55 #elif defined(_x86) || defined(__i386) || defined (_M_IX86)
56 #define _x86 1
57 #endif
58
59 #include <PvApi.h>
60 #ifdef WIN32
61 # include <io.h>
62 #else
63 # include <time.h>
64 # include <unistd.h>
65 #endif
66
67 //#include <arpa/inet.h>
68
69 #define MAX_CAMERAS 10
70
71 /********************* Capturing video from camera via PvAPI *********************/
72
73 class CvCaptureCAM_PvAPI : public CvCapture
74 {
75 public:
76 CvCaptureCAM_PvAPI();
~CvCaptureCAM_PvAPI()77 virtual ~CvCaptureCAM_PvAPI()
78 {
79 close();
80 }
81
82 virtual bool open( int index );
83 virtual void close();
84 virtual double getProperty(int) const;
85 virtual bool setProperty(int, double);
86 virtual bool grabFrame();
87 virtual IplImage* retrieveFrame(int);
getCaptureDomain()88 virtual int getCaptureDomain()
89 {
90 return CV_CAP_PVAPI;
91 }
92
93 protected:
94 #ifndef WIN32
95 virtual void Sleep(unsigned int time);
96 #endif
97
98 void stopCapture();
99 bool startCapture();
100 bool resizeCaptureFrame (int frameWidth, int frameHeight);
101
102 typedef struct
103 {
104 unsigned long UID;
105 tPvHandle Handle;
106 tPvFrame Frame;
107 } tCamera;
108
109 IplImage *frame;
110 tCamera Camera;
111 tPvErr Errcode;
112 };
113
114
CvCaptureCAM_PvAPI()115 CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI()
116 {
117 frame = NULL;
118 memset(&this->Camera, 0, sizeof(this->Camera));
119 }
120
121 #ifndef WIN32
Sleep(unsigned int time)122 void CvCaptureCAM_PvAPI::Sleep(unsigned int time)
123 {
124 struct timespec t,r;
125
126 t.tv_sec = time / 1000;
127 t.tv_nsec = (time % 1000) * 1000000;
128
129 while(nanosleep(&t,&r)==-1)
130 t = r;
131 }
132 #endif
133
close()134 void CvCaptureCAM_PvAPI::close()
135 {
136 // Stop the acquisition & free the camera
137 stopCapture();
138 PvCameraClose(Camera.Handle);
139 PvUnInitialize();
140 }
141
142 // Initialize camera input
open(int index)143 bool CvCaptureCAM_PvAPI::open( int index )
144 {
145 tPvCameraInfo cameraList[MAX_CAMERAS];
146
147 tPvCameraInfo camInfo;
148 tPvIpSettings ipSettings;
149
150
151 if (PvInitialize()) {
152 }
153 //return false;
154
155 Sleep(1000);
156
157 //close();
158
159 int numCameras=PvCameraList(cameraList, MAX_CAMERAS, NULL);
160
161 if (numCameras <= 0 || index >= numCameras)
162 return false;
163
164 Camera.UID = cameraList[index].UniqueId;
165
166 if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings))
167 {
168 /*
169 struct in_addr addr;
170 addr.s_addr = ipSettings.CurrentIpAddress;
171 printf("Current address:\t%s\n",inet_ntoa(addr));
172 addr.s_addr = ipSettings.CurrentIpSubnet;
173 printf("Current subnet:\t\t%s\n",inet_ntoa(addr));
174 addr.s_addr = ipSettings.CurrentIpGateway;
175 printf("Current gateway:\t%s\n",inet_ntoa(addr));
176 */
177 }
178 else
179 {
180 fprintf(stderr,"ERROR: could not retrieve camera IP settings.\n");
181 return false;
182 }
183
184
185 if (PvCameraOpen(Camera.UID, ePvAccessMaster, &(Camera.Handle))==ePvErrSuccess)
186 {
187 tPvUint32 frameWidth, frameHeight;
188 unsigned long maxSize;
189
190 PvAttrUint32Get(Camera.Handle, "Width", &frameWidth);
191 PvAttrUint32Get(Camera.Handle, "Height", &frameHeight);
192
193 // Determine the maximum packet size supported by the system (ethernet adapter)
194 // and then configure the camera to use this value. If the system's NIC only supports
195 // an MTU of 1500 or lower, this will automatically configure an MTU of 1500.
196 // 8228 is the optimal size described by the API in order to enable jumbo frames
197
198 maxSize = 8228;
199 //PvAttrUint32Get(Camera.Handle,"PacketSize",&maxSize);
200 if (PvCaptureAdjustPacketSize(Camera.Handle,maxSize)!=ePvErrSuccess)
201 return false;
202
203 resizeCaptureFrame(frameWidth, frameHeight);
204
205 return startCapture();
206
207 }
208 fprintf(stderr,"Error cannot open camera\n");
209 return false;
210
211 }
212
grabFrame()213 bool CvCaptureCAM_PvAPI::grabFrame()
214 {
215 //if(Camera.Frame.Status != ePvErrUnplugged && Camera.Frame.Status != ePvErrCancelled)
216 return PvCaptureQueueFrame(Camera.Handle, &(Camera.Frame), NULL) == ePvErrSuccess;
217 }
218
219
retrieveFrame(int)220 IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int)
221 {
222 if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess)
223 {
224 return frame;
225 }
226 else return NULL;
227 }
228
getProperty(int property_id) const229 double CvCaptureCAM_PvAPI::getProperty( int property_id ) const
230 {
231 tPvUint32 nTemp;
232
233 switch ( property_id )
234 {
235 case CV_CAP_PROP_FRAME_WIDTH:
236 PvAttrUint32Get(Camera.Handle, "Width", &nTemp);
237 return (double)nTemp;
238 case CV_CAP_PROP_FRAME_HEIGHT:
239 PvAttrUint32Get(Camera.Handle, "Height", &nTemp);
240 return (double)nTemp;
241 case CV_CAP_PROP_EXPOSURE:
242 PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp);
243 return (double)nTemp;
244 case CV_CAP_PROP_FPS:
245 tPvFloat32 nfTemp;
246 PvAttrFloat32Get(Camera.Handle, "StatFrameRate", &nfTemp);
247 return (double)nfTemp;
248 case CV_CAP_PROP_PVAPI_MULTICASTIP:
249 char mEnable[2];
250 char mIp[11];
251 PvAttrEnumGet(Camera.Handle,"MulticastEnable",mEnable,sizeof(mEnable),NULL);
252 if (strcmp(mEnable, "Off") == 0)
253 {
254 return -1;
255 }
256 else
257 {
258 long int ip;
259 int a,b,c,d;
260 PvAttrStringGet(Camera.Handle, "MulticastIPAddress",mIp,sizeof(mIp),NULL);
261 sscanf(mIp, "%d.%d.%d.%d", &a, &b, &c, &d); ip = ((a*256 + b)*256 + c)*256 + d;
262 return (double)ip;
263 }
264 case CV_CAP_PROP_GAIN:
265 PvAttrUint32Get(Camera.Handle, "GainValue", &nTemp);
266 return (double)nTemp;
267 case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE:
268 char triggerMode[256];
269 PvAttrEnumGet(Camera.Handle, "FrameStartTriggerMode", triggerMode, 256, NULL);
270 if (strcmp(triggerMode, "Freerun")==0)
271 return 0.0;
272 else if (strcmp(triggerMode, "SyncIn1")==0)
273 return 1.0;
274 else if (strcmp(triggerMode, "SyncIn2")==0)
275 return 2.0;
276 else if (strcmp(triggerMode, "FixedRate")==0)
277 return 3.0;
278 else if (strcmp(triggerMode, "Software")==0)
279 return 4.0;
280 else
281 return -1.0;
282 case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL:
283 PvAttrUint32Get(Camera.Handle, "DecimationHorizontal", &nTemp);
284 return (double)nTemp;
285 case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL:
286 PvAttrUint32Get(Camera.Handle, "DecimationVertical", &nTemp);
287 return (double)nTemp;
288 case CV_CAP_PROP_PVAPI_BINNINGX:
289 PvAttrUint32Get(Camera.Handle,"BinningX",&nTemp);
290 return (double)nTemp;
291 case CV_CAP_PROP_PVAPI_BINNINGY:
292 PvAttrUint32Get(Camera.Handle,"BinningY",&nTemp);
293 return (double)nTemp;
294 case CV_CAP_PROP_PVAPI_PIXELFORMAT:
295 char pixelFormat[256];
296 PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
297 if (strcmp(pixelFormat, "Mono8")==0)
298 return 1.0;
299 else if (strcmp(pixelFormat, "Mono16")==0)
300 return 2.0;
301 else if (strcmp(pixelFormat, "Bayer8")==0)
302 return 3.0;
303 else if (strcmp(pixelFormat, "Bayer16")==0)
304 return 4.0;
305 else if (strcmp(pixelFormat, "Rgb24")==0)
306 return 5.0;
307 else if (strcmp(pixelFormat, "Bgr24")==0)
308 return 6.0;
309 else if (strcmp(pixelFormat, "Rgba32")==0)
310 return 7.0;
311 else if (strcmp(pixelFormat, "Bgra32")==0)
312 return 8.0;
313 }
314 return -1.0;
315 }
316
setProperty(int property_id,double value)317 bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
318 {
319 tPvErr error;
320
321 switch ( property_id )
322 {
323 case CV_CAP_PROP_FRAME_WIDTH:
324 {
325 tPvUint32 currHeight;
326
327 PvAttrUint32Get(Camera.Handle, "Height", &currHeight);
328
329 stopCapture();
330 // Reallocate Frames
331 if (!resizeCaptureFrame(value, currHeight))
332 {
333 startCapture();
334 return false;
335 }
336
337 startCapture();
338
339 break;
340 }
341 case CV_CAP_PROP_FRAME_HEIGHT:
342 {
343 tPvUint32 currWidth;
344
345 PvAttrUint32Get(Camera.Handle, "Width", &currWidth);
346
347 stopCapture();
348
349 // Reallocate Frames
350 if (!resizeCaptureFrame(currWidth, value))
351 {
352 startCapture();
353 return false;
354 }
355
356 startCapture();
357
358 break;
359 }
360 case CV_CAP_PROP_EXPOSURE:
361 if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess))
362 break;
363 else
364 return false;
365 case CV_CAP_PROP_PVAPI_MULTICASTIP:
366 if (value==-1)
367 {
368 if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "Off")==ePvErrSuccess))
369 break;
370 else
371 return false;
372 }
373 else
374 {
375 cv::String ip=cv::format("%d.%d.%d.%d", ((unsigned int)value>>24)&255, ((unsigned int)value>>16)&255, ((unsigned int)value>>8)&255, (unsigned int)value&255);
376 if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "On")==ePvErrSuccess) &&
377 (PvAttrStringSet(Camera.Handle, "MulticastIPAddress", ip.c_str())==ePvErrSuccess))
378 break;
379 else
380 return false;
381 }
382 case CV_CAP_PROP_GAIN:
383 if (PvAttrUint32Set(Camera.Handle,"GainValue",(tPvUint32)value)!=ePvErrSuccess)
384 {
385 return false;
386 }
387 break;
388 case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE:
389 if (value==0)
390 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun");
391 else if (value==1)
392 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "SyncIn1");
393 else if (value==2)
394 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "SyncIn2");
395 else if (value==3)
396 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "FixedRate");
397 else if (value==4)
398 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Software");
399 else
400 error = ePvErrOutOfRange;
401 if(error==ePvErrSuccess)
402 break;
403 else
404 return false;
405 case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL:
406 if (value >= 1 && value <= 8)
407 error = PvAttrUint32Set(Camera.Handle, "DecimationHorizontal", value);
408 else
409 error = ePvErrOutOfRange;
410 if(error==ePvErrSuccess)
411 break;
412 else
413 return false;
414 case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL:
415 if (value >= 1 && value <= 8)
416 error = PvAttrUint32Set(Camera.Handle, "DecimationVertical", value);
417 else
418 error = ePvErrOutOfRange;
419 if(error==ePvErrSuccess)
420 break;
421 else
422 return false;
423 case CV_CAP_PROP_PVAPI_BINNINGX:
424 error = PvAttrUint32Set(Camera.Handle, "BinningX", value);
425 if(error==ePvErrSuccess)
426 break;
427 else
428 return false;
429 case CV_CAP_PROP_PVAPI_BINNINGY:
430 error = PvAttrUint32Set(Camera.Handle, "BinningY", value);
431 if(error==ePvErrSuccess)
432 break;
433 else
434 return false;
435 case CV_CAP_PROP_PVAPI_PIXELFORMAT:
436 {
437 cv::String pixelFormat;
438
439 if (value==1)
440 pixelFormat = "Mono8";
441 else if (value==2)
442 pixelFormat = "Mono16";
443 else if (value==3)
444 pixelFormat = "Bayer8";
445 else if (value==4)
446 pixelFormat = "Bayer16";
447 else if (value==5)
448 pixelFormat = "Rgb24";
449 else if (value==6)
450 pixelFormat = "Bgr24";
451 else if (value==7)
452 pixelFormat = "Rgba32";
453 else if (value==8)
454 pixelFormat = "Bgra32";
455 else
456 return false;
457
458 if ((PvAttrEnumSet(Camera.Handle,"PixelFormat", pixelFormat.c_str())==ePvErrSuccess))
459 {
460 tPvUint32 currWidth;
461 tPvUint32 currHeight;
462
463 PvAttrUint32Get(Camera.Handle, "Width", &currWidth);
464 PvAttrUint32Get(Camera.Handle, "Height", &currHeight);
465
466 stopCapture();
467 // Reallocate Frames
468 if (!resizeCaptureFrame(currWidth, currHeight))
469 {
470 startCapture();
471 return false;
472 }
473
474 startCapture();
475 return true;
476 }
477 else
478 return false;
479 }
480 default:
481 return false;
482 }
483 return true;
484 }
485
stopCapture()486 void CvCaptureCAM_PvAPI::stopCapture()
487 {
488 PvCommandRun(Camera.Handle, "AcquisitionStop");
489 PvCaptureEnd(Camera.Handle);
490 }
491
startCapture()492 bool CvCaptureCAM_PvAPI::startCapture()
493 {
494 // Start the camera
495 PvCaptureStart(Camera.Handle);
496
497 // Set the camera to capture continuously
498 if(PvAttrEnumSet(Camera.Handle, "AcquisitionMode", "Continuous")!= ePvErrSuccess)
499 {
500 fprintf(stderr,"Could not set PvAPI Acquisition Mode\n");
501 return false;
502 }
503
504 if(PvCommandRun(Camera.Handle, "AcquisitionStart")!= ePvErrSuccess)
505 {
506 fprintf(stderr,"Could not start PvAPI acquisition\n");
507 return false;
508 }
509
510 if(PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun")!= ePvErrSuccess)
511 {
512 fprintf(stderr,"Error setting PvAPI trigger to \"Freerun\"");
513 return false;
514 }
515
516 return true;
517 }
518
resizeCaptureFrame(int frameWidth,int frameHeight)519 bool CvCaptureCAM_PvAPI::resizeCaptureFrame (int frameWidth, int frameHeight)
520 {
521 char pixelFormat[256];
522 tPvUint32 frameSize;
523 tPvUint32 sensorHeight;
524 tPvUint32 sensorWidth;
525
526 if (frame)
527 {
528 cvReleaseImage(&frame);
529 frame = NULL;
530 }
531
532 if (PvAttrUint32Get(Camera.Handle, "SensorWidth", &sensorWidth) != ePvErrSuccess)
533 {
534 return false;
535 }
536
537 if (PvAttrUint32Get(Camera.Handle, "SensorHeight", &sensorHeight) != ePvErrSuccess)
538 {
539 return false;
540 }
541
542 // Cap out of bounds widths to the max supported by the sensor
543 if ((frameWidth < 0) || ((tPvUint32)frameWidth > sensorWidth))
544 {
545 frameWidth = sensorWidth;
546 }
547
548 if ((frameHeight < 0) || ((tPvUint32)frameHeight > sensorHeight))
549 {
550 frameHeight = sensorHeight;
551 }
552
553
554 if (PvAttrUint32Set(Camera.Handle, "Height", frameHeight) != ePvErrSuccess)
555 {
556 return false;
557 }
558
559 if (PvAttrUint32Set(Camera.Handle, "Width", frameWidth) != ePvErrSuccess)
560 {
561 return false;
562 }
563
564 PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
565 PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize);
566
567
568 if ( (strcmp(pixelFormat, "Mono8")==0) || (strcmp(pixelFormat, "Bayer8")==0) )
569 {
570 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 1);
571 frame->widthStep = (int)frameWidth;
572 Camera.Frame.ImageBufferSize = frameSize;
573 Camera.Frame.ImageBuffer = frame->imageData;
574 }
575 else if ( (strcmp(pixelFormat, "Mono16")==0) || (strcmp(pixelFormat, "Bayer16")==0) )
576 {
577 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 1);
578 frame->widthStep = (int)frameWidth*2;
579 Camera.Frame.ImageBufferSize = frameSize;
580 Camera.Frame.ImageBuffer = frame->imageData;
581 }
582 else if ( (strcmp(pixelFormat, "Rgb24")==0) || (strcmp(pixelFormat, "Bgr24")==0) )
583 {
584 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3);
585 frame->widthStep = (int)frameWidth*3;
586 Camera.Frame.ImageBufferSize = frameSize;
587 Camera.Frame.ImageBuffer = frame->imageData;
588 }
589 else if ( (strcmp(pixelFormat, "Rgba32")==0) || (strcmp(pixelFormat, "Bgra32")==0) )
590 {
591 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 4);
592 frame->widthStep = (int)frameWidth*4;
593 Camera.Frame.ImageBufferSize = frameSize;
594 Camera.Frame.ImageBuffer = frame->imageData;
595 }
596 else
597 return false;
598
599 return true;
600 }
601
cvCreateCameraCapture_PvAPI(int index)602 CvCapture* cvCreateCameraCapture_PvAPI( int index )
603 {
604 CvCaptureCAM_PvAPI* capture = new CvCaptureCAM_PvAPI;
605
606 if ( capture->open( index ))
607 return capture;
608
609 delete capture;
610 return NULL;
611 }
612 #endif
613