C-API cleanup: backport videoio changes from 5.x

This commit is contained in:
Maksim Shabunin 2024-10-01 17:05:05 +03:00
parent 658336b366
commit 305b57e622
26 changed files with 1441 additions and 1969 deletions

View File

@ -928,6 +928,17 @@ typedef hfloat float16_t;
}
#endif
/** @brief Constructs the 'fourcc' code, used in video codecs and many other places.
Simply call it with 4 chars like `CV_FOURCC('I', 'Y', 'U', 'V')`
*/
CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4)
{
return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
}
//! Macro to construct the fourcc code of the codec. Same as CV_FOURCC()
#define CV_FOURCC_MACRO(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24))
//! @}
#ifndef __cplusplus

View File

@ -43,7 +43,7 @@
#define OPENCV_DNN_DNN_SHAPE_UTILS_HPP
#include <opencv2/dnn/dnn.hpp>
#include <opencv2/core/types_c.h> // CV_MAX_DIM
#include <opencv2/core/cvdef.h> // CV_MAX_DIM
#include <iostream>
#include <ostream>
#include <sstream>

View File

@ -9,9 +9,11 @@
# error this is a private header which should not be used from outside of the OpenCV library
#endif
#include "opencv2/core/cvdef.h"
#include "opencv2/videoio/videoio_c.h"
#include "opencv2/core/types.hpp"
#include <deque>
#include <vector>
#include <string>
#include <memory>
namespace cv
{
@ -80,8 +82,8 @@ class CV_EXPORTS AVIReadContainer
public:
AVIReadContainer();
void initStream(const String& filename);
void initStream(Ptr<VideoInputStream> m_file_stream_);
void initStream(const std::string& filename);
void initStream(std::shared_ptr<VideoInputStream> m_file_stream_);
void close();
//stores founded frames in m_frame_list which can be accessed via getFrames
@ -121,7 +123,7 @@ protected:
void printError(RiffChunk& chunk, unsigned int expected_fourcc);
Ptr<VideoInputStream> m_file_stream;
std::shared_ptr<VideoInputStream> m_file_stream;
unsigned int m_stream_id;
unsigned long long int m_movi_start;
unsigned long long int m_movi_end;
@ -150,7 +152,7 @@ public:
AVIWriteContainer();
~AVIWriteContainer();
bool initContainer(const String& filename, double fps, Size size, bool iscolor);
bool initContainer(const std::string& filename, double fps, cv::Size size, bool iscolor);
void startWriteAVI(int stream_count);
void writeStreamHeader(Codecs codec_);
void startWriteChunk(uint32_t fourcc);
@ -180,7 +182,7 @@ public:
void jflushStream(unsigned currval, int bitIdx);
private:
Ptr<BitStream> strm;
std::shared_ptr<BitStream> strm;
int outfps;
int width, height, channels;
size_t moviPointer;

View File

@ -5,6 +5,8 @@
#ifndef OPENCV_VIDEOIO_LEGACY_CONSTANTS_H
#define OPENCV_VIDEOIO_LEGACY_CONSTANTS_H
#include "opencv2/core/cvdef.h"
enum
{
CV_CAP_ANY =0, // autodetect
@ -410,22 +412,6 @@ enum
CV_CAP_PROP_VIEWFINDER = 17010 // Enter liveview mode.
};
//! Macro to construct the fourcc code of the codec. Same as CV_FOURCC()
#define CV_FOURCC_MACRO(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24))
/** @brief Constructs the fourcc code of the codec function
Simply call it with 4 chars fourcc code like `CV_FOURCC('I', 'Y', 'U', 'V')`
List of codes can be obtained at [Video Codecs by FOURCC](https://fourcc.org/codecs.php) page.
FFMPEG backend with MP4 container natively uses other values as fourcc code:
see [ObjectType](http://mp4ra.org/#/codecs).
*/
CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4)
{
return CV_FOURCC_MACRO(c1, c2, c3, c4);
}
//! (Windows only) Open Codec Selection Dialog
#define CV_FOURCC_PROMPT -1
//! (Linux only) Use default codec for specified filename

View File

@ -403,17 +403,17 @@ public:
double getProperty(int property_id) const CV_OVERRIDE
{
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return isOpened() ? frameWidth : desiredWidth;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return isOpened() ? frameHeight : desiredHeight;
case CAP_PROP_AUTO_EXPOSURE:
return autoExposure ? 1 : 0;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
return exposureTime;
case CV_CAP_PROP_ISO_SPEED:
case CAP_PROP_ISO_SPEED:
return sensitivity;
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
return fourCC;
default:
break;
@ -425,7 +425,7 @@ public:
bool setProperty(int property_id, double value) CV_OVERRIDE
{
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
desiredWidth = value;
settingWidth = true;
if (settingWidth && settingHeight) {
@ -434,7 +434,7 @@ public:
settingHeight = false;
}
return true;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
desiredHeight = value;
settingHeight = true;
if (settingWidth && settingHeight) {
@ -443,7 +443,7 @@ public:
settingHeight = false;
}
return true;
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
{
uint32_t newFourCC = cvRound(value);
if (fourCC == newFourCC) {
@ -485,18 +485,18 @@ public:
return status == ACAMERA_OK;
}
return true;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
if (isOpened() && exposureRange.Supported()) {
exposureTime = (int64_t)value;
LOGI("Setting CV_CAP_PROP_EXPOSURE will have no effect unless CAP_PROP_AUTO_EXPOSURE is off");
LOGI("Setting CAP_PROP_EXPOSURE will have no effect unless CAP_PROP_AUTO_EXPOSURE is off");
camera_status_t status = ACaptureRequest_setEntry_i64(captureRequest.get(), ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime);
return status == ACAMERA_OK;
}
return false;
case CV_CAP_PROP_ISO_SPEED:
case CAP_PROP_ISO_SPEED:
if (isOpened() && sensitivityRange.Supported()) {
sensitivity = (int32_t)value;
LOGI("Setting CV_CAP_PROP_ISO_SPEED will have no effect unless CAP_PROP_AUTO_EXPOSURE is off");
LOGI("Setting CAP_PROP_ISO_SPEED will have no effect unless CAP_PROP_AUTO_EXPOSURE is off");
camera_status_t status = ACaptureRequest_setEntry_i32(captureRequest.get(), ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity);
return status == ACAMERA_OK;
}

View File

@ -182,16 +182,16 @@ public:
{
switch (property_id)
{
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return (( videoOrientationAuto &&
(cv::ROTATE_90_CLOCKWISE == videoRotationCode || cv::ROTATE_90_COUNTERCLOCKWISE == videoRotationCode))
? videoHeight : videoWidth);
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return (( videoOrientationAuto &&
(cv::ROTATE_90_CLOCKWISE == videoRotationCode || cv::ROTATE_90_COUNTERCLOCKWISE == videoRotationCode))
? videoWidth : videoHeight);
case CV_CAP_PROP_FPS: return videoFrameRate;
case CV_CAP_PROP_FRAME_COUNT: return videoFrameCount;
case CAP_PROP_FPS: return videoFrameRate;
case CAP_PROP_FRAME_COUNT: return videoFrameCount;
case CAP_PROP_ORIENTATION_META: return videoRotation;
case CAP_PROP_ORIENTATION_AUTO: return videoOrientationAuto ? 1 : 0;
}
@ -661,7 +661,7 @@ const AndroidMediaNdkVideoWriter::FourCCInfo AndroidMediaNdkVideoWriter::FOURCC_
{ CV_FOURCC('H', '2', '6', '5'), "video/hevc", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },
{ CV_FOURCC('H', '2', '6', '3'), "video/3gpp", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },
{ CV_FOURCC('M', 'P', '4', 'V'), "video/mp4v-es", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },
{ 0, NULL },
{ 0, NULL, AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },
};

View File

@ -46,6 +46,8 @@
#include "precomp.hpp"
#include "cap_interface.hpp"
using namespace cv;
#ifdef HAVE_ARAVIS_API
#include <arv.h>
@ -93,25 +95,26 @@
/********************* Capturing video from camera via Aravis *********************/
class CvCaptureCAM_Aravis : public CvCapture
class CvCaptureCAM_Aravis : public IVideoCapture
{
public:
CvCaptureCAM_Aravis();
virtual ~CvCaptureCAM_Aravis()
~CvCaptureCAM_Aravis()
{
close();
}
virtual bool open(int);
virtual void close();
virtual double getProperty(int) const CV_OVERRIDE;
virtual bool setProperty(int, double) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
virtual int getCaptureDomain() CV_OVERRIDE
bool open(int);
void close();
double getProperty(int) const CV_OVERRIDE;
bool setProperty(int, double) CV_OVERRIDE;
bool grabFrame() CV_OVERRIDE;
bool retrieveFrame(int, OutputArray) CV_OVERRIDE;
int getCaptureDomain() CV_OVERRIDE
{
return cv::CAP_ARAVIS;
}
bool isOpened() const CV_OVERRIDE { return stream != NULL; }
protected:
bool create(int);
@ -122,7 +125,7 @@ protected:
bool getDeviceNameById(int id, std::string &device);
void autoExposureControl(IplImage*);
void autoExposureControl(const Mat &);
ArvCamera *camera; // Camera to control.
ArvStream *stream; // Object for video stream reception.
@ -167,8 +170,6 @@ protected:
unsigned frameID; // current frame id
unsigned prevFrameID;
IplImage *frame; // local frame copy
};
@ -190,7 +191,6 @@ CvCaptureCAM_Aravis::CvCaptureCAM_Aravis()
allowAutoTrigger = false;
num_buffers = 10;
frame = NULL;
}
void CvCaptureCAM_Aravis::close()
@ -314,51 +314,37 @@ bool CvCaptureCAM_Aravis::grabFrame()
return false;
}
IplImage* CvCaptureCAM_Aravis::retrieveFrame(int)
bool CvCaptureCAM_Aravis::retrieveFrame(int, OutputArray arr)
{
if(framebuffer) {
int depth = 0, channels = 0;
switch(pixelFormat) {
case ARV_PIXEL_FORMAT_MONO_8:
case ARV_PIXEL_FORMAT_BAYER_GR_8:
depth = IPL_DEPTH_8U;
depth = CV_8U;
channels = 1;
break;
case ARV_PIXEL_FORMAT_MONO_12:
case ARV_PIXEL_FORMAT_MONO_16:
depth = IPL_DEPTH_16U;
depth = CV_16U;
channels = 1;
break;
default:
return false;
}
if(depth && channels) {
IplImage src;
cvInitImageHeader( &src, cvSize( width, height ), depth, channels, IPL_ORIGIN_TL, 4 );
cvSetData( &src, framebuffer, src.widthStep );
if( !frame ||
frame->width != src.width ||
frame->height != src.height ||
frame->depth != src.depth ||
frame->nChannels != src.nChannels) {
cvReleaseImage( &frame );
frame = cvCreateImage( cvGetSize(&src), src.depth, channels );
}
cvCopy(&src, frame);
if(controlExposure && ((frameID - prevFrameID) >= 3)) {
// control exposure every third frame
// i.e. skip frame taken with previous exposure setup
autoExposureControl(frame);
}
return frame;
Mat src(Size( width, height ), CV_MAKE_TYPE(depth, channels), framebuffer);
if(controlExposure && ((frameID - prevFrameID) >= 3)) {
// control exposure every third frame
// i.e. skip frame taken with previous exposure setup
autoExposureControl(src);
}
src.copyTo(arr);
return true;
}
return NULL;
return false;
}
void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
void CvCaptureCAM_Aravis::autoExposureControl(const Mat & image)
{
// Software control of exposure parameters utilizing
// automatic change of exposure time & gain
@ -367,10 +353,8 @@ void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
// - to increase brightness, first increase time then gain
// - to decrease brightness, first decrease gain then time
cv::Mat m = cv::cvarrToMat(image);
// calc mean value for luminance or green channel
double brightness = cv::mean(m)[image->nChannels > 1 ? 1 : 0];
double brightness = cv::mean(image)[image.channels() > 1 ? 1 : 0];
if(brightness < 1) brightness = 1;
// mid point - 100 % means no change
@ -437,41 +421,41 @@ void CvCaptureCAM_Aravis::autoExposureControl(IplImage* image)
double CvCaptureCAM_Aravis::getProperty( int property_id ) const
{
switch(property_id) {
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
return (double)frameID/fps;
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return width;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return height;
case CV_CAP_PROP_AUTO_EXPOSURE:
case CAP_PROP_AUTO_EXPOSURE:
return (controlExposure ? 1 : 0);
case CV_CAP_PROP_BRIGHTNESS:
case CAP_PROP_BRIGHTNESS:
return exposureCompensation;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
if(exposureAvailable) {
/* exposure time in seconds, like 1/100 s */
return arv_camera_get_exposure_time(camera, NULL) / 1e6;
}
break;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
if(fpsAvailable) {
return arv_camera_get_frame_rate(camera, NULL);
}
break;
case CV_CAP_PROP_GAIN:
case CAP_PROP_GAIN:
if(gainAvailable) {
return arv_camera_get_gain(camera, NULL);
}
break;
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
{
ArvPixelFormat currFormat = arv_camera_get_pixel_format(camera, NULL);
switch( currFormat ) {
@ -487,7 +471,7 @@ double CvCaptureCAM_Aravis::getProperty( int property_id ) const
}
break;
case CV_CAP_PROP_BUFFERSIZE:
case CAP_PROP_BUFFERSIZE:
if(stream) {
int in, out;
arv_stream_get_n_buffers(stream, &in, &out);
@ -508,7 +492,7 @@ double CvCaptureCAM_Aravis::getProperty( int property_id ) const
bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
{
switch(property_id) {
case CV_CAP_PROP_AUTO_EXPOSURE:
case CAP_PROP_AUTO_EXPOSURE:
if(exposureAvailable || gainAvailable) {
if( (controlExposure = (bool)(int)value) ) {
exposure = exposureAvailable ? arv_camera_get_exposure_time(camera, NULL) : 0;
@ -516,11 +500,11 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
}
}
break;
case CV_CAP_PROP_BRIGHTNESS:
case CAP_PROP_BRIGHTNESS:
exposureCompensation = CLIP(value, -3., 3.);
break;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
if(exposureAvailable) {
/* exposure time in seconds, like 1/100 s */
value *= 1e6; // -> from s to us
@ -529,13 +513,13 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
break;
} else return false;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
if(fpsAvailable) {
arv_camera_set_frame_rate(camera, fps = CLIP(value, fpsMin, fpsMax), NULL);
break;
} else return false;
case CV_CAP_PROP_GAIN:
case CAP_PROP_GAIN:
if(gainAvailable) {
if ( (autoGain = (-1 == value) ) )
break;
@ -544,7 +528,7 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
break;
} else return false;
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
{
ArvPixelFormat newFormat = pixelFormat;
switch((int)value) {
@ -574,7 +558,7 @@ bool CvCaptureCAM_Aravis::setProperty( int property_id, double value )
}
break;
case CV_CAP_PROP_BUFFERSIZE:
case CAP_PROP_BUFFERSIZE:
{
int x = (int)value;
if((x > 0) && (x != num_buffers)) {
@ -621,13 +605,10 @@ bool CvCaptureCAM_Aravis::startCapture()
cv::Ptr<cv::IVideoCapture> cv::create_Aravis_capture( int index )
{
CvCaptureCAM_Aravis* capture = new CvCaptureCAM_Aravis;
Ptr<CvCaptureCAM_Aravis> capture = makePtr<CvCaptureCAM_Aravis>();
if(capture->open(index)) {
return cv::makePtr<cv::LegacyCapture>(capture);
return capture;
}
delete capture;
return NULL;
}
#endif

View File

@ -45,6 +45,7 @@
#define CV_CAP_MODE_GRAY CV_FOURCC_MACRO('G','R','E','Y')
#define CV_CAP_MODE_YUYV CV_FOURCC_MACRO('Y', 'U', 'Y', 'V')
/********************** Declaration of class headers ************************/
/*****************************************************************************
@ -54,7 +55,7 @@
* CaptureDelegate is notified on a separate thread by the OS whenever there
* is a new frame. When "updateImage" is called from the main thread, it
* copies this new frame into an IplImage, but only if this frame has not
* been copied before. When "getOutput" is called from the main thread,
* been copied before. When "getImage" is called from the main thread,
* it gives the last copied IplImage.
*
*****************************************************************************/
@ -67,11 +68,8 @@
{
int newFrame;
CVImageBufferRef mCurrentImageBuffer;
char* imagedata;
IplImage* image;
char* bgr_imagedata;
IplImage* bgr_image;
IplImage* bgr_image_r90;
cv::Mat bgr_image;
cv::Mat bgr_image_r90;
size_t currSize;
}
@ -80,8 +78,8 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection;
- (int)updateImage;
- (IplImage*)getOutput;
- (bool)updateImage;
- (cv::Mat)getImage;
@end
@ -93,18 +91,17 @@ fromConnection:(AVCaptureConnection *)connection;
*
*****************************************************************************/
class CvCaptureCAM : public CvCapture {
class CvCaptureCAM : public cv::IVideoCapture {
public:
CvCaptureCAM(int cameraNum = -1) ;
~CvCaptureCAM();
bool grabFrame() CV_OVERRIDE;
IplImage* retrieveFrame(int) CV_OVERRIDE;
bool retrieveFrame(int, cv::OutputArray) CV_OVERRIDE;
double getProperty(int property_id) const CV_OVERRIDE;
bool setProperty(int property_id, double value) CV_OVERRIDE;
int getCaptureDomain() /*const*/ CV_OVERRIDE { return cv::CAP_AVFOUNDATION; }
bool isOpened() const CV_OVERRIDE { return started; }
virtual IplImage* queryFrame();
virtual int didStart();
private:
AVCaptureSession *mCaptureSession;
AVCaptureDeviceInput *mCaptureDeviceInput;
@ -137,17 +134,17 @@ class CvCaptureCAM : public CvCapture {
*
*****************************************************************************/
class CvCaptureFile : public CvCapture {
class CvCaptureFile : public cv::IVideoCapture {
public:
CvCaptureFile(const char* filename) ;
~CvCaptureFile();
bool grabFrame() CV_OVERRIDE;
IplImage* retrieveFrame(int) CV_OVERRIDE;
bool retrieveFrame(int, cv::OutputArray) CV_OVERRIDE;
double getProperty(int property_id) const CV_OVERRIDE;
bool setProperty(int property_id, double value) CV_OVERRIDE;
int getCaptureDomain() /*const*/ CV_OVERRIDE { return cv::CAP_AVFOUNDATION; }
bool isOpened() const CV_OVERRIDE { return started; }
virtual int didStart();
private:
AVAsset *mAsset;
AVAssetTrack *mAssetTrack;
@ -156,16 +153,14 @@ private:
CMSampleBufferRef mCurrentSampleBuffer;
CVImageBufferRef mGrabbedPixels;
IplImage *mDeviceImage;
uint8_t *mOutImagedata;
IplImage *mOutImage;
cv::Mat mOutImage;
size_t currSize;
uint32_t mMode;
int mFormat;
void handleTracks(NSArray<AVAssetTrack *>* tracks, const char* filename);
bool setupReadingAt(CMTime position);
IplImage* retrieveFramePixelBuffer();
cv::Mat retrieveFramePixelBuffer();
int getPreferredOrientationDegrees() const;
CMTime mFrameTimestamp;
@ -177,22 +172,23 @@ private:
/*****************************************************************************
*
* CvCaptureFile Declaration.
* CvVideoWriter_AVFoundation Declaration.
*
* CvCaptureFile is the instantiation of a capture source for video files.
* CvVideoWriter_AVFoundation is the instantiation of a video output class.
*
*****************************************************************************/
class CvVideoWriter_AVFoundation : public CvVideoWriter{
class CvVideoWriter_AVFoundation : public cv::IVideoWriter{
public:
CvVideoWriter_AVFoundation(const char* filename, int fourcc,
double fps, CvSize frame_size,
double fps, const cv::Size& frame_size,
int is_color=1);
~CvVideoWriter_AVFoundation();
bool writeFrame(const IplImage* image) CV_OVERRIDE;
bool isOpened() const CV_OVERRIDE { return mMovieWriter != NULL && mMovieWriter.status != AVAssetWriterStatusFailed; }
void write(cv::InputArray image) CV_OVERRIDE;
int getCaptureDomain() const CV_OVERRIDE { return cv::CAP_AVFOUNDATION; }
private:
IplImage* argbimage;
cv::Mat argbimage;
AVAssetWriter *mMovieWriter;
AVAssetWriterInput* mMovieWriterInput;
@ -202,7 +198,7 @@ class CvVideoWriter_AVFoundation : public CvVideoWriter{
NSString* codec;
NSString* fileType;
double movieFPS;
CvSize movieSize;
cv::Size movieSize;
int movieColor;
unsigned long frameCount;
};
@ -213,24 +209,21 @@ class CvVideoWriter_AVFoundation : public CvVideoWriter{
cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_file(const std::string &filename)
{
CvCaptureFile *retval = new CvCaptureFile(filename.c_str());
if(retval->didStart())
return makePtr<LegacyCapture>(retval);
delete retval;
cv::Ptr<CvCaptureFile> retval = cv::makePtr<CvCaptureFile>(filename.c_str());
if(retval->isOpened())
return retval;
return NULL;
}
cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
{
#if !TARGET_OS_VISION
CvCaptureCAM* retval = new CvCaptureCAM(index);
if (retval->didStart())
return cv::makePtr<cv::LegacyCapture>(retval);
delete retval;
cv::Ptr<CvCaptureCAM> retval = cv::makePtr<CvCaptureCAM>(index);
if (retval->isOpened())
return retval;
#endif
return 0;
return NULL;
}
@ -238,10 +231,11 @@ cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& file
double fps, const cv::Size &frameSize,
const cv::VideoWriterParameters& params)
{
CvSize sz = { frameSize.width, frameSize.height };
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
CvVideoWriter_AVFoundation* wrt = new CvVideoWriter_AVFoundation(filename.c_str(), fourcc, fps, sz, isColor);
return cv::makePtr<cv::LegacyWriter>(wrt);
cv::Ptr<CvVideoWriter_AVFoundation> wrt = cv::makePtr<CvVideoWriter_AVFoundation>(filename.c_str(), fourcc, fps, frameSize, isColor);
if (wrt->isOpened())
return wrt;
return NULL;
}
/********************** Implementation of Classes ****************************/
@ -283,11 +277,6 @@ CvCaptureCAM::~CvCaptureCAM() {
//cout << "Cleaned up camera." << endl;
}
int CvCaptureCAM::didStart() {
return started;
}
bool CvCaptureCAM::grabFrame() {
return grabFrame(5);
}
@ -309,20 +298,12 @@ bool CvCaptureCAM::grabFrame(double timeOut) {
return total <= timeOut;
}
IplImage* CvCaptureCAM::retrieveFrame(int) {
return [capture getOutput];
}
IplImage* CvCaptureCAM::queryFrame() {
while (!grabFrame()) {
std::cout << "WARNING: Couldn't grab new frame from camera!!!" << std::endl;
/*
cout << "Attempting to restart camera; set capture property DISABLE_AUTO_RESTART to disable." << endl;
stopCaptureDevice();
startCaptureDevice(camNum);
*/
}
return retrieveFrame(0);
bool CvCaptureCAM::retrieveFrame(int, cv::OutputArray arr) {
cv::Mat img = [capture getImage];
if (img.empty())
return false;
img.copyTo(arr);
return true;
}
void CvCaptureCAM::stopCaptureDevice() {
@ -458,11 +439,11 @@ void CvCaptureCAM::setWidthHeight() {
//added macros into headers in videoio_c.h
/*
#define CV_CAP_PROP_IOS_DEVICE_FOCUS 9001
#define CV_CAP_PROP_IOS_DEVICE_EXPOSURE 9002
#define CV_CAP_PROP_IOS_DEVICE_FLASH 9003
#define CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE 9004
#define CV_CAP_PROP_IOS_DEVICE_TORCH 9005
#define CAP_PROP_IOS_DEVICE_FOCUS 9001
#define CAP_PROP_IOS_DEVICE_EXPOSURE 9002
#define CAP_PROP_IOS_DEVICE_FLASH 9003
#define CAP_PROP_IOS_DEVICE_WHITEBALANCE 9004
#define CAP_PROP_IOS_DEVICE_TORCH 9005
*/
@ -523,20 +504,20 @@ double CvCaptureCAM::getProperty(int property_id) const{
[localpool drain];
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
return w;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
return h;
case CV_CAP_PROP_IOS_DEVICE_FOCUS:
case cv::CAP_PROP_IOS_DEVICE_FOCUS:
return mCaptureDevice.focusMode;
case CV_CAP_PROP_IOS_DEVICE_EXPOSURE:
case cv::CAP_PROP_IOS_DEVICE_EXPOSURE:
return mCaptureDevice.exposureMode;
case CV_CAP_PROP_IOS_DEVICE_FLASH:
case cv::CAP_PROP_IOS_DEVICE_FLASH:
return mCaptureDevice.flashMode;
case CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE:
case cv::CAP_PROP_IOS_DEVICE_WHITEBALANCE:
return mCaptureDevice.whiteBalanceMode;
case CV_CAP_PROP_IOS_DEVICE_TORCH:
case cv::CAP_PROP_IOS_DEVICE_TORCH:
return mCaptureDevice.torchMode;
default:
@ -548,7 +529,7 @@ double CvCaptureCAM::getProperty(int property_id) const{
bool CvCaptureCAM::setProperty(int property_id, double value) {
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
width = value;
settingWidth = 1;
if (settingWidth && settingHeight) {
@ -558,7 +539,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
}
return true;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
height = value;
settingHeight = 1;
if (settingWidth && settingHeight) {
@ -568,7 +549,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
}
return true;
case CV_CAP_PROP_IOS_DEVICE_FOCUS:
case cv::CAP_PROP_IOS_DEVICE_FOCUS:
if ([mCaptureDevice isFocusModeSupported:(AVCaptureFocusMode)value]){
NSError* error = nil;
[mCaptureDevice lockForConfiguration:&error];
@ -581,7 +562,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
return false;
}
case CV_CAP_PROP_IOS_DEVICE_EXPOSURE:
case cv::CAP_PROP_IOS_DEVICE_EXPOSURE:
if ([mCaptureDevice isExposureModeSupported:(AVCaptureExposureMode)value]){
NSError* error = nil;
[mCaptureDevice lockForConfiguration:&error];
@ -594,7 +575,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
return false;
}
case CV_CAP_PROP_IOS_DEVICE_FLASH:
case cv::CAP_PROP_IOS_DEVICE_FLASH:
if ( [mCaptureDevice hasFlash] && [mCaptureDevice isFlashModeSupported:(AVCaptureFlashMode)value]){
NSError* error = nil;
[mCaptureDevice lockForConfiguration:&error];
@ -607,7 +588,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
return false;
}
case CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE:
case cv::CAP_PROP_IOS_DEVICE_WHITEBALANCE:
if ([mCaptureDevice isWhiteBalanceModeSupported:(AVCaptureWhiteBalanceMode)value]){
NSError* error = nil;
[mCaptureDevice lockForConfiguration:&error];
@ -620,7 +601,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
return false;
}
case CV_CAP_PROP_IOS_DEVICE_TORCH:
case cv::CAP_PROP_IOS_DEVICE_TORCH:
if ([mCaptureDevice hasFlash] && [mCaptureDevice isTorchModeSupported:(AVCaptureTorchMode)value]){
NSError* error = nil;
[mCaptureDevice lockForConfiguration:&error];
@ -649,7 +630,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
* CaptureDelegate is notified on a separate thread by the OS whenever there
* is a new frame. When "updateImage" is called from the main thread, it
* copies this new frame into an IplImage, but only if this frame has not
* been copied before. When "getOutput" is called from the main thread,
* been copied before. When "getImage" is called from the main thread,
* it gives the last copied IplImage.
*
*****************************************************************************/
@ -660,22 +641,14 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
- (id)init {
[super init];
newFrame = 0;
imagedata = NULL;
bgr_imagedata = NULL;
currSize = 0;
image = NULL;
bgr_image = NULL;
bgr_image_r90 = NULL;
return self;
}
-(void)dealloc {
if (imagedata != NULL) free(imagedata);
if (bgr_imagedata != NULL) free(bgr_imagedata);
cvReleaseImage(&image);
cvReleaseImage(&bgr_image);
cvReleaseImage(&bgr_image_r90);
bgr_image.release();
bgr_image_r90.release();
[super dealloc];
}
@ -705,13 +678,7 @@ fromConnection:(AVCaptureConnection *)connection{
}
-(IplImage*) getOutput {
//return bgr_image;
return bgr_image_r90;
}
-(int) updateImage {
-(bool) updateImage {
if (newFrame==0) return 0;
CVPixelBufferRef pixels;
@ -721,64 +688,40 @@ fromConnection:(AVCaptureConnection *)connection{
}
CVPixelBufferLockBaseAddress(pixels, 0);
uint32_t* baseaddress = (uint32_t*)CVPixelBufferGetBaseAddress(pixels);
uchar* baseaddress = reinterpret_cast<uchar*>(CVPixelBufferGetBaseAddress(pixels));
size_t width = CVPixelBufferGetWidth(pixels);
size_t height = CVPixelBufferGetHeight(pixels);
cv::Size sz { (int)CVPixelBufferGetWidth(pixels), (int)CVPixelBufferGetHeight(pixels) };
size_t rowBytes = CVPixelBufferGetBytesPerRow(pixels);
OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixels);
if (rowBytes != 0) {
if (currSize != rowBytes*height*sizeof(char)) {
currSize = rowBytes*height*sizeof(char);
if (imagedata != NULL) free(imagedata);
if (bgr_imagedata != NULL) free(bgr_imagedata);
imagedata = (char*)malloc(currSize);
bgr_imagedata = (char*)malloc(currSize);
}
memcpy(imagedata, baseaddress, currSize);
if (image == NULL) {
image = cvCreateImageHeader(cvSize((int)width,(int)height), IPL_DEPTH_8U, 4);
}
image->width = (int)width;
image->height = (int)height;
image->nChannels = 4;
image->depth = IPL_DEPTH_8U;
image->widthStep = (int)rowBytes;
image->imageData = imagedata;
image->imageSize = (int)currSize;
if (bgr_image == NULL) {
bgr_image = cvCreateImageHeader(cvSize((int)width,(int)height), IPL_DEPTH_8U, 3);
}
bgr_image->width = (int)width;
bgr_image->height = (int)height;
bgr_image->nChannels = 3;
bgr_image->depth = IPL_DEPTH_8U;
bgr_image->widthStep = (int)rowBytes;
bgr_image->imageData = bgr_imagedata;
bgr_image->imageSize = (int)currSize;
cv::cvtColor(cv::cvarrToMat(image), cv::cvarrToMat(bgr_image), cv::COLOR_BGRA2BGR);
bool res = false;
if (rowBytes != 0 && pixelFormat == kCVPixelFormatType_32BGRA) {
bgr_image.create(sz, CV_8UC3);
cv::Mat devImage(sz, CV_8UC4, baseaddress, rowBytes);
cv::cvtColor(devImage, bgr_image, cv::COLOR_BGRA2BGR);
// image taken from the buffer is incorrected rotated. I'm using cvTranspose + cvFlip.
// There should be an option in iOS API to rotate the buffer output orientation.
// iOS provides hardware accelerated rotation through AVCaptureConnection class
// I can't get it work.
if (bgr_image_r90 == NULL){
bgr_image_r90 = cvCreateImage(cvSize((int)height, (int)width), IPL_DEPTH_8U, 3);
}
cvTranspose(bgr_image, bgr_image_r90);
cvFlip(bgr_image_r90, NULL, 1);
bgr_image_r90.create(sz, CV_8UC3);
cv::transpose(bgr_image, bgr_image_r90);
cv::flip(bgr_image_r90, bgr_image_r90, 1);
res = true;
} else {
fprintf(stderr, "OpenCV: rowBytes == 0 or unknown pixel format 0x%08X\n", pixelFormat);
bgr_image.create(cv::Size(0, 0), bgr_image.type());
bgr_image_r90.create(cv::Size(0, 0), bgr_image_r90.type());
}
CVPixelBufferUnlockBaseAddress(pixels, 0);
CVBufferRelease(pixels);
return 1;
return res;
}
-(cv::Mat) getImage {
return bgr_image_r90;
}
@end
@ -800,9 +743,6 @@ CvCaptureFile::CvCaptureFile(const char* filename) {
mAssetTrack = nil;
mAssetReader = nil;
mTrackOutput = nil;
mDeviceImage = NULL;
mOutImage = NULL;
mOutImagedata = NULL;
currSize = 0;
mMode = CV_CAP_MODE_BGR;
mFormat = CV_8UC3;
@ -848,9 +788,7 @@ CvCaptureFile::CvCaptureFile(const char* filename) {
CvCaptureFile::~CvCaptureFile() {
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
free(mOutImagedata);
cvReleaseImage(&mOutImage);
cvReleaseImage(&mDeviceImage);
mOutImage.release();
[mAssetReader release];
[mTrackOutput release];
[mAssetTrack release];
@ -938,10 +876,6 @@ bool CvCaptureFile::setupReadingAt(CMTime position) {
return [mAssetReader startReading];
}
int CvCaptureFile::didStart() {
return started;
}
bool CvCaptureFile::grabFrame() {
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
@ -960,28 +894,29 @@ bool CvCaptureFile::grabFrame() {
return isReading;
}
IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
cv::Mat CvCaptureFile::retrieveFramePixelBuffer() {
if ( ! mGrabbedPixels ) {
return 0;
return cv::Mat();
}
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
CVPixelBufferLockBaseAddress(mGrabbedPixels, 0);
void *baseaddress;
size_t width, height, rowBytes;
size_t rowBytes;
cv::Size sz;
OSType pixelFormat = CVPixelBufferGetPixelFormatType(mGrabbedPixels);
if (CVPixelBufferIsPlanar(mGrabbedPixels)) {
baseaddress = CVPixelBufferGetBaseAddressOfPlane(mGrabbedPixels, 0);
width = CVPixelBufferGetWidthOfPlane(mGrabbedPixels, 0);
height = CVPixelBufferGetHeightOfPlane(mGrabbedPixels, 0);
sz.width = CVPixelBufferGetWidthOfPlane(mGrabbedPixels, 0);
sz.height = CVPixelBufferGetHeightOfPlane(mGrabbedPixels, 0);
rowBytes = CVPixelBufferGetBytesPerRowOfPlane(mGrabbedPixels, 0);
} else {
baseaddress = CVPixelBufferGetBaseAddress(mGrabbedPixels);
width = CVPixelBufferGetWidth(mGrabbedPixels);
height = CVPixelBufferGetHeight(mGrabbedPixels);
sz.width = CVPixelBufferGetWidth(mGrabbedPixels);
sz.height = CVPixelBufferGetHeight(mGrabbedPixels);
rowBytes = CVPixelBufferGetBytesPerRow(mGrabbedPixels);
}
@ -990,7 +925,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
return cv::Mat();
}
int outChannels;
@ -1005,26 +940,9 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
return cv::Mat();
}
if ( currSize != width*outChannels*height ) {
currSize = width*outChannels*height;
free(mOutImagedata);
mOutImagedata = reinterpret_cast<uint8_t*>(malloc(currSize));
}
if (mOutImage == NULL) {
mOutImage = cvCreateImageHeader(cvSize((int)width,(int)height), IPL_DEPTH_8U, outChannels);
}
mOutImage->width = int(width);
mOutImage->height = int(height);
mOutImage->nChannels = outChannels;
mOutImage->depth = IPL_DEPTH_8U;
mOutImage->widthStep = int(width*outChannels);
mOutImage->imageData = reinterpret_cast<char *>(mOutImagedata);
mOutImage->imageSize = int(currSize);
int deviceChannels;
int cvtCode;
@ -1042,7 +960,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else if ( pixelFormat == kCVPixelFormatType_24RGB ) {
deviceChannels = 3;
@ -1050,7 +968,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
if (mMode == CV_CAP_MODE_BGR) {
cvtCode = cv::COLOR_RGB2BGR;
} else if (mMode == CV_CAP_MODE_RGB) {
cvtCode = 0;
cvtCode = -1;
} else if (mMode == CV_CAP_MODE_GRAY) {
cvtCode = cv::COLOR_RGB2GRAY;
} else {
@ -1058,7 +976,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else if ( pixelFormat == kCVPixelFormatType_422YpCbCr8 ) { // 422 (2vuy, UYVY)
deviceChannels = 2;
@ -1076,11 +994,11 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else if ( pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange || // 420v
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ) { // 420f
height = height * 3 / 2;
sz.height = sz.height * 3 / 2;
deviceChannels = 1;
if (mMode == CV_CAP_MODE_BGR) {
@ -1094,7 +1012,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else {
char pfBuf[] = { (char)pixelFormat, (char)(pixelFormat >> 8),
@ -1103,24 +1021,15 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
return cv::Mat();
}
if (mDeviceImage == NULL) {
mDeviceImage = cvCreateImageHeader(cvSize(int(width),int(height)), IPL_DEPTH_8U, deviceChannels);
}
mDeviceImage->width = int(width);
mDeviceImage->height = int(height);
mDeviceImage->nChannels = deviceChannels;
mDeviceImage->depth = IPL_DEPTH_8U;
mDeviceImage->widthStep = int(rowBytes);
mDeviceImage->imageData = reinterpret_cast<char *>(baseaddress);
mDeviceImage->imageSize = int(rowBytes*height);
mOutImage.create(sz, CV_MAKE_TYPE(CV_8U, outChannels));
cv::Mat devImage(sz, CV_MAKE_TYPE(CV_8U, deviceChannels), baseaddress, rowBytes);
if (cvtCode == -1) {
cv::cvarrToMat(mDeviceImage).copyTo(cv::cvarrToMat(mOutImage));
devImage.copyTo(mOutImage);
} else {
cv::cvtColor(cv::cvarrToMat(mDeviceImage), cv::cvarrToMat(mOutImage), cvtCode);
cv::cvtColor(devImage, mOutImage, cvtCode);
}
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
@ -1138,8 +1047,12 @@ int CvCaptureFile::getPreferredOrientationDegrees() const {
return static_cast<int>(round(radians * 180 / M_PI));
}
IplImage* CvCaptureFile::retrieveFrame(int) {
return retrieveFramePixelBuffer();
bool CvCaptureFile::retrieveFrame(int, cv::OutputArray arr) {
cv::Mat res = retrieveFramePixelBuffer();
if (res.empty())
return false;
res.copyTo(arr);
return true;
}
double CvCaptureFile::getProperty(int property_id) const{
@ -1148,25 +1061,25 @@ double CvCaptureFile::getProperty(int property_id) const{
CMTime t;
switch (property_id) {
case CV_CAP_PROP_POS_MSEC:
case cv::CAP_PROP_POS_MSEC:
return mFrameTimestamp.value * 1000.0 / mFrameTimestamp.timescale;
case CV_CAP_PROP_POS_FRAMES:
case cv::CAP_PROP_POS_FRAMES:
return mAssetTrack.nominalFrameRate > 0 ? mFrameNum : 0;
case CV_CAP_PROP_POS_AVI_RATIO:
case cv::CAP_PROP_POS_AVI_RATIO:
t = [mAsset duration];
return (mFrameTimestamp.value * t.timescale) / double(mFrameTimestamp.timescale * t.value);
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
return mAssetTrack.naturalSize.width;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
return mAssetTrack.naturalSize.height;
case CV_CAP_PROP_FPS:
case cv::CAP_PROP_FPS:
return mAssetTrack.nominalFrameRate;
case CV_CAP_PROP_FRAME_COUNT:
case cv::CAP_PROP_FRAME_COUNT:
t = [mAsset duration];
return round((t.value * mAssetTrack.nominalFrameRate) / double(t.timescale));
case CV_CAP_PROP_FORMAT:
case cv::CAP_PROP_FORMAT:
return mFormat;
case CV_CAP_PROP_FOURCC:
case cv::CAP_PROP_FOURCC:
return mMode;
case cv::CAP_PROP_ORIENTATION_META:
return getPreferredOrientationDegrees();
@ -1186,20 +1099,20 @@ bool CvCaptureFile::setProperty(int property_id, double value) {
CMTime t;
switch (property_id) {
case CV_CAP_PROP_POS_MSEC:
case cv::CAP_PROP_POS_MSEC:
t = mAsset.duration;
t.value = value * t.timescale / 1000;
retval = setupReadingAt(t);
break;
case CV_CAP_PROP_POS_FRAMES:
case cv::CAP_PROP_POS_FRAMES:
retval = mAssetTrack.nominalFrameRate > 0 ? setupReadingAt(CMTimeMake(value, mAssetTrack.nominalFrameRate)) : false;
break;
case CV_CAP_PROP_POS_AVI_RATIO:
case cv::CAP_PROP_POS_AVI_RATIO:
t = mAsset.duration;
t.value = round(t.value * value);
retval = setupReadingAt(t);
break;
case CV_CAP_PROP_FOURCC:
case cv::CAP_PROP_FOURCC:
uint32_t mode;
mode = cvRound(value);
if (mMode == mode) {
@ -1239,7 +1152,7 @@ bool CvCaptureFile::setProperty(int property_id, double value) {
CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const char* filename, int fourcc,
double fps, CvSize frame_size,
double fps, const cv::Size& frame_size,
int is_color) {
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
@ -1249,7 +1162,7 @@ CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const char* filename, int
movieFPS = fps;
movieSize = frame_size;
movieColor = is_color;
argbimage = cvCreateImage(movieSize, IPL_DEPTH_8U, 4);
argbimage = cv::Mat(movieSize, CV_8UC4);
path = [[[NSString stringWithCString:filename encoding:NSASCIIStringEncoding] stringByExpandingTildeInPath] retain];
@ -1387,13 +1300,13 @@ CvVideoWriter_AVFoundation::~CvVideoWriter_AVFoundation() {
[path release];
[codec release];
[fileType release];
cvReleaseImage(&argbimage);
argbimage.release();
[localpool drain];
}];
}
bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
void CvVideoWriter_AVFoundation::write(cv::InputArray image) {
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
// writer status check
@ -1401,30 +1314,30 @@ bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
NSLog(@"[mMovieWriterInput isReadyForMoreMediaData] Not ready for media data or ...");
NSLog(@"mMovieWriter.status: %d. Error: %@", (int)mMovieWriter.status, [mMovieWriter.error localizedDescription]);
[localpool drain];
return false;
return;
}
BOOL success = FALSE;
if (iplimage->height!=movieSize.height || iplimage->width!=movieSize.width){
if (image.size().height!=movieSize.height || image.size().width!=movieSize.width){
std::cout<<"Frame size does not match video size."<<std::endl;
[localpool drain];
return false;
return;
}
if (movieColor) {
//assert(iplimage->nChannels == 3);
cv::cvtColor(cv::cvarrToMat(iplimage), cv::cvarrToMat(argbimage), cv::COLOR_BGR2BGRA);
//assert(image->nChannels == 3);
cv::cvtColor(image, argbimage, cv::COLOR_BGR2BGRA);
}else{
//assert(iplimage->nChannels == 1);
cv::cvtColor(cv::cvarrToMat(iplimage), cv::cvarrToMat(argbimage), cv::COLOR_GRAY2BGRA);
//assert(image->nChannels == 1);
cv::cvtColor(image, argbimage, cv::COLOR_GRAY2BGRA);
}
//IplImage -> CGImage conversion
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData *nsData = [NSData dataWithBytes:argbimage->imageData length:argbimage->imageSize];
NSData *nsData = [NSData dataWithBytes:argbimage.data length:argbimage.total() * argbimage.elemSize()];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)nsData);
CGImageRef cgImage = CGImageCreate(argbimage->width, argbimage->height,
argbimage->depth, argbimage->depth * argbimage->nChannels, argbimage->widthStep,
CGImageRef cgImage = CGImageCreate(argbimage.size().width, argbimage.size().height,
8, 32, argbimage.step[0],
colorSpace, kCGImageAlphaLast|kCGBitmapByteOrderDefault,
provider, NULL, false, kCGRenderingIntentDefault);
@ -1458,10 +1371,10 @@ bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
if (success) {
frameCount ++;
//NSLog(@"Frame #%d", frameCount);
return true;
return;
}else{
NSLog(@"Frame appendPixelBuffer failed.");
return false;
return;
}
}

View File

@ -53,6 +53,7 @@
#define CV_CAP_MODE_GRAY CV_FOURCC_MACRO('G','R','E','Y')
#define CV_CAP_MODE_YUYV CV_FOURCC_MACRO('Y', 'U', 'Y', 'V')
/********************** Declaration of class headers ************************/
/*****************************************************************************
@ -62,8 +63,7 @@
* CaptureDelegate is notified on a separate thread by the OS whenever there
* is a new frame. When "updateImage" is called from the main thread, it
* copies this new frame into an IplImage, but only if this frame has not
* been copied before. When "getOutput" is called from the main thread,
* it gives the last copied IplImage.
* been copied before.
*
*****************************************************************************/
@ -73,9 +73,7 @@
NSCondition *mHasNewFrame;
CVPixelBufferRef mGrabbedPixels;
CVImageBufferRef mCurrentImageBuffer;
IplImage *mDeviceImage;
uint8_t *mOutImagedata;
IplImage *mOutImage;
cv::Mat mOutImage;
size_t currSize;
}
@ -84,8 +82,8 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection;
- (BOOL)grabImageUntilDate: (NSDate *)limit;
- (int)updateImage;
- (IplImage*)getOutput;
- (bool)updateImage;
- (cv::Mat)getImage;
@end
@ -97,17 +95,16 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
*
*****************************************************************************/
class CvCaptureCAM : public CvCapture {
class CvCaptureCAM : public cv::IVideoCapture {
public:
CvCaptureCAM(int cameraNum = -1) ;
~CvCaptureCAM();
bool grabFrame() CV_OVERRIDE;
IplImage* retrieveFrame(int) CV_OVERRIDE;
bool retrieveFrame(int, cv::OutputArray) CV_OVERRIDE;
double getProperty(int property_id) const CV_OVERRIDE;
bool setProperty(int property_id, double value) CV_OVERRIDE;
int getCaptureDomain() /*const*/ CV_OVERRIDE { return cv::CAP_AVFOUNDATION; }
virtual int didStart();
bool isOpened() const CV_OVERRIDE { return started; }
private:
AVCaptureSession *mCaptureSession;
@ -140,17 +137,16 @@ private:
*
*****************************************************************************/
class CvCaptureFile : public CvCapture {
class CvCaptureFile : public cv::VideoCaptureBase {
public:
CvCaptureFile(const char* filename) ;
~CvCaptureFile();
bool grabFrame() CV_OVERRIDE;
IplImage* retrieveFrame(int) CV_OVERRIDE;
double getProperty(int property_id) const CV_OVERRIDE;
bool setProperty(int property_id, double value) CV_OVERRIDE;
bool retrieveFrame_(int, cv::OutputArray) CV_OVERRIDE;
double getProperty_(int property_id) const CV_OVERRIDE;
bool setProperty_(int property_id, double value) CV_OVERRIDE;
int getCaptureDomain() /*const*/ CV_OVERRIDE { return cv::CAP_AVFOUNDATION; }
virtual int didStart();
bool isOpened() const CV_OVERRIDE { return started; }
private:
AVAsset *mAsset;
@ -160,15 +156,13 @@ private:
CMSampleBufferRef mCurrentSampleBuffer;
CVImageBufferRef mGrabbedPixels;
IplImage *mDeviceImage;
uint8_t *mOutImagedata;
IplImage *mOutImage;
cv::Mat mOutImage;
size_t currSize;
uint32_t mMode;
int mFormat;
bool setupReadingAt(CMTime position);
IplImage* retrieveFramePixelBuffer();
cv::Mat retrieveFramePixelBuffer();
int getPreferredOrientationDegrees() const;
CMTime mFrameTimestamp;
@ -186,18 +180,18 @@ private:
*
*****************************************************************************/
class CvVideoWriter_AVFoundation : public CvVideoWriter {
class CvVideoWriter_AVFoundation : public cv::IVideoWriter {
public:
CvVideoWriter_AVFoundation(const std::string &filename, int fourcc, double fps, CvSize frame_size, int is_color);
CvVideoWriter_AVFoundation(const std::string &filename, int fourcc, double fps, const cv::Size& frame_size, int is_color);
~CvVideoWriter_AVFoundation();
bool writeFrame(const IplImage* image) CV_OVERRIDE;
void write(cv::InputArray image) CV_OVERRIDE;
int getCaptureDomain() const CV_OVERRIDE { return cv::CAP_AVFOUNDATION; }
bool isOpened() const
bool isOpened() const CV_OVERRIDE
{
return is_good;
}
private:
IplImage* argbimage;
cv::Mat argbimage;
AVAssetWriter *mMovieWriter;
AVAssetWriterInput* mMovieWriterInput;
@ -207,7 +201,7 @@ class CvVideoWriter_AVFoundation : public CvVideoWriter {
NSString* codec;
NSString* fileType;
double mMovieFPS;
CvSize movieSize;
cv::Size movieSize;
int movieColor;
unsigned long mFrameNum;
bool is_good;
@ -217,35 +211,28 @@ class CvVideoWriter_AVFoundation : public CvVideoWriter {
cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_file(const std::string &filename)
{
CvCaptureFile *retval = new CvCaptureFile(filename.c_str());
if(retval->didStart())
return makePtr<LegacyCapture>(retval);
delete retval;
cv::Ptr<CvCaptureFile> retval = cv::makePtr<CvCaptureFile>(filename.c_str());
if(retval->isOpened())
return retval;
return NULL;
}
cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
{
CvCaptureCAM* retval = new CvCaptureCAM(index);
if (retval->didStart())
return cv::makePtr<cv::LegacyCapture>(retval);
delete retval;
return 0;
cv::Ptr<CvCaptureCAM> retval = cv::makePtr<CvCaptureCAM>(index);
if (retval->isOpened())
return retval;
return NULL;
}
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc,
double fps, const cv::Size& frameSize,
const cv::VideoWriterParameters& params)
{
CvSize sz = { frameSize.width, frameSize.height };
const bool isColor = params.get(VIDEOWRITER_PROP_IS_COLOR, true);
CvVideoWriter_AVFoundation* wrt = new CvVideoWriter_AVFoundation(filename, fourcc, fps, sz, isColor);
const bool isColor = params.get(cv::VIDEOWRITER_PROP_IS_COLOR, true);
cv::Ptr<CvVideoWriter_AVFoundation> wrt = cv::makePtr<CvVideoWriter_AVFoundation>(filename, fourcc, fps, frameSize, isColor);
if (wrt->isOpened())
{
return cv::makePtr<cv::LegacyWriter>(wrt);
}
delete wrt;
return wrt;
return NULL;
}
@ -285,11 +272,6 @@ CvCaptureCAM::~CvCaptureCAM() {
stopCaptureDevice();
}
int CvCaptureCAM::didStart() {
return started;
}
bool CvCaptureCAM::grabFrame() {
return grabFrame(1);
}
@ -300,16 +282,19 @@ bool CvCaptureCAM::grabFrame(double timeOut) {
bool isGrabbed = false;
NSDate *limit = [NSDate dateWithTimeIntervalSinceNow: timeOut];
if ( [mCapture grabImageUntilDate: limit] ) {
[mCapture updateImage];
isGrabbed = true;
isGrabbed = [mCapture updateImage];
}
[localpool drain];
return isGrabbed;
}
IplImage* CvCaptureCAM::retrieveFrame(int) {
return [mCapture getOutput];
bool CvCaptureCAM::retrieveFrame(int, cv::OutputArray arr) {
cv::Mat img = [mCapture getImage];
if (img.empty())
return false;
img.copyTo(arr);
return true;
}
void CvCaptureCAM::stopCaptureDevice() {
@ -494,19 +479,19 @@ double CvCaptureCAM::getProperty(int property_id) const{
double retval = 0;
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
retval = s1.width;
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
retval = s1.height;
break;
case CV_CAP_PROP_FPS:
case cv::CAP_PROP_FPS:
{
CMTime frameDuration = mCaptureDevice.activeVideoMaxFrameDuration;
retval = frameDuration.timescale / double(frameDuration.value);
}
break;
case CV_CAP_PROP_FORMAT:
case cv::CAP_PROP_FORMAT:
retval = CV_8UC3;
break;
default:
@ -523,7 +508,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
bool isSucceeded = false;
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
width = value;
settingWidth = 1;
if (settingWidth && settingHeight) {
@ -533,7 +518,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
}
isSucceeded = true;
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
height = value;
settingHeight = 1;
if (settingWidth && settingHeight) {
@ -543,7 +528,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
}
isSucceeded = true;
break;
case CV_CAP_PROP_FPS:
case cv::CAP_PROP_FPS:
if ( [mCaptureDevice lockForConfiguration: NULL] ) {
NSArray * ranges = mCaptureDevice.activeFormat.videoSupportedFrameRateRanges;
AVFrameRateRange *matchedRange = ranges[0];
@ -577,8 +562,7 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
* CaptureDelegate is notified on a separate thread by the OS whenever there
* is a new frame. When "updateImage" is called from the main thread, it
* copies this new frame into an IplImage, but only if this frame has not
* been copied before. When "getOutput" is called from the main thread,
* it gives the last copied IplImage.
* been copied before.
*
*****************************************************************************/
@ -590,17 +574,12 @@ bool CvCaptureCAM::setProperty(int property_id, double value) {
mHasNewFrame = [[NSCondition alloc] init];
mCurrentImageBuffer = NULL;
mGrabbedPixels = NULL;
mDeviceImage = NULL;
mOutImagedata = NULL;
mOutImage = NULL;
currSize = 0;
return self;
}
-(void)dealloc {
free(mOutImagedata);
cvReleaseImage(&mOutImage);
cvReleaseImage(&mDeviceImage);
mOutImage.release();
CVBufferRelease(mCurrentImageBuffer);
CVBufferRelease(mGrabbedPixels);
[mHasNewFrame release];
@ -627,10 +606,6 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
}
-(IplImage*) getOutput {
return mOutImage;
}
-(BOOL) grabImageUntilDate: (NSDate *)limit {
BOOL isGrabbed = NO;
[mHasNewFrame lock];
@ -647,89 +622,44 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
return isGrabbed;
}
-(int) updateImage {
-(bool) updateImage {
if ( ! mGrabbedPixels ) {
return 0;
return false;
}
CVPixelBufferLockBaseAddress(mGrabbedPixels, 0);
void *baseaddress = CVPixelBufferGetBaseAddress(mGrabbedPixels);
uchar *baseaddress = reinterpret_cast<uchar*>(CVPixelBufferGetBaseAddress(mGrabbedPixels));
size_t width = CVPixelBufferGetWidth(mGrabbedPixels);
size_t height = CVPixelBufferGetHeight(mGrabbedPixels);
cv::Size sz { (int)CVPixelBufferGetWidth(mGrabbedPixels), (int)CVPixelBufferGetHeight(mGrabbedPixels) };
size_t rowBytes = CVPixelBufferGetBytesPerRow(mGrabbedPixels);
OSType pixelFormat = CVPixelBufferGetPixelFormatType(mGrabbedPixels);
if ( rowBytes == 0 ) {
fprintf(stderr, "OpenCV: error: rowBytes == 0\n");
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
}
if ( currSize != width*3*height ) {
currSize = width*3*height;
free(mOutImagedata);
mOutImagedata = reinterpret_cast<uint8_t*>(malloc(currSize));
}
if (mOutImage == NULL) {
mOutImage = cvCreateImageHeader(cvSize((int)width,(int)height), IPL_DEPTH_8U, 3);
}
mOutImage->width = int(width);
mOutImage->height = int(height);
mOutImage->nChannels = 3;
mOutImage->depth = IPL_DEPTH_8U;
mOutImage->widthStep = int(width*3);
mOutImage->imageData = reinterpret_cast<char *>(mOutImagedata);
mOutImage->imageSize = int(currSize);
if ( pixelFormat == kCVPixelFormatType_32BGRA ) {
if (mDeviceImage == NULL) {
mDeviceImage = cvCreateImageHeader(cvSize(int(width),int(height)), IPL_DEPTH_8U, 4);
bool res = false;
if (rowBytes != 0 && (pixelFormat == kCVPixelFormatType_32BGRA || pixelFormat == kCVPixelFormatType_422YpCbCr8)) {
mOutImage.create(sz, CV_8UC3);
if ( pixelFormat == kCVPixelFormatType_32BGRA ) {
cv::Mat devImage(sz, CV_8UC4, baseaddress, rowBytes);
cv::cvtColor(devImage, mOutImage, cv::COLOR_BGRA2BGR);
res = true;
} else if ( pixelFormat == kCVPixelFormatType_422YpCbCr8 ) {
cv::Mat devImage(sz, CV_8UC2, baseaddress, rowBytes);
cv::cvtColor(devImage, mOutImage, cv::COLOR_YUV2BGR_UYVY);
res = true;
}
mDeviceImage->width = int(width);
mDeviceImage->height = int(height);
mDeviceImage->nChannels = 4;
mDeviceImage->depth = IPL_DEPTH_8U;
mDeviceImage->widthStep = int(rowBytes);
mDeviceImage->imageData = reinterpret_cast<char *>(baseaddress);
mDeviceImage->imageSize = int(rowBytes*height);
cvtColor(cv::cvarrToMat(mDeviceImage), cv::cvarrToMat(mOutImage), cv::COLOR_BGRA2BGR);
} else if ( pixelFormat == kCVPixelFormatType_422YpCbCr8 ) {
if ( currSize != width*3*height ) {
currSize = width*3*height;
free(mOutImagedata);
mOutImagedata = reinterpret_cast<uint8_t*>(malloc(currSize));
}
if (mDeviceImage == NULL) {
mDeviceImage = cvCreateImageHeader(cvSize(int(width),int(height)), IPL_DEPTH_8U, 2);
}
mDeviceImage->width = int(width);
mDeviceImage->height = int(height);
mDeviceImage->nChannels = 2;
mDeviceImage->depth = IPL_DEPTH_8U;
mDeviceImage->widthStep = int(rowBytes);
mDeviceImage->imageData = reinterpret_cast<char *>(baseaddress);
mDeviceImage->imageSize = int(rowBytes*height);
cvtColor(cv::cvarrToMat(mDeviceImage), cv::cvarrToMat(mOutImage), cv::COLOR_YUV2BGR_UYVY);
} else {
fprintf(stderr, "OpenCV: unknown pixel format 0x%08X\n", pixelFormat);
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
fprintf(stderr, "OpenCV: rowBytes == 0 or unknown pixel format 0x%08X\n", pixelFormat);
mOutImage.create(cv::Size(0, 0), mOutImage.type());
}
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 1;
return res;
}
-(cv::Mat) getImage {
return mOutImage;
}
@end
@ -750,9 +680,6 @@ CvCaptureFile::CvCaptureFile(const char* filename) {
mAssetTrack = nil;
mAssetReader = nil;
mTrackOutput = nil;
mDeviceImage = NULL;
mOutImage = NULL;
mOutImagedata = NULL;
currSize = 0;
mMode = CV_CAP_MODE_BGR;
mFormat = CV_8UC3;
@ -796,9 +723,7 @@ CvCaptureFile::CvCaptureFile(const char* filename) {
CvCaptureFile::~CvCaptureFile() {
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
free(mOutImagedata);
cvReleaseImage(&mOutImage);
cvReleaseImage(&mDeviceImage);
mOutImage.release();
[mAssetReader release];
[mTrackOutput release];
[mAssetTrack release];
@ -873,10 +798,6 @@ bool CvCaptureFile::setupReadingAt(CMTime position) {
return [mAssetReader startReading];
}
int CvCaptureFile::didStart() {
return started;
}
bool CvCaptureFile::grabFrame() {
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
@ -896,28 +817,29 @@ bool CvCaptureFile::grabFrame() {
}
IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
cv::Mat CvCaptureFile::retrieveFramePixelBuffer() {
if ( ! mGrabbedPixels ) {
return 0;
return cv::Mat();
}
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
CVPixelBufferLockBaseAddress(mGrabbedPixels, 0);
void *baseaddress;
size_t width, height, rowBytes;
uchar *baseaddress;
size_t rowBytes;
cv::Size sz;
OSType pixelFormat = CVPixelBufferGetPixelFormatType(mGrabbedPixels);
if (CVPixelBufferIsPlanar(mGrabbedPixels)) {
baseaddress = CVPixelBufferGetBaseAddressOfPlane(mGrabbedPixels, 0);
width = CVPixelBufferGetWidthOfPlane(mGrabbedPixels, 0);
height = CVPixelBufferGetHeightOfPlane(mGrabbedPixels, 0);
baseaddress = reinterpret_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(mGrabbedPixels, 0));
sz.width = CVPixelBufferGetWidthOfPlane(mGrabbedPixels, 0);
sz.height = CVPixelBufferGetHeightOfPlane(mGrabbedPixels, 0);
rowBytes = CVPixelBufferGetBytesPerRowOfPlane(mGrabbedPixels, 0);
} else {
baseaddress = CVPixelBufferGetBaseAddress(mGrabbedPixels);
width = CVPixelBufferGetWidth(mGrabbedPixels);
height = CVPixelBufferGetHeight(mGrabbedPixels);
baseaddress = reinterpret_cast<uchar*>(CVPixelBufferGetBaseAddress(mGrabbedPixels));
sz.width = CVPixelBufferGetWidth(mGrabbedPixels);
sz.height = CVPixelBufferGetHeight(mGrabbedPixels);
rowBytes = CVPixelBufferGetBytesPerRow(mGrabbedPixels);
}
@ -926,7 +848,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
return cv::Mat();
}
// Output image parameters.
@ -942,27 +864,9 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
return cv::Mat();
}
if ( currSize != width*outChannels*height ) {
currSize = width*outChannels*height;
free(mOutImagedata);
mOutImagedata = reinterpret_cast<uint8_t*>(malloc(currSize));
}
// Build the header for the output image.
if (mOutImage == NULL) {
mOutImage = cvCreateImageHeader(cvSize((int)width,(int)height), IPL_DEPTH_8U, outChannels);
}
mOutImage->width = int(width);
mOutImage->height = int(height);
mOutImage->nChannels = outChannels;
mOutImage->depth = IPL_DEPTH_8U;
mOutImage->widthStep = int(width*outChannels);
mOutImage->imageData = reinterpret_cast<char *>(mOutImagedata);
mOutImage->imageSize = int(currSize);
// Device image parameters and conversion code.
// (Not all of these conversions are used in production, but they were all tested to find the fastest options.)
int deviceChannels;
@ -982,7 +886,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else if ( pixelFormat == kCVPixelFormatType_24RGB ) {
deviceChannels = 3;
@ -990,7 +894,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
if (mMode == CV_CAP_MODE_BGR) {
cvtCode = cv::COLOR_RGB2BGR;
} else if (mMode == CV_CAP_MODE_RGB) {
cvtCode = 0;
cvtCode = -1;
} else if (mMode == CV_CAP_MODE_GRAY) {
cvtCode = cv::COLOR_RGB2GRAY;
} else {
@ -998,7 +902,7 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else if ( pixelFormat == kCVPixelFormatType_422YpCbCr8 ) { // 422 (2vuy, UYVY)
deviceChannels = 2;
@ -1016,13 +920,13 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else if ( pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange || // 420v
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ) { // 420f
// cvtColor(cv::COLOR_YUV2GRAY_420) is expecting a single buffer with both the Y plane and the CrCb planes.
// So, lie about the height of the buffer. cvtColor(cv::COLOR_YUV2GRAY_420) will only read the first 2/3 of it.
height = height * 3 / 2;
sz.height = sz.height * 3 / 2;
deviceChannels = 1;
if (mMode == CV_CAP_MODE_BGR) {
@ -1036,34 +940,24 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
fprintf(stderr, "OpenCV: unsupported pixel conversion mode\n");
return 0;
return cv::Mat();
}
} else {
fprintf(stderr, "OpenCV: unsupported pixel format 0x%08X\n", pixelFormat);
CVPixelBufferUnlockBaseAddress(mGrabbedPixels, 0);
CVBufferRelease(mGrabbedPixels);
mGrabbedPixels = NULL;
return 0;
return cv::Mat();
}
// Build the header for the device image.
if (mDeviceImage == NULL) {
mDeviceImage = cvCreateImageHeader(cvSize(int(width),int(height)), IPL_DEPTH_8U, deviceChannels);
}
mDeviceImage->width = int(width);
mDeviceImage->height = int(height);
mDeviceImage->nChannels = deviceChannels;
mDeviceImage->depth = IPL_DEPTH_8U;
mDeviceImage->widthStep = int(rowBytes);
mDeviceImage->imageData = reinterpret_cast<char *>(baseaddress);
mDeviceImage->imageSize = int(rowBytes*height);
mOutImage.create(sz, CV_MAKE_TYPE(CV_8U, outChannels));
cv::Mat devImage(sz, CV_MAKE_TYPE(CV_8U, deviceChannels), baseaddress, rowBytes);
// Convert the device image into the output image.
if (cvtCode == -1) {
// Copy.
cv::cvarrToMat(mDeviceImage).copyTo(cv::cvarrToMat(mOutImage));
devImage.copyTo(mOutImage);
} else {
cvtColor(cv::cvarrToMat(mDeviceImage), cv::cvarrToMat(mOutImage), cvtCode);
cv::cvtColor(devImage, mOutImage, cvtCode);
}
@ -1082,35 +976,39 @@ int CvCaptureFile::getPreferredOrientationDegrees() const {
return static_cast<int>(round(radians * 180 / M_PI));
}
IplImage* CvCaptureFile::retrieveFrame(int) {
return retrieveFramePixelBuffer();
bool CvCaptureFile::retrieveFrame_(int, cv::OutputArray arr) {
cv::Mat res = retrieveFramePixelBuffer();
if (res.empty())
return false;
res.copyTo(arr);
return true;
}
double CvCaptureFile::getProperty(int property_id) const{
double CvCaptureFile::getProperty_(int property_id) const{
if (mAsset == nil) return 0;
CMTime t;
switch (property_id) {
case CV_CAP_PROP_POS_MSEC:
case cv::CAP_PROP_POS_MSEC:
return mFrameTimestamp.value * 1000.0 / mFrameTimestamp.timescale;
case CV_CAP_PROP_POS_FRAMES:
case cv::CAP_PROP_POS_FRAMES:
return mAssetTrack.nominalFrameRate > 0 ? mFrameNum : 0;
case CV_CAP_PROP_POS_AVI_RATIO:
case cv::CAP_PROP_POS_AVI_RATIO:
t = [mAsset duration];
return (mFrameTimestamp.value * t.timescale) / double(mFrameTimestamp.timescale * t.value);
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
return mAssetTrack.naturalSize.width;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
return mAssetTrack.naturalSize.height;
case CV_CAP_PROP_FPS:
case cv::CAP_PROP_FPS:
return mAssetTrack.nominalFrameRate;
case CV_CAP_PROP_FRAME_COUNT:
case cv::CAP_PROP_FRAME_COUNT:
t = [mAsset duration];
return round((t.value * mAssetTrack.nominalFrameRate) / double(t.timescale));
case CV_CAP_PROP_FORMAT:
case cv::CAP_PROP_FORMAT:
return mFormat;
case CV_CAP_PROP_FOURCC:
case cv::CAP_PROP_FOURCC:
return mMode;
case cv::CAP_PROP_ORIENTATION_META:
return getPreferredOrientationDegrees();
@ -1121,7 +1019,7 @@ double CvCaptureFile::getProperty(int property_id) const{
return 0;
}
bool CvCaptureFile::setProperty(int property_id, double value) {
bool CvCaptureFile::setProperty_(int property_id, double value) {
if (mAsset == nil) return false;
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
@ -1130,20 +1028,20 @@ bool CvCaptureFile::setProperty(int property_id, double value) {
CMTime t;
switch (property_id) {
case CV_CAP_PROP_POS_MSEC:
case cv::CAP_PROP_POS_MSEC:
t = mAsset.duration;
t.value = value * t.timescale / 1000;
retval = setupReadingAt(t);
break;
case CV_CAP_PROP_POS_FRAMES:
case cv::CAP_PROP_POS_FRAMES:
retval = mAssetTrack.nominalFrameRate > 0 ? setupReadingAt(CMTimeMake(value, mAssetTrack.nominalFrameRate)) : false;
break;
case CV_CAP_PROP_POS_AVI_RATIO:
case cv::CAP_PROP_POS_AVI_RATIO:
t = mAsset.duration;
t.value = round(t.value * value);
retval = setupReadingAt(t);
break;
case CV_CAP_PROP_FOURCC:
case cv::CAP_PROP_FOURCC:
uint32_t mode;
mode = cvRound(value);
if (mMode == mode) {
@ -1182,8 +1080,8 @@ bool CvCaptureFile::setProperty(int property_id, double value) {
*****************************************************************************/
CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const std::string &filename, int fourcc, double fps, CvSize frame_size, int is_color)
: argbimage(nil), mMovieWriter(nil), mMovieWriterInput(nil), mMovieWriterAdaptor(nil), path(nil),
CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const std::string &filename, int fourcc, double fps, const cv::Size& frame_size, int is_color)
: mMovieWriter(nil), mMovieWriterInput(nil), mMovieWriterAdaptor(nil), path(nil),
codec(nil), fileType(nil), mMovieFPS(fps), movieSize(frame_size), movieColor(is_color), mFrameNum(0),
is_good(true)
{
@ -1194,7 +1092,7 @@ CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const std::string &filena
}
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
argbimage = cvCreateImage(movieSize, IPL_DEPTH_8U, 4);
argbimage.create(movieSize, CV_8UC4);
path = [[[NSString stringWithUTF8String:filename.c_str()] stringByExpandingTildeInPath] retain];
NSString *fileExt =[[[path pathExtension] lowercaseString] copy];
@ -1314,8 +1212,8 @@ CvVideoWriter_AVFoundation::~CvVideoWriter_AVFoundation() {
[codec release];
if (fileType)
[fileType release];
if (argbimage)
cvReleaseImage(&argbimage);
if (!argbimage.empty())
argbimage.release();
[localpool drain];
@ -1325,14 +1223,14 @@ static void releaseCallback( void *releaseRefCon, const void * ) {
CFRelease((CFDataRef)releaseRefCon);
}
bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
void CvVideoWriter_AVFoundation::write(cv::InputArray image) {
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
// writer status check
if (mMovieWriter.status != AVAssetWriterStatusWriting ) {
NSLog(@"mMovieWriter.status: %d. Error: %@", (int)mMovieWriter.status, [mMovieWriter.error localizedDescription]);
[localpool drain];
return false;
return;
}
// Make writeFrame() a blocking call.
@ -1344,25 +1242,23 @@ bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
BOOL success = FALSE;
if (iplimage->height!=movieSize.height || iplimage->width!=movieSize.width){
if (image.size().height!=movieSize.height || image.size().width!=movieSize.width){
fprintf(stderr, "OpenCV: Frame size does not match video size.\n");
[localpool drain];
return false;
return;
}
if (movieColor) {
//assert(iplimage->nChannels == 3);
cvtColor(cv::cvarrToMat(iplimage), cv::cvarrToMat(argbimage), cv::COLOR_BGR2BGRA);
cv::cvtColor(image, argbimage, cv::COLOR_BGR2BGRA);
}else{
//assert(iplimage->nChannels == 1);
cvtColor(cv::cvarrToMat(iplimage), cv::cvarrToMat(argbimage), cv::COLOR_GRAY2BGRA);
cv::cvtColor(image, argbimage, cv::COLOR_GRAY2BGRA);
}
//IplImage -> CGImage conversion
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData *nsData = [NSData dataWithBytes:argbimage->imageData length:argbimage->imageSize];
NSData *nsData = [NSData dataWithBytes:argbimage.data length:argbimage.total() * argbimage.elemSize()];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)nsData);
CGImageRef cgImage = CGImageCreate(argbimage->width, argbimage->height,
argbimage->depth, argbimage->depth * argbimage->nChannels, argbimage->widthStep,
CGImageRef cgImage = CGImageCreate(argbimage.size().width, argbimage.size().height,
8, 32, argbimage.step[0],
colorSpace, kCGImageAlphaLast|kCGBitmapByteOrderDefault,
provider, NULL, false, kCGRenderingIntentDefault);
@ -1395,10 +1291,8 @@ bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
if (success) {
mFrameNum ++;
//NSLog(@"Frame #%d", mFrameNum);
return true;
}else{
NSLog(@"Frame appendPixelBuffer failed.");
return false;
}
}

View File

@ -60,6 +60,8 @@
#include <stdlib.h>
#include <string.h>
using namespace cv;
struct CvDC1394
{
CvDC1394();
@ -88,24 +90,27 @@ static CvDC1394& getDC1394()
return dc1394;
}
class CvCaptureCAM_DC1394_v2_CPP : public CvCapture
#define CAP_PROP_MAX_DC1394 31
class CvCaptureCAM_DC1394_v2_CPP : public IVideoCapture
{
public:
static int dc1394properties[CV_CAP_PROP_MAX_DC1394];
static int dc1394properties[CAP_PROP_MAX_DC1394];
CvCaptureCAM_DC1394_v2_CPP();
virtual ~CvCaptureCAM_DC1394_v2_CPP()
~CvCaptureCAM_DC1394_v2_CPP()
{
close();
}
virtual bool open(int index);
virtual void close();
bool open(int index);
void close();
virtual double getProperty(int) const CV_OVERRIDE;
virtual bool setProperty(int, double) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_DC1394; }
double getProperty(int) const CV_OVERRIDE;
bool setProperty(int, double) CV_OVERRIDE;
bool grabFrame() CV_OVERRIDE;
bool retrieveFrame(int, OutputArray) CV_OVERRIDE;
int getCaptureDomain() CV_OVERRIDE { return CAP_DC1394; }
bool isOpened() const CV_OVERRIDE { return dcCam && started; }
protected:
@ -129,37 +134,37 @@ protected:
dc1394color_filter_t bayerFilter;
enum { NIMG = 2 };
IplImage *img[NIMG];
Mat img[NIMG];
dc1394video_frame_t* frameC;
int nimages;
dc1394featureset_t feature_set;
};
//mapping CV_CAP_PROP_ to DC1394_FEATUREs
int CvCaptureCAM_DC1394_v2_CPP::dc1394properties[CV_CAP_PROP_MAX_DC1394] = {
-1, //no corresponding feature for CV_CAP_PROP_POS_MSEC
//mapping CAP_PROP_ to DC1394_FEATUREs
int CvCaptureCAM_DC1394_v2_CPP::dc1394properties[CAP_PROP_MAX_DC1394] = {
-1, //no corresponding feature for CAP_PROP_POS_MSEC
-1,-1,-1,-1,
DC1394_FEATURE_FRAME_RATE, //CV_CAP_PROP_FPS - fps can be set for format 7 only!
DC1394_FEATURE_FRAME_RATE, //CAP_PROP_FPS - fps can be set for format 7 only!
-1,-1,-1,-1,
DC1394_FEATURE_BRIGHTNESS, //CV_CAP_PROP_BRIGHTNESS 10
DC1394_FEATURE_BRIGHTNESS, //CAP_PROP_BRIGHTNESS 10
-1,
DC1394_FEATURE_SATURATION, //CV_CAP_PROP_SATURATION
DC1394_FEATURE_SATURATION, //CAP_PROP_SATURATION
DC1394_FEATURE_HUE,
DC1394_FEATURE_GAIN,
DC1394_FEATURE_SHUTTER, //CV_CAP_PROP_EXPOSURE
-1, //CV_CAP_PROP_CONVERT_RGB
DC1394_FEATURE_WHITE_BALANCE, //corresponds to CV_CAP_PROP_WHITE_BALANCE_BLUE_U and CV_CAP_PROP_WHITE_BALANCE_RED_V, see set function to check these props are set
DC1394_FEATURE_SHUTTER, //CAP_PROP_EXPOSURE
-1, //CAP_PROP_CONVERT_RGB
DC1394_FEATURE_WHITE_BALANCE, //corresponds to CAP_PROP_WHITE_BALANCE_BLUE_U and CAP_PROP_WHITE_BALANCE_RED_V, see set function to check these props are set
-1,-1,
DC1394_FEATURE_SHARPNESS, //20
DC1394_FEATURE_EXPOSURE, //CV_CAP_PROP_AUTO_EXPOSURE - this is auto exposure according to the IIDC standard
DC1394_FEATURE_GAMMA, //CV_CAP_PROP_GAMMA
DC1394_FEATURE_TEMPERATURE, //CV_CAP_PROP_TEMPERATURE
DC1394_FEATURE_TRIGGER, //CV_CAP_PROP_TRIGGER
DC1394_FEATURE_TRIGGER_DELAY, //CV_CAP_PROP_TRIGGER_DELAY
DC1394_FEATURE_WHITE_BALANCE, //CV_CAP_PROP_WHITE_BALANCE_RED_V
DC1394_FEATURE_ZOOM, //CV_CAP_PROP_ZOOM
DC1394_FEATURE_FOCUS, //CV_CAP_PROP_FOCUS
-1 //CV_CAP_PROP_GUID
DC1394_FEATURE_EXPOSURE, //CAP_PROP_AUTO_EXPOSURE - this is auto exposure according to the IIDC standard
DC1394_FEATURE_GAMMA, //CAP_PROP_GAMMA
DC1394_FEATURE_TEMPERATURE, //CAP_PROP_TEMPERATURE
DC1394_FEATURE_TRIGGER, //CAP_PROP_TRIGGER
DC1394_FEATURE_TRIGGER_DELAY, //CAP_PROP_TRIGGER_DELAY
DC1394_FEATURE_WHITE_BALANCE, //CAP_PROP_WHITE_BALANCE_RED_V
DC1394_FEATURE_ZOOM, //CAP_PROP_ZOOM
DC1394_FEATURE_FOCUS, //CAP_PROP_FOCUS
-1 //CAP_PROP_GUID
};
CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP()
{
@ -177,8 +182,6 @@ CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP()
frameWidth = 640;
frameHeight = 480;
for (int i = 0; i < NIMG; i++)
img[i] = 0;
frameC = 0;
nimages = 1;
userMode = -1;
@ -396,7 +399,7 @@ void CvCaptureCAM_DC1394_v2_CPP::close()
for (int i = 0; i < NIMG; i++)
{
cvReleaseImage(&img[i]);
img[i].release();
}
if (frameC)
{
@ -446,7 +449,6 @@ bool CvCaptureCAM_DC1394_v2_CPP::grabFrame()
for (i = 0; i < nimages; i++)
{
IplImage fhdr;
dc1394video_frame_t f = fs ? *fs : *dcFrame, *fc = &f;
f.size[1] /= nimages;
f.image += f.size[0] * f.size[1] * i; // TODO: make it more universal
@ -468,19 +470,18 @@ bool CvCaptureCAM_DC1394_v2_CPP::grabFrame()
}
fc = frameC;
}
if (!img[i])
img[i] = cvCreateImage(cvSize(fc->size[0], fc->size[1]), 8, nch);
cvInitImageHeader(&fhdr, cvSize(fc->size[0], fc->size[1]), 8, nch);
cvSetData(&fhdr, fc->image, fc->size[0]*nch);
Mat frame(Size(fc->size[0], fc->size[1]), CV_MAKE_TYPE(CV_8U, nch), fc->image);
img[i].create(frame.size(), frame.type());
// Swap R&B channels:
if (nch==3)
{
cv::Mat tmp = cv::cvarrToMat(&fhdr);
cv::cvtColor(tmp, tmp, cv::COLOR_RGB2BGR, tmp.channels());
cv::cvtColor(frame, img[i], cv::COLOR_RGB2BGR);
}
else
{
frame.copyTo(img[i]);
}
cvCopy(&fhdr, img[i]);
}
code = true;
@ -498,9 +499,13 @@ _exit_:
return code;
}
IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx)
bool CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx, OutputArray arr)
{
return 0 <= idx && idx < nimages ? img[idx] : 0;
if (0 <= idx && idx < nimages)
img[idx].copyTo(arr);
else
return false;
return true;
}
double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId) const
@ -510,40 +515,40 @@ double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId) const
switch (propId)
{
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return frameWidth ? frameWidth : frameHeight*4 / 3;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return frameHeight ? frameHeight : frameWidth*3 / 4;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
return fps;
case CV_CAP_PROP_RECTIFICATION:
case CAP_PROP_RECTIFICATION:
CV_LOG_WARNING(NULL, "cap_dc1394: rectification support has been removed from videoio module");
return 0;
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
if (dc1394_feature_whitebalance_get_value(dcCam,
&fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value,
&fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS)
return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value;
break;
case CV_CAP_PROP_WHITE_BALANCE_RED_V:
case CAP_PROP_WHITE_BALANCE_RED_V:
if (dc1394_feature_whitebalance_get_value(dcCam,
&fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value,
&fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS)
return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value;
break;
case CV_CAP_PROP_GUID:
case CAP_PROP_GUID:
//the least 32 bits are enough to identify the camera
return (double) (guid & 0x00000000FFFFFFFF);
break;
case CV_CAP_PROP_MODE:
case CAP_PROP_MODE:
return (double) userMode;
break;
case CV_CAP_PROP_ISO_SPEED:
case CAP_PROP_ISO_SPEED:
return (double) isoSpeed;
case CV_CAP_PROP_BUFFERSIZE:
case CAP_PROP_BUFFERSIZE:
return (double) nDMABufs;
default:
if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
if (propId<CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
&& dcCam)
//&& feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable)
if (dc1394_feature_get_value(dcCam,(dc1394feature_t)dc1394properties[propId],
@ -557,50 +562,50 @@ bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
{
switch (propId)
{
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
if(started)
return false;
frameWidth = cvRound(value);
frameHeight = 0;
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
if(started)
return false;
frameWidth = 0;
frameHeight = cvRound(value);
break;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
if(started)
return false;
fps = value;
break;
case CV_CAP_PROP_RECTIFICATION:
case CAP_PROP_RECTIFICATION:
CV_LOG_WARNING(NULL, "cap_dc1394: rectification support has been removed from videoio module");
return false;
case CV_CAP_PROP_MODE:
case CAP_PROP_MODE:
if(started)
return false;
userMode = cvRound(value);
break;
case CV_CAP_PROP_ISO_SPEED:
case CAP_PROP_ISO_SPEED:
if(started)
return false;
isoSpeed = cvRound(value);
break;
case CV_CAP_PROP_BUFFERSIZE:
case CAP_PROP_BUFFERSIZE:
if(started)
return false;
nDMABufs = value;
break;
//The code below is based on coriander, callbacks.c:795, refer to case RANGE_MENU_MAN :
default:
if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
if (propId<CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
&& dcCam)
{
//get the corresponding feature from property-id
dc1394feature_info_t *act_feature = &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN];
if (cvRound(value) == CV_CAP_PROP_DC1394_OFF)
if (cvRound(value) == CAP_PROP_DC1394_OFF)
{
if ( (act_feature->on_off_capable)
&& (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_OFF) == DC1394_SUCCESS))
@ -624,7 +629,7 @@ bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
else
act_feature->abs_control=DC1394_OFF;
//set AUTO
if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_AUTO)
if (cvRound(value) == CAP_PROP_DC1394_MODE_AUTO)
{
if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS)
return false;
@ -632,7 +637,7 @@ bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
return true;
}
//set ONE PUSH
if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO)
if (cvRound(value) == CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO)
{
//have to set to manual first, otherwise one push will be ignored (AVT manual 4.3.0 p. 115)
if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS)
@ -647,7 +652,7 @@ bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
else
act_feature->current_mode=DC1394_FEATURE_MODE_MANUAL;
// if property is one of the white balance features treat it in different way
if (propId == CV_CAP_PROP_WHITE_BALANCE_BLUE_U)
if (propId == CAP_PROP_WHITE_BALANCE_BLUE_U)
{
if (dc1394_feature_whitebalance_set_value(dcCam,cvRound(value), act_feature->RV_value)!=DC1394_SUCCESS)
return false;
@ -657,7 +662,7 @@ bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
return true;
}
}
if (propId == CV_CAP_PROP_WHITE_BALANCE_RED_V)
if (propId == CAP_PROP_WHITE_BALANCE_RED_V)
{
if (dc1394_feature_whitebalance_set_value(dcCam, act_feature->BU_value, cvRound(value))!=DC1394_SUCCESS)
return false;
@ -692,10 +697,9 @@ bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
cv::Ptr<cv::IVideoCapture> cv::create_DC1394_capture(int index)
{
CvCaptureCAM_DC1394_v2_CPP* capture = new CvCaptureCAM_DC1394_v2_CPP;
Ptr<CvCaptureCAM_DC1394_v2_CPP> capture = makePtr<CvCaptureCAM_DC1394_v2_CPP>();
if (capture->open(index))
return cv::makePtr<cv::LegacyCapture>(capture);
delete capture;
return capture;
return 0;
}

View File

@ -41,6 +41,8 @@
#include "precomp.hpp"
using namespace cv;
#if defined _WIN32 && defined HAVE_DSHOW
#include "cap_dshow.hpp"
@ -544,7 +546,7 @@ class videoInput{
//number of devices available
int devicesFound;
// mapping from OpenCV CV_CAP_PROP to videoinput/dshow properties
// mapping from OpenCV CAP_PROP to videoinput/dshow properties
int getVideoPropertyFromCV(int cv_property);
int getCameraPropertyFromCV(int cv_property);
@ -2379,37 +2381,37 @@ void videoInput::getVideoPropertyAsString(int prop, char * propertyAsString){
int videoInput::getVideoPropertyFromCV(int cv_property){
// see VideoProcAmpProperty in strmif.h
switch (cv_property) {
case CV_CAP_PROP_BRIGHTNESS:
case CAP_PROP_BRIGHTNESS:
return VideoProcAmp_Brightness;
case CV_CAP_PROP_CONTRAST:
case CAP_PROP_CONTRAST:
return VideoProcAmp_Contrast;
case CV_CAP_PROP_HUE:
case CAP_PROP_HUE:
return VideoProcAmp_Hue;
case CV_CAP_PROP_SATURATION:
case CAP_PROP_SATURATION:
return VideoProcAmp_Saturation;
case CV_CAP_PROP_SHARPNESS:
case CAP_PROP_SHARPNESS:
return VideoProcAmp_Sharpness;
case CV_CAP_PROP_GAMMA:
case CAP_PROP_GAMMA:
return VideoProcAmp_Gamma;
case CV_CAP_PROP_MONOCHROME:
case CAP_PROP_MONOCHROME:
return VideoProcAmp_ColorEnable;
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
return VideoProcAmp_WhiteBalance;
case cv::VideoCaptureProperties::CAP_PROP_AUTO_WB:
return VideoProcAmp_WhiteBalance;
case CV_CAP_PROP_BACKLIGHT:
case CAP_PROP_BACKLIGHT:
return VideoProcAmp_BacklightCompensation;
case CV_CAP_PROP_GAIN:
case CAP_PROP_GAIN:
return VideoProcAmp_Gain;
}
return -1;
@ -2419,26 +2421,29 @@ int videoInput::getCameraPropertyFromCV(int cv_property){
// see CameraControlProperty in strmif.h
switch (cv_property) {
case CV_CAP_PROP_PAN:
case CAP_PROP_PAN:
return CameraControl_Pan;
case CV_CAP_PROP_TILT:
case CAP_PROP_TILT:
return CameraControl_Tilt;
case CV_CAP_PROP_ROLL:
case CAP_PROP_ROLL:
return CameraControl_Roll;
case CV_CAP_PROP_ZOOM:
case CAP_PROP_ZOOM:
return CameraControl_Zoom;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
return CameraControl_Exposure;
case CV_CAP_PROP_IRIS:
case CAP_PROP_IRIS:
return CameraControl_Iris;
case CV_CAP_PROP_FOCUS:
case CAP_PROP_FOCUS:
return CameraControl_Focus;
default:
break;
}
return -1;
}
@ -3389,35 +3394,35 @@ double VideoCapture_DShow::getProperty(int propIdx) const
switch (propIdx)
{
// image format properties
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return g_VI.getWidth(m_index);
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return g_VI.getHeight(m_index);
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
return g_VI.getFourcc(m_index);
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
return g_VI.getFPS(m_index);
case CV_CAP_PROP_CONVERT_RGB:
case CAP_PROP_CONVERT_RGB:
return g_VI.getConvertRGB(m_index);
case CAP_PROP_CHANNEL:
return g_VI.getChannel(m_index);
case CV_CAP_PROP_AUTOFOCUS:
case CAP_PROP_AUTOFOCUS:
// Flags indicate whether or not autofocus is enabled
if (g_VI.getVideoSettingCamera(m_index, CameraControl_Focus, min_value, max_value, stepping_delta, current_value, flags, defaultValue))
return (double)flags;
break;
// video filter properties
case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_HUE:
case CV_CAP_PROP_SATURATION:
case CV_CAP_PROP_SHARPNESS:
case CV_CAP_PROP_GAMMA:
case CV_CAP_PROP_MONOCHROME:
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_BACKLIGHT:
case CV_CAP_PROP_GAIN:
case CAP_PROP_BRIGHTNESS:
case CAP_PROP_CONTRAST:
case CAP_PROP_HUE:
case CAP_PROP_SATURATION:
case CAP_PROP_SHARPNESS:
case CAP_PROP_GAMMA:
case CAP_PROP_MONOCHROME:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_BACKLIGHT:
case CAP_PROP_GAIN:
if (g_VI.getVideoSettingFilter(m_index, g_VI.getVideoPropertyFromCV(propIdx), min_value, max_value, stepping_delta, current_value, flags, defaultValue))
return (double)current_value;
break;
@ -3428,17 +3433,17 @@ double VideoCapture_DShow::getProperty(int propIdx) const
break;
// camera properties
case CV_CAP_PROP_PAN:
case CV_CAP_PROP_TILT:
case CV_CAP_PROP_ROLL:
case CV_CAP_PROP_ZOOM:
case CV_CAP_PROP_EXPOSURE:
case CV_CAP_PROP_IRIS:
case CV_CAP_PROP_FOCUS:
case CAP_PROP_PAN:
case CAP_PROP_TILT:
case CAP_PROP_ROLL:
case CAP_PROP_ZOOM:
case CAP_PROP_EXPOSURE:
case CAP_PROP_IRIS:
case CAP_PROP_FOCUS:
if (g_VI.getVideoSettingCamera(m_index, g_VI.getCameraPropertyFromCV(propIdx), min_value, max_value, stepping_delta, current_value, flags, defaultValue))
return (double)current_value;
break;
case CV_CAP_PROP_SETTINGS:
case CAP_PROP_SETTINGS:
return g_VI.property_window_count(m_index);
default:
break;
@ -3452,17 +3457,17 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
bool handled = false;
switch (propIdx)
{
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
m_width = cvRound(propVal);
handled = true;
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
m_height = cvRound(propVal);
handled = true;
break;
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
m_fourcc = (int)(unsigned long)(propVal);
m_width = (int)getProperty(CAP_PROP_FRAME_WIDTH);
m_height = (int)getProperty(CAP_PROP_FRAME_HEIGHT);
@ -3488,7 +3493,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
g_VI.setConvertRGB(m_index, m_convertRGBSet);
break;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
{
int fps = cvRound(propVal);
if (fps != g_VI.getFPS(m_index))
@ -3504,7 +3509,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
return g_VI.isDeviceSetup(m_index);
}
case CV_CAP_PROP_AUTO_EXPOSURE:
case CAP_PROP_AUTO_EXPOSURE:
{
// Flags are required to toggle auto exposure or not, but the setProperty interface does not support multiple parameters
bool enabled = cvRound(propVal) == 1;
@ -3516,7 +3521,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
return g_VI.setVideoSettingCamera(m_index, CameraControl_Exposure, currentExposure, enabled ? CameraControl_Flags_Auto | CameraControl_Flags_Manual : CameraControl_Flags_Manual, enabled ? true : false);
}
case CV_CAP_PROP_AUTOFOCUS:
case CAP_PROP_AUTOFOCUS:
{
// Flags are required to toggle autofocus or not, but the setProperty interface does not support multiple parameters
bool enabled = cvRound(propVal) == 1;
@ -3528,7 +3533,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
return g_VI.setVideoSettingCamera(m_index, CameraControl_Focus, currentFocus, enabled ? CameraControl_Flags_Auto | CameraControl_Flags_Manual : CameraControl_Flags_Manual, enabled ? true : false);
}
case CV_CAP_PROP_CONVERT_RGB:
case CAP_PROP_CONVERT_RGB:
{
const bool convertRgb = cvRound(propVal) == 1;
const bool success = g_VI.setConvertRGB(m_index, convertRgb);
@ -3575,14 +3580,14 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
switch (propIdx)
{
case cv::VideoCaptureProperties::CAP_PROP_AUTO_WB:
case CV_CAP_PROP_AUTO_EXPOSURE:
case CAP_PROP_AUTO_EXPOSURE:
useDefaultValue = true;
if (cvRound(propVal) == 1)
flags = VideoProcAmp_Flags_Auto;
else
flags = VideoProcAmp_Flags_Manual;
break;
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
flags = VideoProcAmp_Flags_Manual;
break;
}
@ -3590,33 +3595,33 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
//video Filter properties
switch (propIdx)
{
case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_HUE:
case CV_CAP_PROP_SATURATION:
case CV_CAP_PROP_SHARPNESS:
case CV_CAP_PROP_GAMMA:
case CV_CAP_PROP_MONOCHROME:
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_BRIGHTNESS:
case CAP_PROP_CONTRAST:
case CAP_PROP_HUE:
case CAP_PROP_SATURATION:
case CAP_PROP_SHARPNESS:
case CAP_PROP_GAMMA:
case CAP_PROP_MONOCHROME:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
case cv::VideoCaptureProperties::CAP_PROP_AUTO_WB:
case CV_CAP_PROP_BACKLIGHT:
case CV_CAP_PROP_GAIN:
case CAP_PROP_BACKLIGHT:
case CAP_PROP_GAIN:
return g_VI.setVideoSettingFilter(m_index, g_VI.getVideoPropertyFromCV(propIdx), (long)propVal, flags, useDefaultValue);
}
//camera properties
switch (propIdx)
{
case CV_CAP_PROP_PAN:
case CV_CAP_PROP_TILT:
case CV_CAP_PROP_ROLL:
case CV_CAP_PROP_ZOOM:
case CV_CAP_PROP_EXPOSURE:
case CV_CAP_PROP_IRIS:
case CV_CAP_PROP_FOCUS:
case CAP_PROP_PAN:
case CAP_PROP_TILT:
case CAP_PROP_ROLL:
case CAP_PROP_ZOOM:
case CAP_PROP_EXPOSURE:
case CAP_PROP_IRIS:
case CAP_PROP_FOCUS:
return g_VI.setVideoSettingCamera(m_index, g_VI.getCameraPropertyFromCV(propIdx), (long)propVal);
// show video/camera filter dialog
case CV_CAP_PROP_SETTINGS:
case CAP_PROP_SETTINGS:
return g_VI.showSettingsWindow(m_index);
}
@ -3646,7 +3651,7 @@ bool VideoCapture_DShow::retrieveFrame(int, OutputArray frame)
}
int VideoCapture_DShow::getCaptureDomain()
{
return CV_CAP_DSHOW;
return CAP_DSHOW;
}
bool VideoCapture_DShow::isOpened() const
{

View File

@ -65,7 +65,7 @@
namespace cv {
namespace {
class CvCapture_FFMPEG_proxy CV_FINAL : public cv::IVideoCapture
class CvCapture_FFMPEG_proxy CV_FINAL : public cv::VideoCaptureBase
{
public:
CvCapture_FFMPEG_proxy() { ffmpegCapture = 0; }
@ -76,11 +76,11 @@ public:
}
virtual ~CvCapture_FFMPEG_proxy() { close(); }
virtual double getProperty(int propId) const CV_OVERRIDE
virtual double getProperty_(int propId) const CV_OVERRIDE
{
return ffmpegCapture ? icvGetCaptureProperty_FFMPEG_p(ffmpegCapture, propId) : 0;
}
virtual bool setProperty(int propId, double value) CV_OVERRIDE
virtual bool setProperty_(int propId, double value) CV_OVERRIDE
{
return ffmpegCapture ? icvSetCaptureProperty_FFMPEG_p(ffmpegCapture, propId, value)!=0 : false;
}
@ -88,7 +88,7 @@ public:
{
return ffmpegCapture ? icvGrabFrame_FFMPEG_p(ffmpegCapture)!=0 : false;
}
virtual bool retrieveFrame(int flag, cv::OutputArray frame) CV_OVERRIDE
virtual bool retrieveFrame_(int flag, cv::OutputArray frame) CV_OVERRIDE
{
unsigned char* data = 0;
int step=0, width=0, height=0, cn=0, depth=0;
@ -112,10 +112,7 @@ public:
return false;
}
cv::Mat tmp(height, width, CV_MAKETYPE(depth, cn), data, step);
applyMetadataRotation(*this, tmp);
tmp.copyTo(frame);
cv::Mat(height, width, CV_MAKETYPE(depth, cn), data, step).copyTo(frame);
return true;
}
bool open(const cv::String& filename, const cv::VideoCaptureParameters& params)
@ -134,7 +131,7 @@ public:
}
virtual bool isOpened() const CV_OVERRIDE { return ffmpegCapture != 0; }
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_FFMPEG; }
virtual int getCaptureDomain() CV_OVERRIDE { return cv::CAP_FFMPEG; }
protected:
CvCapture_FFMPEG* ffmpegCapture;

View File

@ -569,7 +569,6 @@ struct CvCapture_FFMPEG
int64_t frame_number, first_frame_number;
bool rotation_auto;
int rotation_angle; // valid 0, 90, 180, 270
double eps_zero;
/*
@ -634,11 +633,6 @@ void CvCapture_FFMPEG::init()
rotation_angle = 0;
#if (LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 92, 100))
rotation_auto = true;
#else
rotation_auto = false;
#endif
dict = NULL;
#if USE_AV_INTERRUPT_CALLBACK
@ -1808,9 +1802,9 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
case CAP_PROP_FRAME_COUNT:
return (double)get_total_frames();
case CAP_PROP_FRAME_WIDTH:
return (double)((rotation_auto && ((rotation_angle%180) != 0)) ? frame.height : frame.width);
return frame.width;
case CAP_PROP_FRAME_HEIGHT:
return (double)((rotation_auto && ((rotation_angle%180) != 0)) ? frame.width : frame.height);
return frame.height;
case CAP_PROP_FRAME_TYPE:
return (double)av_get_picture_type_char(picture->pict_type);
case CAP_PROP_FPS:
@ -1852,12 +1846,6 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
return static_cast<double>(get_bitrate());
case CAP_PROP_ORIENTATION_META:
return static_cast<double>(rotation_angle);
case CAP_PROP_ORIENTATION_AUTO:
#if LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)
return static_cast<double>(rotation_auto);
#else
return 0;
#endif
#if USE_AV_HW_CODECS
case CAP_PROP_HW_ACCELERATION:
return static_cast<double>(va_type);
@ -2077,14 +2065,6 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value )
case CAP_PROP_CONVERT_RGB:
convertRGB = (value != 0);
return true;
case CAP_PROP_ORIENTATION_AUTO:
#if LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100)
rotation_auto = value != 0 ? true : false;
return true;
#else
rotation_auto = false;
return false;
#endif
default:
return false;
}

View File

@ -102,8 +102,8 @@ public:
* and CAP_PROP_GPHOTO2_FLUSH_MSGS (will return pointer to char array).
* 6. Camera settings are fetched from device as lazy as possible.
* It creates problem with situation when change of one setting
* affects another setting. You can use CV_CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE
* or CV_CAP_PROP_GPHOTO2_RELOAD_CONFIG to be sure that property you are
* affects another setting. You can use CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE
* or CAP_PROP_GPHOTO2_RELOAD_CONFIG to be sure that property you are
* planning to get will be actual.
*
* Capture can work in 2 main modes: preview and final.
@ -111,22 +111,22 @@ public:
* Change modes with CAP_PROP_GPHOTO2_PREVIEW property.
*
* Moreover some generic properties are mapped to widgets, or implemented:
* * CV_CAP_PROP_SPEED,
* * CV_CAP_PROP_APERATURE,
* * CV_CAP_PROP_EXPOSUREPROGRAM,
* * CV_CAP_PROP_VIEWFINDER,
* * CV_CAP_PROP_POS_MSEC,
* * CV_CAP_PROP_POS_FRAMES,
* * CV_CAP_PROP_FRAME_WIDTH,
* * CV_CAP_PROP_FRAME_HEIGHT,
* * CV_CAP_PROP_FPS,
* * CV_CAP_PROP_FRAME_COUNT
* * CV_CAP_PROP_FORMAT,
* * CV_CAP_PROP_EXPOSURE,
* * CV_CAP_PROP_TRIGGER_DELAY,
* * CV_CAP_PROP_ZOOM,
* * CV_CAP_PROP_FOCUS,
* * CV_CAP_PROP_ISO_SPEED.
* * CAP_PROP_SPEED,
* * CAP_PROP_APERATURE,
* * CAP_PROP_EXPOSUREPROGRAM,
* * CAP_PROP_VIEWFINDER,
* * CAP_PROP_POS_MSEC,
* * CAP_PROP_POS_FRAMES,
* * CAP_PROP_FRAME_WIDTH,
* * CAP_PROP_FRAME_HEIGHT,
* * CAP_PROP_FPS,
* * CAP_PROP_FRAME_COUNT
* * CAP_PROP_FORMAT,
* * CAP_PROP_EXPOSURE,
* * CAP_PROP_TRIGGER_DELAY,
* * CAP_PROP_ZOOM,
* * CAP_PROP_FOCUS,
* * CAP_PROP_ISO_SPEED.
*/
class DigitalCameraCapture: public IVideoCapture
{
@ -144,7 +144,7 @@ public:
virtual bool setProperty(int, double) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
virtual bool retrieveFrame(int, OutputArray) CV_OVERRIDE;
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_GPHOTO2; }
virtual int getCaptureDomain() CV_OVERRIDE { return CAP_GPHOTO2; }
bool open(int index);
void close();
@ -216,10 +216,10 @@ private:
std::deque<CameraFile *> grabbedFrames;
// Properties
bool preview; // CV_CAP_PROP_GPHOTO2_PREVIEW
std::string widgetInfo; // CV_CAP_PROP_GPHOTO2_WIDGET_ENUMERATE
bool preview; // CAP_PROP_GPHOTO2_PREVIEW
std::string widgetInfo; // CAP_PROP_GPHOTO2_WIDGET_ENUMERATE
std::map<int, CameraWidget *> widgets;
bool reloadOnChange; // CV_CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE
bool reloadOnChange; // CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE
time_t firstCapturedFrameTime;
unsigned long int capturedFrames;
@ -232,9 +232,9 @@ private:
int collectWidgets(std::ostream &os, CameraWidget * widget);
// Messages / debug
mutable std::ostringstream msgsBuffer; // CV_CAP_PROP_GPHOTO2_FLUSH_MSGS
mutable std::string lastFlush; // CV_CAP_PROP_GPHOTO2_FLUSH_MSGS
bool collectMsgs; // CV_CAP_PROP_GPHOTO2_COLLECT_MSGS
mutable std::ostringstream msgsBuffer; // CAP_PROP_GPHOTO2_FLUSH_MSGS
mutable std::string lastFlush; // CAP_PROP_GPHOTO2_FLUSH_MSGS
bool collectMsgs; // CAP_PROP_GPHOTO2_COLLECT_MSGS
};
/**
@ -506,18 +506,18 @@ CameraWidget * DigitalCameraCapture::getGenericProperty(int propertyId,
{
switch (propertyId)
{
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
{
// Only seconds level precision, FUTURE: cross-platform milliseconds
output = (time(0) - firstCapturedFrameTime) * 1e2;
return NULL;
}
case CV_CAP_PROP_POS_FRAMES:
case CAP_PROP_POS_FRAMES:
{
output = capturedFrames;
return NULL;
}
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
{
if (!frame.empty())
{
@ -525,7 +525,7 @@ CameraWidget * DigitalCameraCapture::getGenericProperty(int propertyId,
}
return NULL;
}
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
{
if (!frame.empty())
{
@ -533,7 +533,7 @@ CameraWidget * DigitalCameraCapture::getGenericProperty(int propertyId,
}
return NULL;
}
case CV_CAP_PROP_FORMAT:
case CAP_PROP_FORMAT:
{
if (!frame.empty())
{
@ -541,39 +541,39 @@ CameraWidget * DigitalCameraCapture::getGenericProperty(int propertyId,
}
return NULL;
}
case CV_CAP_PROP_FPS: // returns average fps from the begin
case CAP_PROP_FPS: // returns average fps from the begin
{
double wholeProcessTime = 0;
getGenericProperty(CV_CAP_PROP_POS_MSEC, wholeProcessTime);
getGenericProperty(CAP_PROP_POS_MSEC, wholeProcessTime);
wholeProcessTime /= 1e2;
output = capturedFrames / wholeProcessTime;
return NULL;
}
case CV_CAP_PROP_FRAME_COUNT:
case CAP_PROP_FRAME_COUNT:
{
output = capturedFrames;
return NULL;
}
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
return findWidgetByName(PROP_EXPOSURE_COMPENSACTION);
case CV_CAP_PROP_TRIGGER_DELAY:
case CAP_PROP_TRIGGER_DELAY:
return findWidgetByName(PROP_SELF_TIMER_DELAY);
case CV_CAP_PROP_ZOOM:
case CAP_PROP_ZOOM:
return findWidgetByName(PROP_MANUALFOCUS);
case CV_CAP_PROP_FOCUS:
case CAP_PROP_FOCUS:
return findWidgetByName(PROP_AUTOFOCUS);
case CV_CAP_PROP_ISO_SPEED:
case CAP_PROP_ISO_SPEED:
return findWidgetByName(PROP_ISO);
case CV_CAP_PROP_SPEED:
case CAP_PROP_SPEED:
return findWidgetByName(PROP_SPEED);
case CV_CAP_PROP_APERTURE:
case CAP_PROP_APERTURE:
{
CameraWidget * widget = findWidgetByName(PROP_APERTURE_NIKON);
return (widget == 0) ? findWidgetByName(PROP_APERTURE_CANON) : widget;
}
case CV_CAP_PROP_EXPOSUREPROGRAM:
case CAP_PROP_EXPOSUREPROGRAM:
return findWidgetByName(PROP_EXPOSURE_PROGRAM);
case CV_CAP_PROP_VIEWFINDER:
case CAP_PROP_VIEWFINDER:
return findWidgetByName(PROP_VIEWFINDER);
}
return NULL;
@ -596,19 +596,19 @@ double DigitalCameraCapture::getProperty(int propertyId) const
switch (propertyId)
{
// gphoto2 cap featured
case CV_CAP_PROP_GPHOTO2_PREVIEW:
case CAP_PROP_GPHOTO2_PREVIEW:
return preview;
case CV_CAP_PROP_GPHOTO2_WIDGET_ENUMERATE:
case CAP_PROP_GPHOTO2_WIDGET_ENUMERATE:
if (rootWidget == NULL)
return 0;
return (intptr_t) widgetInfo.c_str();
case CV_CAP_PROP_GPHOTO2_RELOAD_CONFIG:
case CAP_PROP_GPHOTO2_RELOAD_CONFIG:
return 0; // Trigger, only by set
case CV_CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE:
case CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE:
return reloadOnChange;
case CV_CAP_PROP_GPHOTO2_COLLECT_MSGS:
case CAP_PROP_GPHOTO2_COLLECT_MSGS:
return collectMsgs;
case CV_CAP_PROP_GPHOTO2_FLUSH_MSGS:
case CAP_PROP_GPHOTO2_FLUSH_MSGS:
lastFlush = msgsBuffer.str();
msgsBuffer.str("");
msgsBuffer.clear();
@ -682,35 +682,35 @@ CameraWidget * DigitalCameraCapture::setGenericProperty(int propertyId,
{
switch (propertyId)
{
case CV_CAP_PROP_POS_MSEC:
case CV_CAP_PROP_POS_FRAMES:
case CV_CAP_PROP_FRAME_WIDTH:
case CV_CAP_PROP_FRAME_HEIGHT:
case CV_CAP_PROP_FPS:
case CV_CAP_PROP_FRAME_COUNT:
case CV_CAP_PROP_FORMAT:
case CAP_PROP_POS_MSEC:
case CAP_PROP_POS_FRAMES:
case CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FPS:
case CAP_PROP_FRAME_COUNT:
case CAP_PROP_FORMAT:
output = false;
return NULL;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
return findWidgetByName(PROP_EXPOSURE_COMPENSACTION);
case CV_CAP_PROP_TRIGGER_DELAY:
case CAP_PROP_TRIGGER_DELAY:
return findWidgetByName(PROP_SELF_TIMER_DELAY);
case CV_CAP_PROP_ZOOM:
case CAP_PROP_ZOOM:
return findWidgetByName(PROP_MANUALFOCUS);
case CV_CAP_PROP_FOCUS:
case CAP_PROP_FOCUS:
return findWidgetByName(PROP_AUTOFOCUS);
case CV_CAP_PROP_ISO_SPEED:
case CAP_PROP_ISO_SPEED:
return findWidgetByName(PROP_ISO);
case CV_CAP_PROP_SPEED:
case CAP_PROP_SPEED:
return findWidgetByName(PROP_SPEED);
case CV_CAP_PROP_APERTURE:
case CAP_PROP_APERTURE:
{
CameraWidget * widget = findWidgetByName(PROP_APERTURE_NIKON);
return (widget == NULL) ? findWidgetByName(PROP_APERTURE_CANON) : widget;
}
case CV_CAP_PROP_EXPOSUREPROGRAM:
case CAP_PROP_EXPOSUREPROGRAM:
return findWidgetByName(PROP_EXPOSURE_PROGRAM);
case CV_CAP_PROP_VIEWFINDER:
case CAP_PROP_VIEWFINDER:
return findWidgetByName(PROP_VIEWFINDER);
}
return NULL;
@ -733,21 +733,21 @@ bool DigitalCameraCapture::setProperty(int propertyId, double value)
switch (propertyId)
{
// gphoto2 cap featured
case CV_CAP_PROP_GPHOTO2_PREVIEW:
case CAP_PROP_GPHOTO2_PREVIEW:
preview = value != 0;
return true;
case CV_CAP_PROP_GPHOTO2_WIDGET_ENUMERATE:
case CAP_PROP_GPHOTO2_WIDGET_ENUMERATE:
return false;
case CV_CAP_PROP_GPHOTO2_RELOAD_CONFIG:
case CAP_PROP_GPHOTO2_RELOAD_CONFIG:
reloadConfig();
return true;
case CV_CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE:
case CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE:
reloadOnChange = value != 0;
return true;
case CV_CAP_PROP_GPHOTO2_COLLECT_MSGS:
case CAP_PROP_GPHOTO2_COLLECT_MSGS:
collectMsgs = value != 0;
return true;
case CV_CAP_PROP_GPHOTO2_FLUSH_MSGS:
case CAP_PROP_GPHOTO2_FLUSH_MSGS:
return false;
default:
widget = setGenericProperty(propertyId, value, output);
@ -1002,7 +1002,7 @@ void DigitalCameraCapture::readFrameFromFile(CameraFile * file, OutputArray outp
CR(gp_file_get_data_and_size(file, &data, &size));
if (size > 0)
{
Mat buf = Mat(1, size, CV_8UC1, (void *) data);
Mat buf(1, size, CV_8UC1, (void *) data);
if(!buf.empty())
{
frame = imdecode(buf, IMREAD_UNCHANGED);

View File

@ -287,10 +287,10 @@ std::string get_gst_propname(int propId)
{
switch (propId)
{
case CV_CAP_PROP_BRIGHTNESS: return "brightness";
case CV_CAP_PROP_CONTRAST: return "contrast";
case CV_CAP_PROP_SATURATION: return "saturation";
case CV_CAP_PROP_HUE: return "hue";
case CAP_PROP_BRIGHTNESS: return "brightness";
case CAP_PROP_CONTRAST: return "contrast";
case CAP_PROP_SATURATION: return "saturation";
case CAP_PROP_HUE: return "hue";
default: return std::string();
}
}
@ -1115,14 +1115,14 @@ bool GStreamerCapture::retrieveVideoFrame(int, OutputArray dst)
else if (name == "video/x-bayer")
{
CV_CheckEQ((int)n_planes, 0, "");
Mat src = Mat(sz, CV_8UC1, frame.map[0].data);
Mat src(sz, CV_8UC1, frame.map[0].data);
src.copyTo(dst);
return true;
}
else if (name == "image/jpeg")
{
CV_CheckEQ((int)n_planes, 0, "");
Mat src = Mat(Size(frame.map[0].size, 1), CV_8UC1, frame.map[0].data);
Mat src(Size(frame.map[0].size, 1), CV_8UC1, frame.map[0].data);
src.copyTo(dst);
return true;
}
@ -1326,7 +1326,7 @@ void GStreamerCapture::newPad(GstElement *, GstPad *pad, gpointer data)
/*!
* \brief Create GStreamer pipeline
* \param filename Filename to open in case of CV_CAP_GSTREAMER_FILE
* \param filename Filename to open in case of CAP_GSTREAMER_FILE
* \return boolean. Specifies if opening was successful.
*
* In case of camera 'index', a pipeline is constructed as follows:
@ -1862,9 +1862,9 @@ double GStreamerCapture::getProperty(int propId) const
switch(propId)
{
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
return double(timestamp) / GST_MSECOND;
case CV_CAP_PROP_POS_FRAMES:
case CAP_PROP_POS_FRAMES:
if (!isPosFramesSupported)
{
if (isPosFramesEmulated)
@ -1879,7 +1879,7 @@ double GStreamerCapture::getProperty(int propId) const
return 0;
}
return value;
case CV_CAP_PROP_POS_AVI_RATIO:
case CAP_PROP_POS_AVI_RATIO:
format = GST_FORMAT_PERCENT;
status = gst_element_query_position(sink.get(), CV_GST_FORMAT(format), &value);
if(!status) {
@ -1888,18 +1888,18 @@ double GStreamerCapture::getProperty(int propId) const
return 0;
}
return ((double) value) / GST_FORMAT_PERCENT_MAX;
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return width;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return height;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
return fps;
case CV_CAP_PROP_FRAME_COUNT:
case CAP_PROP_FRAME_COUNT:
return (double)duration;
case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_SATURATION:
case CV_CAP_PROP_HUE:
case CAP_PROP_BRIGHTNESS:
case CAP_PROP_CONTRAST:
case CAP_PROP_SATURATION:
case CAP_PROP_HUE:
if (v4l2src)
{
std::string propName = get_gst_propname(propId);
@ -1915,7 +1915,7 @@ double GStreamerCapture::getProperty(int propId) const
return static_cast<double>(va_type);
case CAP_PROP_HW_DEVICE:
return static_cast<double>(hw_device);
case CV_CAP_GSTREAMER_QUEUE_LENGTH:
case CAP_PROP_GSTREAMER_QUEUE_LENGTH:
if(!sink)
{
CV_WARN("there is no sink yet");
@ -1972,14 +1972,14 @@ bool GStreamerCapture::setProperty(int propId, double value)
return false;
}
bool needRestart = this->isPipelinePlaying() && (propId == CV_CAP_PROP_FRAME_WIDTH || propId == CV_CAP_PROP_FRAME_HEIGHT || propId == CV_CAP_PROP_FPS);
bool needRestart = this->isPipelinePlaying() && (propId == CAP_PROP_FRAME_WIDTH || propId == CAP_PROP_FRAME_HEIGHT || propId == CAP_PROP_FPS);
if (needRestart) {
this->stopPipeline();
}
switch(propId)
{
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
{
if(!gst_element_seek_simple(GST_ELEMENT(pipeline.get()), GST_FORMAT_TIME,
flags, (gint64) (value * GST_MSECOND))) {
@ -2006,7 +2006,7 @@ bool GStreamerCapture::setProperty(int propId, double value)
}
return true;
}
case CV_CAP_PROP_POS_FRAMES:
case CAP_PROP_POS_FRAMES:
{
if (!isPosFramesSupported)
{
@ -2037,7 +2037,7 @@ bool GStreamerCapture::setProperty(int propId, double value)
gst_element_get_state(pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
return true;
}
case CV_CAP_PROP_POS_AVI_RATIO:
case CAP_PROP_POS_AVI_RATIO:
{
// https://stackoverflow.com/questions/31290315
// GStreamer docs: GST_FORMAT_PERCENT (5) percentage of stream (few, if any, elements implement this as of May 2009)
@ -2065,19 +2065,19 @@ bool GStreamerCapture::setProperty(int propId, double value)
}
return true;
}
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
if(value > 0)
setFilter("width", G_TYPE_INT, (int) value, 0);
else
removeFilter("width");
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
if(value > 0)
setFilter("height", G_TYPE_INT, (int) value, 0);
else
removeFilter("height");
break;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
if(value > 0) {
int num = 0, denom = 1;
toFraction(value, num, denom);
@ -2085,10 +2085,10 @@ bool GStreamerCapture::setProperty(int propId, double value)
} else
removeFilter("framerate");
break;
case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_SATURATION:
case CV_CAP_PROP_HUE:
case CAP_PROP_BRIGHTNESS:
case CAP_PROP_CONTRAST:
case CAP_PROP_SATURATION:
case CAP_PROP_HUE:
if (v4l2src)
{
std::string propName = get_gst_propname(propId);
@ -2100,14 +2100,14 @@ bool GStreamerCapture::setProperty(int propId, double value)
}
}
return false;
case CV_CAP_PROP_GAIN:
case CV_CAP_PROP_CONVERT_RGB:
case CAP_PROP_GAIN:
case CAP_PROP_CONVERT_RGB:
break;
case cv::CAP_PROP_HW_ACCELERATION:
return false; // open-only
case cv::CAP_PROP_HW_DEVICE:
return false; // open-only
case CV_CAP_GSTREAMER_QUEUE_LENGTH:
case CAP_PROP_GSTREAMER_QUEUE_LENGTH:
{
if(!sink)
{
@ -2182,7 +2182,7 @@ Ptr<IVideoCapture> createGStreamerCapture_cam(int index, const cv::VideoCaptureP
* \brief The CvVideoWriter_GStreamer class
* Use GStreamer to write video
*/
class CvVideoWriter_GStreamer : public CvVideoWriter
class CvVideoWriter_GStreamer : public IVideoWriter
{
public:
CvVideoWriter_GStreamer()
@ -2212,11 +2212,12 @@ public:
bool open(const std::string &filename, int fourcc,
double fps, const Size &frameSize, const VideoWriterParameters& params );
void close();
bool writeFrame( const IplImage* image ) CV_OVERRIDE;
void write(InputArray) CV_OVERRIDE;
int getIplDepth() const { return ipl_depth; }
virtual double getProperty(int) const CV_OVERRIDE;
double getProperty(int) const CV_OVERRIDE;
bool isOpened() const CV_OVERRIDE { return pipeline && source; }
protected:
const char* filenameToMimetype(const char* filename);
@ -2540,7 +2541,7 @@ bool CvVideoWriter_GStreamer::open( const std::string &filename, int fourcc,
if (fourcc == CV_FOURCC('M','J','P','G') && frameSize.height == 1)
{
CV_Assert(depth == CV_8U);
ipl_depth = IPL_DEPTH_8U;
ipl_depth = CV_8U;
input_pix_fmt = GST_VIDEO_FORMAT_ENCODED;
caps.attach(gst_caps_new_simple("image/jpeg",
"framerate", GST_TYPE_FRACTION, int(fps_num), int(fps_denom),
@ -2550,7 +2551,7 @@ bool CvVideoWriter_GStreamer::open( const std::string &filename, int fourcc,
else if (is_color)
{
CV_Assert(depth == CV_8U);
ipl_depth = IPL_DEPTH_8U;
ipl_depth = CV_8U;
input_pix_fmt = GST_VIDEO_FORMAT_BGR;
bufsize = frameSize.width * frameSize.height * 3;
@ -2566,7 +2567,7 @@ bool CvVideoWriter_GStreamer::open( const std::string &filename, int fourcc,
}
else if (!is_color && depth == CV_8U)
{
ipl_depth = IPL_DEPTH_8U;
ipl_depth = CV_8U;
input_pix_fmt = GST_VIDEO_FORMAT_GRAY8;
bufsize = frameSize.width * frameSize.height;
@ -2580,7 +2581,7 @@ bool CvVideoWriter_GStreamer::open( const std::string &filename, int fourcc,
}
else if (!is_color && depth == CV_16U)
{
ipl_depth = IPL_DEPTH_16U;
ipl_depth = CV_16U;
input_pix_fmt = GST_VIDEO_FORMAT_GRAY16_LE;
bufsize = frameSize.width * frameSize.height * 2;
@ -2670,53 +2671,53 @@ bool CvVideoWriter_GStreamer::open( const std::string &filename, int fourcc,
* The timestamp for the buffer is generated from the framerate set in open
* and ensures a smooth video
*/
bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
void CvVideoWriter_GStreamer::write(InputArray image)
{
GstClockTime duration, timestamp;
GstFlowReturn ret;
int size;
handleMessage(pipeline);
if (input_pix_fmt == GST_VIDEO_FORMAT_ENCODED) {
if (image->nChannels != 1 || image->depth != IPL_DEPTH_8U || image->height != 1) {
CV_WARN("cvWriteFrame() needs images with depth = IPL_DEPTH_8U, nChannels = 1 and height = 1.");
return false;
if (image.type() != CV_8UC1 || image.size().height != 1) {
CV_WARN("write frame skipped - expected CV_8UC1, height==1");
return;
}
}
else
if(input_pix_fmt == GST_VIDEO_FORMAT_BGR) {
if (image->nChannels != 3 || image->depth != IPL_DEPTH_8U) {
CV_WARN("cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 3.");
return false;
if (image.type() != CV_8UC3) {
CV_WARN("write frame skipped - expected CV_8UC3");
return;
}
}
else if (input_pix_fmt == GST_VIDEO_FORMAT_GRAY8) {
if (image->nChannels != 1 || image->depth != IPL_DEPTH_8U) {
CV_WARN("cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1.");
return false;
if (image.type() != CV_8UC1) {
CV_WARN("write frame skipped - expected CV_8UC1");
return;
}
}
else if (input_pix_fmt == GST_VIDEO_FORMAT_GRAY16_LE) {
if (image->nChannels != 1 || image->depth != IPL_DEPTH_16U) {
CV_WARN("cvWriteFrame() needs images with depth = IPL_DEPTH_16U and nChannels = 1.");
return false;
if (image.type() != CV_16UC1) {
CV_WARN("write frame skipped - expected CV_16UC3");
return;
}
}
else {
CV_WARN("cvWriteFrame() needs BGR or grayscale images\n");
return false;
CV_WARN("write frame skipped - unsupported format");
return;
}
size = image->imageSize;
Mat imageMat = image.getMat();
const size_t buf_size = imageMat.total() * imageMat.elemSize();
duration = ((double)1/framerate) * GST_SECOND;
timestamp = num_frames * duration;
//gst_app_src_push_buffer takes ownership of the buffer, so we need to supply it a copy
GstBuffer *buffer = gst_buffer_new_allocate(NULL, size, NULL);
GstBuffer *buffer = gst_buffer_new_allocate(NULL, buf_size, NULL);
GstMapInfo info;
gst_buffer_map(buffer, &info, (GstMapFlags)GST_MAP_READ);
memcpy(info.data, (guint8*)image->imageData, size);
memcpy(info.data, (guint8*)imageMat.data, buf_size);
gst_buffer_unmap(buffer, &info);
GST_BUFFER_DURATION(buffer) = duration;
GST_BUFFER_PTS(buffer) = timestamp;
@ -2728,14 +2729,12 @@ bool CvVideoWriter_GStreamer::writeFrame( const IplImage * image )
if (ret != GST_FLOW_OK)
{
CV_WARN("Error pushing buffer to GStreamer pipeline");
return false;
return;
}
//GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");
++num_frames;
return true;
}
@ -2755,18 +2754,9 @@ double CvVideoWriter_GStreamer::getProperty(int propId) const
Ptr<IVideoWriter> create_GStreamer_writer(const std::string& filename, int fourcc, double fps,
const cv::Size& frameSize, const VideoWriterParameters& params)
{
CvVideoWriter_GStreamer* wrt = new CvVideoWriter_GStreamer;
try
{
if (wrt->open(filename, fourcc, fps, frameSize, params))
return makePtr<LegacyWriter>(wrt);
delete wrt;
}
catch (...)
{
delete wrt;
throw;
}
Ptr<CvVideoWriter_GStreamer> ret = makePtr<CvVideoWriter_GStreamer>();
if (ret->open(filename, fourcc, fps, frameSize, params))
return ret;
return 0;
}
@ -3030,7 +3020,7 @@ CvResult CV_API_CALL cv_writer_open_with_params(
CvVideoWriter_GStreamer* wrt = 0;
try
{
CvSize sz = { width, height };
cv::Size sz { width, height };
VideoWriterParameters parameters(params, n_params);
wrt = new CvVideoWriter_GStreamer();
if (wrt && wrt->open(filename, fourcc, fps, sz, parameters))
@ -3104,11 +3094,11 @@ CvResult CV_API_CALL cv_writer_write(CvPluginWriter handle, const unsigned char
try
{
CvVideoWriter_GStreamer* instance = (CvVideoWriter_GStreamer*)handle;
CvSize sz = { width, height };
IplImage img;
cvInitImageHeader(&img, sz, instance->getIplDepth(), cn);
cvSetData(&img, const_cast<unsigned char*>(data), step);
return instance->writeFrame(&img) ? CV_ERROR_OK : CV_ERROR_FAIL;
const cv::Size sz = { width, height };
const int image_type = CV_MAKE_TYPE(instance->getIplDepth(), cn);
cv::Mat img(sz, image_type, (void*)data, step);
instance->write(img);
return CV_ERROR_OK;
}
catch (const std::exception& e)
{

View File

@ -151,23 +151,23 @@ double CvCapture_Images::getProperty(int id) const
{
switch(id)
{
case CV_CAP_PROP_POS_MSEC:
case cv::CAP_PROP_POS_MSEC:
CV_WARN("collections of images don't have framerates");
return 0;
case CV_CAP_PROP_POS_FRAMES:
case cv::CAP_PROP_POS_FRAMES:
return currentframe;
case CV_CAP_PROP_FRAME_COUNT:
case cv::CAP_PROP_FRAME_COUNT:
return length;
case CV_CAP_PROP_POS_AVI_RATIO:
case cv::CAP_PROP_POS_AVI_RATIO:
return (double)currentframe / (double)(length - 1);
case CV_CAP_PROP_FRAME_WIDTH:
case cv::CAP_PROP_FRAME_WIDTH:
return frame.cols;
case CV_CAP_PROP_FRAME_HEIGHT:
case cv::CAP_PROP_FRAME_HEIGHT:
return frame.rows;
case CV_CAP_PROP_FPS:
case cv::CAP_PROP_FPS:
CV_WARN("collections of images don't have framerates");
return 1;
case CV_CAP_PROP_FOURCC:
case cv::CAP_PROP_FOURCC:
CV_WARN("collections of images don't have 4-character codes");
return 0;
}
@ -178,8 +178,8 @@ bool CvCapture_Images::setProperty(int id, double value)
{
switch(id)
{
case CV_CAP_PROP_POS_MSEC:
case CV_CAP_PROP_POS_FRAMES:
case cv::CAP_PROP_POS_MSEC:
case cv::CAP_PROP_POS_FRAMES:
if(value < 0) {
CV_WARN("seeking to negative positions does not work - clamping");
value = 0;
@ -192,7 +192,7 @@ bool CvCapture_Images::setProperty(int id, double value)
if (currentframe != 0)
grabbedInOpen = false; // grabbed frame is not valid anymore
return true;
case CV_CAP_PROP_POS_AVI_RATIO:
case cv::CAP_PROP_POS_AVI_RATIO:
if(value > 1) {
CV_WARN("seeking beyond end of sequence - clamping");
value = 1;
@ -372,21 +372,17 @@ Ptr<IVideoCapture> create_Images_capture(const std::string &filename)
// image sequence writer
//
//
class CvVideoWriter_Images CV_FINAL : public CvVideoWriter
class CvVideoWriter_Images CV_FINAL : public IVideoWriter
{
public:
CvVideoWriter_Images()
{
filename_pattern.clear();
currentframe = 0;
}
virtual ~CvVideoWriter_Images() { close(); }
virtual bool open( const char* _filename );
virtual void close();
virtual bool setProperty( int, double ); // FIXIT doesn't work: IVideoWriter interface only!
virtual bool writeFrame( const IplImage* ) CV_OVERRIDE;
CvVideoWriter_Images(const std::string & _filename);
void close();
~CvVideoWriter_Images() CV_OVERRIDE { close(); }
double getProperty(int) const CV_OVERRIDE { return 0; }
bool setProperty( int, double ) CV_OVERRIDE; // FIXIT doesn't work: IVideoWriter interface only!
bool isOpened() const CV_OVERRIDE { return !filename_pattern.empty(); }
void write( InputArray ) CV_OVERRIDE;
int getCaptureDomain() const CV_OVERRIDE { return cv::CAP_IMAGES; }
protected:
std::string filename_pattern;
@ -394,7 +390,7 @@ protected:
std::vector<int> params;
};
bool CvVideoWriter_Images::writeFrame( const IplImage* image )
void CvVideoWriter_Images::write(InputArray image)
{
CV_Assert(!filename_pattern.empty());
cv::String filename = cv::format(filename_pattern.c_str(), (int)currentframe);
@ -404,12 +400,9 @@ bool CvVideoWriter_Images::writeFrame( const IplImage* image )
image_params.push_back(0); // append parameters 'stop' mark
image_params.push_back(0);
cv::Mat img = cv::cvarrToMat(image);
bool ret = cv::imwrite(filename, img, image_params);
cv::Mat img = image.getMat();
cv::imwrite(filename, img, image_params);
currentframe++;
return ret;
}
void CvVideoWriter_Images::close()
@ -420,12 +413,11 @@ void CvVideoWriter_Images::close()
}
bool CvVideoWriter_Images::open( const char* _filename )
CvVideoWriter_Images::CvVideoWriter_Images(const std::string & _filename)
{
unsigned offset = 0;
close();
CV_Assert(_filename);
filename_pattern = icvExtractPattern(_filename, &offset);
CV_Assert(!filename_pattern.empty());
@ -433,12 +425,10 @@ bool CvVideoWriter_Images::open( const char* _filename )
if (!cv::haveImageWriter(filename))
{
close();
return false;
}
currentframe = offset;
params.clear();
return true;
}
@ -454,23 +444,9 @@ bool CvVideoWriter_Images::setProperty( int id, double value )
}
Ptr<IVideoWriter> create_Images_writer(const std::string &filename, int, double, const Size &,
const cv::VideoWriterParameters&)
const cv::VideoWriterParameters&)
{
CvVideoWriter_Images *writer = new CvVideoWriter_Images;
try
{
if( writer->open( filename.c_str() ))
return makePtr<LegacyWriter>(writer);
delete writer;
}
catch (...)
{
delete writer;
throw;
}
return 0;
return makePtr<CvVideoWriter_Images>(filename);
}
} // cv::

View File

@ -241,85 +241,31 @@ public:
};
} // namespace
//===================================================
// Utility
static inline void applyMetadataRotation(const IVideoCapture& cap, OutputArray mat)
// Advanced base class for VideoCapture backends providing some extra functionality
class VideoCaptureBase : public IVideoCapture
{
bool rotation_auto = 0 != cap.getProperty(CAP_PROP_ORIENTATION_AUTO);
int rotation_angle = static_cast<int>(cap.getProperty(CAP_PROP_ORIENTATION_META));
if(!rotation_auto || rotation_angle%360 == 0)
{
return;
}
cv::RotateFlags flag;
if(rotation_angle == 90 || rotation_angle == -270) { // Rotate clockwise 90 degrees
flag = cv::ROTATE_90_CLOCKWISE;
} else if(rotation_angle == 270 || rotation_angle == -90) { // Rotate clockwise 270 degrees
flag = cv::ROTATE_90_COUNTERCLOCKWISE;
} else if(rotation_angle == 180 || rotation_angle == -180) { // Rotate clockwise 180 degrees
flag = cv::ROTATE_180;
} else { // Unsupported rotation
return;
}
cv::rotate(mat, mat, flag);
}
//===================================================
// Wrapper
class LegacyCapture : public IVideoCapture
{
private:
CvCapture * cap;
bool autorotate;
LegacyCapture(const LegacyCapture &);
LegacyCapture& operator=(const LegacyCapture &);
bool shouldSwapWidthHeight() const
{
if (!autorotate)
return false;
int rotation = static_cast<int>(cap->getProperty(cv::CAP_PROP_ORIENTATION_META));
return std::abs(rotation % 180) == 90;
}
public:
LegacyCapture(CvCapture * cap_) : cap(cap_), autorotate(true) {}
~LegacyCapture()
{
cvReleaseCapture(&cap);
}
VideoCaptureBase() : autorotate(false) {}
double getProperty(int propId) const CV_OVERRIDE
{
if (!cap)
return 0;
switch(propId)
{
case cv::CAP_PROP_ORIENTATION_AUTO:
return static_cast<double>(autorotate);
case cv::CAP_PROP_FRAME_WIDTH:
return shouldSwapWidthHeight() ? cap->getProperty(cv::CAP_PROP_FRAME_HEIGHT) : cap->getProperty(cv::CAP_PROP_FRAME_WIDTH);
return shouldSwapWidthHeight() ? getProperty_(cv::CAP_PROP_FRAME_HEIGHT) : getProperty_(cv::CAP_PROP_FRAME_WIDTH);
case cv::CAP_PROP_FRAME_HEIGHT:
return shouldSwapWidthHeight() ? cap->getProperty(cv::CAP_PROP_FRAME_WIDTH) : cap->getProperty(cv::CAP_PROP_FRAME_HEIGHT);
return shouldSwapWidthHeight() ? getProperty_(cv::CAP_PROP_FRAME_WIDTH) : getProperty_(cv::CAP_PROP_FRAME_HEIGHT);
default:
return cap->getProperty(propId);
return getProperty_(propId);
}
}
bool setProperty(int propId, double value) CV_OVERRIDE
{
if (!cap)
return false;
switch(propId)
{
case cv::CAP_PROP_ORIENTATION_AUTO:
@ -327,84 +273,55 @@ public:
return true;
default:
return cvSetCaptureProperty(cap, propId, value) != 0;
return setProperty_(propId, value);
}
}
bool grabFrame() CV_OVERRIDE
{
return cap ? cvGrabFrame(cap) != 0 : false;
}
bool retrieveFrame(int channel, OutputArray image) CV_OVERRIDE
{
IplImage* _img = cvRetrieveFrame(cap, channel);
if( !_img )
{
image.release();
const bool res = retrieveFrame_(channel, image);
if (res)
applyMetadataRotation(image);
return res;
}
protected:
virtual double getProperty_(int) const = 0;
virtual bool setProperty_(int, double) = 0;
virtual bool retrieveFrame_(int, OutputArray) = 0;
protected:
bool shouldSwapWidthHeight() const
{
if (!autorotate)
return false;
}
if(_img->origin == IPL_ORIGIN_TL)
{
cv::cvarrToMat(_img).copyTo(image);
}
else
{
Mat temp = cv::cvarrToMat(_img);
flip(temp, image, 0);
}
applyMetadataRotation(*this, image);
return true;
int rotation = static_cast<int>(getProperty(cv::CAP_PROP_ORIENTATION_META));
return std::abs(rotation % 180) == 90;
}
bool isOpened() const CV_OVERRIDE
void applyMetadataRotation(OutputArray mat) const
{
return cap != 0; // legacy interface doesn't support closed files
}
int getCaptureDomain() CV_OVERRIDE
{
return cap ? cap->getCaptureDomain() : 0;
bool rotation_auto = 0 != getProperty(CAP_PROP_ORIENTATION_AUTO);
int rotation_angle = static_cast<int>(getProperty(CAP_PROP_ORIENTATION_META));
if(!rotation_auto || rotation_angle%360 == 0)
{
return;
}
cv::RotateFlags flag;
if(rotation_angle == 90 || rotation_angle == -270) { // Rotate clockwise 90 degrees
flag = cv::ROTATE_90_CLOCKWISE;
} else if(rotation_angle == 270 || rotation_angle == -90) { // Rotate clockwise 270 degrees
flag = cv::ROTATE_90_COUNTERCLOCKWISE;
} else if(rotation_angle == 180 || rotation_angle == -180) { // Rotate clockwise 180 degrees
flag = cv::ROTATE_180;
} else { // Unsupported rotation
return;
}
cv::rotate(mat, mat, flag);
}
CvCapture* getCvCapture() const { return cap; }
protected:
bool autorotate;
};
class LegacyWriter : public IVideoWriter
{
private:
CvVideoWriter * writer;
LegacyWriter(const LegacyWriter &);
LegacyWriter& operator=(const LegacyWriter &);
public:
LegacyWriter(CvVideoWriter * wri_) : writer(wri_)
{}
~LegacyWriter()
{
cvReleaseVideoWriter(&writer);
}
double getProperty(int propId) const CV_OVERRIDE
{
if (writer)
{
return writer->getProperty(propId);
}
return 0.;
}
bool setProperty(int, double) CV_OVERRIDE
{
return false;
}
bool isOpened() const CV_OVERRIDE
{
return writer != NULL;
}
void write(InputArray image) CV_OVERRIDE
{
IplImage _img = cvIplImage(image.getMat());
cvWriteFrame(writer, &_img);
}
int getCaptureDomain() const CV_OVERRIDE
{
return writer ? writer->getCaptureDomain() : 0;
}
};
//==================================================================================================

View File

@ -758,7 +758,7 @@ public:
bool retrieveVideoFrame(OutputArray);
virtual bool retrieveFrame(int, cv::OutputArray) CV_OVERRIDE;
virtual bool isOpened() const CV_OVERRIDE { return isOpen; }
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_MSMF; }
virtual int getCaptureDomain() CV_OVERRIDE { return CAP_MSMF; }
protected:
bool configureOutput();
bool configureAudioOutput(MediaType newType);
@ -2080,131 +2080,131 @@ double CvCapture_MSMF::getProperty( int property_id ) const
if (isOpen)
switch (property_id)
{
case CV_CAP_PROP_MODE:
case CAP_PROP_MODE:
return captureMode;
case cv::CAP_PROP_HW_DEVICE:
return hwDeviceIndex;
case cv::CAP_PROP_HW_ACCELERATION:
return static_cast<double>(va_type);
case CV_CAP_PROP_CONVERT_RGB:
case CAP_PROP_CONVERT_RGB:
return convertFormat ? 1 : 0;
case CV_CAP_PROP_SAR_NUM:
case CAP_PROP_SAR_NUM:
return captureVideoFormat.aspectRatioNum;
case CV_CAP_PROP_SAR_DEN:
case CAP_PROP_SAR_DEN:
return captureVideoFormat.aspectRatioDenom;
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
return captureVideoFormat.width;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
return captureVideoFormat.height;
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
return captureVideoFormat.subType.Data1;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
return captureVideoFormat.getFramerate();
case CV_CAP_PROP_FRAME_COUNT:
case CAP_PROP_FRAME_COUNT:
if (duration != 0)
return floor(((double)duration / 1e7)* captureVideoFormat.getFramerate() + 0.5);
else
break;
case CV_CAP_PROP_POS_FRAMES:
case CAP_PROP_POS_FRAMES:
return (double)nFrame;
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
return (double)usedVideoSampleTime / 1e4;
case CAP_PROP_AUDIO_POS:
return (double)audioSamplePos;
case CV_CAP_PROP_POS_AVI_RATIO:
case CAP_PROP_POS_AVI_RATIO:
if (duration != 0)
return (double)usedVideoSampleTime / duration;
else
break;
case CV_CAP_PROP_BRIGHTNESS:
case CAP_PROP_BRIGHTNESS:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Brightness, cVal))
return cVal;
break;
case CV_CAP_PROP_CONTRAST:
case CAP_PROP_CONTRAST:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Contrast, cVal))
return cVal;
break;
case CV_CAP_PROP_SATURATION:
case CAP_PROP_SATURATION:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Saturation, cVal))
return cVal;
break;
case CV_CAP_PROP_HUE:
case CAP_PROP_HUE:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Hue, cVal))
return cVal;
break;
case CV_CAP_PROP_GAIN:
case CAP_PROP_GAIN:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Gain, cVal))
return cVal;
break;
case CV_CAP_PROP_SHARPNESS:
case CAP_PROP_SHARPNESS:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Sharpness, cVal))
return cVal;
break;
case CV_CAP_PROP_GAMMA:
case CAP_PROP_GAMMA:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_Gamma, cVal))
return cVal;
break;
case CV_CAP_PROP_BACKLIGHT:
case CAP_PROP_BACKLIGHT:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_BacklightCompensation, cVal))
return cVal;
break;
case CV_CAP_PROP_MONOCHROME:
case CAP_PROP_MONOCHROME:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_ColorEnable, cVal))
return cVal == 0 ? 1 : 0;
break;
case CV_CAP_PROP_TEMPERATURE:
case CAP_PROP_TEMPERATURE:
if (readComplexPropery<IAMVideoProcAmp>(VideoProcAmp_WhiteBalance, cVal))
return cVal;
break;
case CV_CAP_PROP_PAN:
case CAP_PROP_PAN:
if (readComplexPropery<IAMCameraControl>(CameraControl_Pan, cVal))
return cVal;
break;
case CV_CAP_PROP_TILT:
case CAP_PROP_TILT:
if (readComplexPropery<IAMCameraControl>(CameraControl_Tilt, cVal))
return cVal;
break;
case CV_CAP_PROP_ROLL:
case CAP_PROP_ROLL:
if (readComplexPropery<IAMCameraControl>(CameraControl_Roll, cVal))
return cVal;
break;
case CV_CAP_PROP_IRIS:
case CAP_PROP_IRIS:
if (readComplexPropery<IAMCameraControl>(CameraControl_Iris, cVal))
return cVal;
break;
case CV_CAP_PROP_EXPOSURE:
case CV_CAP_PROP_AUTO_EXPOSURE:
case CAP_PROP_EXPOSURE:
case CAP_PROP_AUTO_EXPOSURE:
if (readComplexPropery<IAMCameraControl>(CameraControl_Exposure, cVal))
{
if (property_id == CV_CAP_PROP_EXPOSURE)
if (property_id == CAP_PROP_EXPOSURE)
return cVal;
else
return cVal == VideoProcAmp_Flags_Auto;
}
break;
case CV_CAP_PROP_ZOOM:
case CAP_PROP_ZOOM:
if (readComplexPropery<IAMCameraControl>(CameraControl_Zoom, cVal))
return cVal;
break;
case CV_CAP_PROP_FOCUS:
case CV_CAP_PROP_AUTOFOCUS:
case CAP_PROP_FOCUS:
case CAP_PROP_AUTOFOCUS:
if (readComplexPropery<IAMCameraControl>(CameraControl_Focus, cVal))
{
if (property_id == CV_CAP_PROP_FOCUS)
if (property_id == CAP_PROP_FOCUS)
return cVal;
else
return cVal == VideoProcAmp_Flags_Auto;
}
break;
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_WHITE_BALANCE_RED_V:
case CV_CAP_PROP_RECTIFICATION:
case CV_CAP_PROP_TRIGGER:
case CV_CAP_PROP_TRIGGER_DELAY:
case CV_CAP_PROP_GUID:
case CV_CAP_PROP_ISO_SPEED:
case CV_CAP_PROP_SETTINGS:
case CV_CAP_PROP_BUFFERSIZE:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_WHITE_BALANCE_RED_V:
case CAP_PROP_RECTIFICATION:
case CAP_PROP_TRIGGER:
case CAP_PROP_TRIGGER_DELAY:
case CAP_PROP_GUID:
case CAP_PROP_ISO_SPEED:
case CAP_PROP_SETTINGS:
case CAP_PROP_BUFFERSIZE:
case CAP_PROP_AUDIO_BASE_INDEX:
return audioBaseIndex;
case CAP_PROP_AUDIO_TOTAL_STREAMS:
@ -2246,7 +2246,7 @@ bool CvCapture_MSMF::setProperty( int property_id, double value )
if (isOpen)
switch (property_id)
{
case CV_CAP_PROP_MODE:
case CAP_PROP_MODE:
switch ((MSMFCapture_Mode)((int)value))
{
case MODE_SW:
@ -2256,107 +2256,107 @@ bool CvCapture_MSMF::setProperty( int property_id, double value )
default:
return false;
}
case CV_CAP_PROP_FOURCC:
case CAP_PROP_FOURCC:
return configureVideoOutput(newFormat, (int)cvRound(value));
case CV_CAP_PROP_FORMAT:
case CAP_PROP_FORMAT:
return configureVideoOutput(newFormat, (int)cvRound(value));
case CV_CAP_PROP_CONVERT_RGB:
case CAP_PROP_CONVERT_RGB:
convertFormat = (value != 0);
return configureVideoOutput(newFormat, outputVideoFormat);
case CV_CAP_PROP_SAR_NUM:
case CAP_PROP_SAR_NUM:
if (value > 0)
{
newFormat.aspectRatioNum = (UINT32)cvRound(value);
return configureVideoOutput(newFormat, outputVideoFormat);
}
break;
case CV_CAP_PROP_SAR_DEN:
case CAP_PROP_SAR_DEN:
if (value > 0)
{
newFormat.aspectRatioDenom = (UINT32)cvRound(value);
return configureVideoOutput(newFormat, outputVideoFormat);
}
break;
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
if (value >= 0)
{
newFormat.width = (UINT32)cvRound(value);
return configureVideoOutput(newFormat, outputVideoFormat);
}
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
if (value >= 0)
{
newFormat.height = (UINT32)cvRound(value);
return configureVideoOutput(newFormat, outputVideoFormat);
}
break;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
if (value >= 0)
{
newFormat.setFramerate(value);
return configureVideoOutput(newFormat, outputVideoFormat);
}
break;
case CV_CAP_PROP_FRAME_COUNT:
case CAP_PROP_FRAME_COUNT:
break;
case CV_CAP_PROP_POS_AVI_RATIO:
case CAP_PROP_POS_AVI_RATIO:
if (duration != 0)
return setTime(duration * value, true);
break;
case CV_CAP_PROP_POS_FRAMES:
case CAP_PROP_POS_FRAMES:
if (std::fabs(captureVideoFormat.getFramerate()) > 0)
return setTime((int)value);
break;
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
return setTime(value * 1e4, false);
case CV_CAP_PROP_BRIGHTNESS:
case CAP_PROP_BRIGHTNESS:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Brightness, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_CONTRAST:
case CAP_PROP_CONTRAST:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Contrast, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_SATURATION:
case CAP_PROP_SATURATION:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Saturation, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_HUE:
case CAP_PROP_HUE:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Hue, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_GAIN:
case CAP_PROP_GAIN:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Gain, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_SHARPNESS:
case CAP_PROP_SHARPNESS:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Sharpness, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_GAMMA:
case CAP_PROP_GAMMA:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_Gamma, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_BACKLIGHT:
case CAP_PROP_BACKLIGHT:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_BacklightCompensation, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_MONOCHROME:
case CAP_PROP_MONOCHROME:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_ColorEnable, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_TEMPERATURE:
case CAP_PROP_TEMPERATURE:
return writeComplexProperty<IAMVideoProcAmp>(VideoProcAmp_WhiteBalance, value, VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_PAN:
case CAP_PROP_PAN:
return writeComplexProperty<IAMCameraControl>(CameraControl_Pan, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_TILT:
case CAP_PROP_TILT:
return writeComplexProperty<IAMCameraControl>(CameraControl_Tilt, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_ROLL:
case CAP_PROP_ROLL:
return writeComplexProperty<IAMCameraControl>(CameraControl_Roll, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_IRIS:
case CAP_PROP_IRIS:
return writeComplexProperty<IAMCameraControl>(CameraControl_Iris, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
return writeComplexProperty<IAMCameraControl>(CameraControl_Exposure, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_AUTO_EXPOSURE:
case CAP_PROP_AUTO_EXPOSURE:
return writeComplexProperty<IAMCameraControl>(CameraControl_Exposure, value, value != 0 ? VideoProcAmp_Flags_Auto : VideoProcAmp_Flags_Manual);
case CV_CAP_PROP_ZOOM:
case CAP_PROP_ZOOM:
return writeComplexProperty<IAMCameraControl>(CameraControl_Zoom, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_FOCUS:
case CAP_PROP_FOCUS:
return writeComplexProperty<IAMCameraControl>(CameraControl_Focus, value, CameraControl_Flags_Manual);
case CV_CAP_PROP_AUTOFOCUS:
case CAP_PROP_AUTOFOCUS:
return writeComplexProperty<IAMCameraControl>(CameraControl_Focus, value, value != 0 ? CameraControl_Flags_Auto : CameraControl_Flags_Manual);
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_WHITE_BALANCE_RED_V:
case CV_CAP_PROP_RECTIFICATION:
case CV_CAP_PROP_TRIGGER:
case CV_CAP_PROP_TRIGGER_DELAY:
case CV_CAP_PROP_GUID:
case CV_CAP_PROP_ISO_SPEED:
case CV_CAP_PROP_SETTINGS:
case CV_CAP_PROP_BUFFERSIZE:
case CAP_PROP_WHITE_BALANCE_BLUE_U:
case CAP_PROP_WHITE_BALANCE_RED_V:
case CAP_PROP_RECTIFICATION:
case CAP_PROP_TRIGGER:
case CAP_PROP_TRIGGER_DELAY:
case CAP_PROP_GUID:
case CAP_PROP_ISO_SPEED:
case CAP_PROP_SETTINGS:
case CAP_PROP_BUFFERSIZE:
default:
break;
}

View File

@ -43,6 +43,8 @@
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
using namespace cv;
#ifdef HAVE_OPENNI2
#include <queue>
@ -100,7 +102,7 @@ private:
}
};
class CvCapture_OpenNI2 : public CvCapture
class CvCapture_OpenNI2 : public IVideoCapture
{
public:
enum { DEVICE_DEFAULT=0, DEVICE_MS_KINECT=0, DEVICE_ASUS_XTION=1, DEVICE_ORBBEC_ASTRA=2, DEVICE_MAX=2 };
@ -114,25 +116,17 @@ public:
CvCapture_OpenNI2(int index = 0);
CvCapture_OpenNI2(const char * filename);
virtual ~CvCapture_OpenNI2();
~CvCapture_OpenNI2();
virtual double getProperty(int propIdx) const CV_OVERRIDE;
virtual bool setProperty(int probIdx, double propVal) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
virtual IplImage* retrieveFrame(int outputType) CV_OVERRIDE;
virtual int getCaptureDomain() CV_OVERRIDE { return cv::CAP_OPENNI2; }
double getProperty(int propIdx) const CV_OVERRIDE;
bool setProperty(int probIdx, double propVal) CV_OVERRIDE;
bool grabFrame() CV_OVERRIDE;
bool retrieveFrame(int outputType, OutputArray arr) CV_OVERRIDE;
int getCaptureDomain() CV_OVERRIDE { return cv::CAP_OPENNI2; }
bool isOpened() const;
bool isOpened() const CV_OVERRIDE;
protected:
struct OutputMap
{
public:
cv::Mat mat;
IplImage* getIplImagePtr();
private:
IplImage iplHeader;
};
static const int outputMapsTypesCount = 8;
@ -140,14 +134,14 @@ protected:
CvCapture_OpenNI2(int index, const char * filename);
IplImage* retrieveDepthMap();
IplImage* retrievePointCloudMap();
IplImage* retrieveDisparityMap();
IplImage* retrieveDisparityMap_32F();
IplImage* retrieveValidDepthMask();
IplImage* retrieveBGRImage();
IplImage* retrieveGrayImage();
IplImage* retrieveIrImage();
Mat retrieveDepthMap();
Mat retrievePointCloudMap();
Mat retrieveDisparityMap();
Mat retrieveDisparityMap_32F();
Mat retrieveValidDepthMask();
Mat retrieveBGRImage();
Mat retrieveGrayImage();
Mat retrieveIrImage();
void toggleStream(int stream, bool toggle);
bool readCamerasParams();
@ -186,18 +180,9 @@ protected:
// The value for pixels without a valid disparity measurement
int noSampleValue;
std::vector<OutputMap> outputMaps;
std::vector<cv::Mat> outputMaps;
};
IplImage* CvCapture_OpenNI2::OutputMap::getIplImagePtr()
{
if( mat.empty() )
return 0;
iplHeader = cvIplImage(mat);
return &iplHeader;
}
bool CvCapture_OpenNI2::isOpened() const
{
return isContextOpened;
@ -296,10 +281,10 @@ CvCapture_OpenNI2::CvCapture_OpenNI2(int index, const char * filename) :
if (needIR)
toggleStream(CV_IR_STREAM, true);
setProperty(CV_CAP_PROP_OPENNI_REGISTRATION, 1.0);
setProperty(CAP_PROP_OPENNI_REGISTRATION, 1.0);
// default for Kinect2 camera
setProperty(CV_CAP_PROP_OPENNI2_MIRROR, 0.0);
setProperty(CAP_PROP_OPENNI2_MIRROR, 0.0);
isContextOpened = true;
@ -440,17 +425,17 @@ double CvCapture_OpenNI2::getProperty( int propIdx ) const
if( isOpened() )
{
int purePropIdx = propIdx & ~CV_CAP_OPENNI_GENERATORS_MASK;
int purePropIdx = propIdx & ~CAP_OPENNI_GENERATORS_MASK;
if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_IMAGE_GENERATOR )
if( (propIdx & CAP_OPENNI_GENERATORS_MASK) == CAP_OPENNI_IMAGE_GENERATOR )
{
propValue = getImageGeneratorProperty( purePropIdx );
}
else if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_DEPTH_GENERATOR )
else if( (propIdx & CAP_OPENNI_GENERATORS_MASK) == CAP_OPENNI_DEPTH_GENERATOR )
{
propValue = getDepthGeneratorProperty( purePropIdx );
}
else if ((propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_IR_GENERATOR)
else if ((propIdx & CAP_OPENNI_GENERATORS_MASK) == CAP_OPENNI_IR_GENERATOR)
{
propValue = getIrGeneratorProperty(purePropIdx);
}
@ -468,17 +453,17 @@ bool CvCapture_OpenNI2::setProperty( int propIdx, double propValue )
bool isSet = false;
if( isOpened() )
{
int purePropIdx = propIdx & ~CV_CAP_OPENNI_GENERATORS_MASK;
int purePropIdx = propIdx & ~CAP_OPENNI_GENERATORS_MASK;
if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_IMAGE_GENERATOR )
if( (propIdx & CAP_OPENNI_GENERATORS_MASK) == CAP_OPENNI_IMAGE_GENERATOR )
{
isSet = setImageGeneratorProperty( purePropIdx, propValue );
}
else if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_DEPTH_GENERATOR )
else if( (propIdx & CAP_OPENNI_GENERATORS_MASK) == CAP_OPENNI_DEPTH_GENERATOR )
{
isSet = setDepthGeneratorProperty( purePropIdx, propValue );
}
else if ((propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_IR_GENERATOR)
else if ((propIdx & CAP_OPENNI_GENERATORS_MASK) == CAP_OPENNI_IR_GENERATOR)
{
isSet = setIrGeneratorProperty(purePropIdx, propValue);
}
@ -497,19 +482,19 @@ double CvCapture_OpenNI2::getCommonProperty( int propIdx ) const
switch( propIdx )
{
case CV_CAP_PROP_FRAME_WIDTH :
case CV_CAP_PROP_FRAME_HEIGHT :
case CV_CAP_PROP_FPS :
case CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH :
case CV_CAP_PROP_OPENNI_BASELINE :
case CV_CAP_PROP_OPENNI_FOCAL_LENGTH :
case CV_CAP_PROP_OPENNI_REGISTRATION :
case CAP_PROP_FRAME_WIDTH :
case CAP_PROP_FRAME_HEIGHT :
case CAP_PROP_FPS :
case CAP_PROP_OPENNI_FRAME_MAX_DEPTH :
case CAP_PROP_OPENNI_BASELINE :
case CAP_PROP_OPENNI_FOCAL_LENGTH :
case CAP_PROP_OPENNI_REGISTRATION :
propValue = getDepthGeneratorProperty( propIdx );
break;
case CV_CAP_PROP_OPENNI2_SYNC :
case CAP_PROP_OPENNI2_SYNC :
propValue = const_cast<CvCapture_OpenNI2 *>(this)->device.getDepthColorSyncEnabled();
break;
case CV_CAP_PROP_OPENNI2_MIRROR:
case CAP_PROP_OPENNI2_MIRROR:
{
bool isMirroring = false;
for (int i = 0; i < CV_MAX_NUM_STREAMS; ++i)
@ -530,7 +515,7 @@ bool CvCapture_OpenNI2::setCommonProperty( int propIdx, double propValue )
switch( propIdx )
{
case CV_CAP_PROP_OPENNI2_MIRROR:
case CAP_PROP_OPENNI2_MIRROR:
{
bool mirror = propValue > 0.0 ? true : false;
for (int i = 0; i < CV_MAX_NUM_STREAMS; ++i)
@ -542,16 +527,16 @@ bool CvCapture_OpenNI2::setCommonProperty( int propIdx, double propValue )
break;
// There is a set of properties that correspond to depth generator by default
// (is they are pass without particular generator flag).
case CV_CAP_PROP_OPENNI_REGISTRATION:
case CAP_PROP_OPENNI_REGISTRATION:
isSet = setDepthGeneratorProperty(propIdx, propValue);
break;
case CV_CAP_PROP_OPENNI2_SYNC:
case CAP_PROP_OPENNI2_SYNC:
isSet = device.setDepthColorSyncEnabled(propValue > 0.0) == openni::STATUS_OK;
break;
case CV_CAP_PROP_FRAME_WIDTH:
case CV_CAP_PROP_FRAME_HEIGHT:
case CV_CAP_PROP_AUTOFOCUS:
case CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_AUTOFOCUS:
isSet = false;
break;
@ -572,41 +557,41 @@ double CvCapture_OpenNI2::getDepthGeneratorProperty( int propIdx ) const
switch( propIdx )
{
case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT:
case CAP_PROP_OPENNI_GENERATOR_PRESENT:
propValue = streams[CV_DEPTH_STREAM].isValid();
break;
case CV_CAP_PROP_FRAME_WIDTH :
case CAP_PROP_FRAME_WIDTH :
propValue = streams[CV_DEPTH_STREAM].getVideoMode().getResolutionX();
break;
case CV_CAP_PROP_FRAME_HEIGHT :
case CAP_PROP_FRAME_HEIGHT :
propValue = streams[CV_DEPTH_STREAM].getVideoMode().getResolutionY();
break;
case CV_CAP_PROP_FPS :
case CAP_PROP_FPS :
mode = streams[CV_DEPTH_STREAM].getVideoMode();
propValue = mode.getFps();
break;
case CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH :
case CAP_PROP_OPENNI_FRAME_MAX_DEPTH :
propValue = streams[CV_DEPTH_STREAM].getMaxPixelValue();
break;
case CV_CAP_PROP_OPENNI_BASELINE :
case CAP_PROP_OPENNI_BASELINE :
if(baseline <= 0)
if (!const_cast<CvCapture_OpenNI2*>(this)->readCamerasParams())
return 0;
propValue = baseline;
break;
case CV_CAP_PROP_OPENNI_FOCAL_LENGTH :
case CAP_PROP_OPENNI_FOCAL_LENGTH :
if(depthFocalLength_VGA <= 0)
if (!const_cast<CvCapture_OpenNI2*>(this)->readCamerasParams())
return 0;
propValue = (double)depthFocalLength_VGA;
break;
case CV_CAP_PROP_OPENNI_REGISTRATION :
case CAP_PROP_OPENNI_REGISTRATION :
propValue = device.getImageRegistrationMode();
break;
case CV_CAP_PROP_POS_MSEC :
case CAP_PROP_POS_MSEC :
propValue = (double)streamFrames[CV_DEPTH_STREAM].getTimestamp();
break;
case CV_CAP_PROP_POS_FRAMES :
case CAP_PROP_POS_FRAMES :
propValue = streamFrames[CV_DEPTH_STREAM].getFrameIndex();
break;
default :
@ -622,14 +607,14 @@ bool CvCapture_OpenNI2::setDepthGeneratorProperty( int propIdx, double propValue
switch( propIdx )
{
case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT:
case CAP_PROP_OPENNI_GENERATOR_PRESENT:
if (isContextOpened)
{
toggleStream(CV_DEPTH_STREAM, propValue > 0.0);
isSet = true;
}
break;
case CV_CAP_PROP_OPENNI_REGISTRATION:
case CAP_PROP_OPENNI_REGISTRATION:
{
CV_Assert(streams[CV_DEPTH_STREAM].isValid());
if( propValue != 0.0 ) // "on"
@ -690,22 +675,22 @@ double CvCapture_OpenNI2::getImageGeneratorProperty( int propIdx ) const
openni::VideoMode mode;
switch( propIdx )
{
case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT:
case CAP_PROP_OPENNI_GENERATOR_PRESENT:
propValue = streams[CV_COLOR_STREAM].isValid();
break;
case CV_CAP_PROP_FRAME_WIDTH :
case CAP_PROP_FRAME_WIDTH :
propValue = streams[CV_COLOR_STREAM].getVideoMode().getResolutionX();
break;
case CV_CAP_PROP_FRAME_HEIGHT :
case CAP_PROP_FRAME_HEIGHT :
propValue = streams[CV_COLOR_STREAM].getVideoMode().getResolutionY();
break;
case CV_CAP_PROP_FPS :
case CAP_PROP_FPS :
propValue = streams[CV_COLOR_STREAM].getVideoMode().getFps();
break;
case CV_CAP_PROP_POS_MSEC :
case CAP_PROP_POS_MSEC :
propValue = (double)streamFrames[CV_COLOR_STREAM].getTimestamp();
break;
case CV_CAP_PROP_POS_FRAMES :
case CAP_PROP_POS_FRAMES :
propValue = (double)streamFrames[CV_COLOR_STREAM].getFrameIndex();
break;
default :
@ -721,14 +706,14 @@ bool CvCapture_OpenNI2::setImageGeneratorProperty(int propIdx, double propValue)
switch( propIdx )
{
case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT:
case CAP_PROP_OPENNI_GENERATOR_PRESENT:
if (isContextOpened)
{
toggleStream(CV_COLOR_STREAM, propValue > 0.0);
isSet = true;
}
break;
case CV_CAP_PROP_OPENNI_OUTPUT_MODE :
case CAP_PROP_OPENNI_OUTPUT_MODE :
{
if (!streams[CV_COLOR_STREAM].isValid())
return isSet;
@ -736,23 +721,23 @@ bool CvCapture_OpenNI2::setImageGeneratorProperty(int propIdx, double propValue)
switch( cvRound(propValue) )
{
case CV_CAP_OPENNI_VGA_30HZ :
case CAP_OPENNI_VGA_30HZ :
mode.setResolution(640,480);
mode.setFps(30);
break;
case CV_CAP_OPENNI_SXGA_15HZ :
case CAP_OPENNI_SXGA_15HZ :
mode.setResolution(1280, 960);
mode.setFps(15);
break;
case CV_CAP_OPENNI_SXGA_30HZ :
case CAP_OPENNI_SXGA_30HZ :
mode.setResolution(1280, 960);
mode.setFps(30);
break;
case CV_CAP_OPENNI_QVGA_30HZ :
case CAP_OPENNI_QVGA_30HZ :
mode.setResolution(320, 240);
mode.setFps(30);
break;
case CV_CAP_OPENNI_QVGA_60HZ :
case CAP_OPENNI_QVGA_60HZ :
mode.setResolution(320, 240);
mode.setFps(60);
break;
@ -787,22 +772,22 @@ double CvCapture_OpenNI2::getIrGeneratorProperty(int propIdx) const
openni::VideoMode mode;
switch (propIdx)
{
case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT:
case CAP_PROP_OPENNI_GENERATOR_PRESENT:
propValue = streams[CV_IR_STREAM].isValid();
break;
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
propValue = streams[CV_IR_STREAM].getVideoMode().getResolutionX();
break;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
propValue = streams[CV_IR_STREAM].getVideoMode().getResolutionY();
break;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
propValue = streams[CV_IR_STREAM].getVideoMode().getFps();
break;
case CV_CAP_PROP_POS_MSEC:
case CAP_PROP_POS_MSEC:
propValue = (double)streamFrames[CV_IR_STREAM].getTimestamp();
break;
case CV_CAP_PROP_POS_FRAMES:
case CAP_PROP_POS_FRAMES:
propValue = (double)streamFrames[CV_IR_STREAM].getFrameIndex();
break;
default:
@ -818,14 +803,14 @@ bool CvCapture_OpenNI2::setIrGeneratorProperty(int propIdx, double propValue)
switch (propIdx)
{
case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT:
case CAP_PROP_OPENNI_GENERATOR_PRESENT:
if (isContextOpened)
{
toggleStream(CV_IR_STREAM, propValue > 0.0);
isSet = true;
}
break;
case CV_CAP_PROP_OPENNI_OUTPUT_MODE:
case CAP_PROP_OPENNI_OUTPUT_MODE:
{
if (!streams[CV_IR_STREAM].isValid())
return isSet;
@ -833,23 +818,23 @@ bool CvCapture_OpenNI2::setIrGeneratorProperty(int propIdx, double propValue)
switch (cvRound(propValue))
{
case CV_CAP_OPENNI_VGA_30HZ:
case CAP_OPENNI_VGA_30HZ:
mode.setResolution(640, 480);
mode.setFps(30);
break;
case CV_CAP_OPENNI_SXGA_15HZ:
case CAP_OPENNI_SXGA_15HZ:
mode.setResolution(1280, 960);
mode.setFps(15);
break;
case CV_CAP_OPENNI_SXGA_30HZ:
case CAP_OPENNI_SXGA_30HZ:
mode.setResolution(1280, 960);
mode.setFps(30);
break;
case CV_CAP_OPENNI_QVGA_30HZ:
case CAP_OPENNI_QVGA_30HZ:
mode.setResolution(320, 240);
mode.setFps(30);
break;
case CV_CAP_OPENNI_QVGA_60HZ:
case CAP_OPENNI_QVGA_60HZ:
mode.setResolution(320, 240);
mode.setFps(60);
break;
@ -913,20 +898,20 @@ inline void getDepthMapFromMetaData(const openni::VideoFrameRef& depthMetaData,
depthMap.setTo( cv::Scalar::all( CvCapture_OpenNI2::INVALID_PIXEL_VAL ), badMask );
}
IplImage* CvCapture_OpenNI2::retrieveDepthMap()
Mat CvCapture_OpenNI2::retrieveDepthMap()
{
if( !streamFrames[CV_DEPTH_STREAM].isValid() )
return 0;
return Mat();
getDepthMapFromMetaData(streamFrames[CV_DEPTH_STREAM], outputMaps[CV_CAP_OPENNI_DEPTH_MAP].mat, noSampleValue, shadowValue );
getDepthMapFromMetaData(streamFrames[CV_DEPTH_STREAM], outputMaps[CAP_OPENNI_DEPTH_MAP], noSampleValue, shadowValue );
return outputMaps[CV_CAP_OPENNI_DEPTH_MAP].getIplImagePtr();
return outputMaps[CAP_OPENNI_DEPTH_MAP];
}
IplImage* CvCapture_OpenNI2::retrievePointCloudMap()
Mat CvCapture_OpenNI2::retrievePointCloudMap()
{
if( !streamFrames[CV_DEPTH_STREAM].isValid() )
return 0;
return Mat();
cv::Mat depthImg;
getDepthMapFromMetaData(streamFrames[CV_DEPTH_STREAM], depthImg, noSampleValue, shadowValue);
@ -952,9 +937,9 @@ IplImage* CvCapture_OpenNI2::retrievePointCloudMap()
}
}
outputMaps[CV_CAP_OPENNI_POINT_CLOUD_MAP].mat = pointCloud_XYZ;
outputMaps[CAP_OPENNI_POINT_CLOUD_MAP] = pointCloud_XYZ;
return outputMaps[CV_CAP_OPENNI_POINT_CLOUD_MAP].getIplImagePtr();
return outputMaps[CAP_OPENNI_POINT_CLOUD_MAP];
}
static void computeDisparity_32F( const openni::VideoFrameRef& depthMetaData, cv::Mat& disp, double baseline, int F, int noSampleValue, int shadowValue)
@ -980,46 +965,46 @@ static void computeDisparity_32F( const openni::VideoFrameRef& depthMetaData, cv
}
}
IplImage* CvCapture_OpenNI2::retrieveDisparityMap()
Mat CvCapture_OpenNI2::retrieveDisparityMap()
{
if (!streamFrames[CV_DEPTH_STREAM].isValid())
return nullptr;
return Mat();
if (!readCamerasParams())
return nullptr;
return Mat();
cv::Mat disp32;
computeDisparity_32F(streamFrames[CV_DEPTH_STREAM], disp32, baseline, depthFocalLength_VGA, noSampleValue, shadowValue);
disp32.convertTo(outputMaps[CV_CAP_OPENNI_DISPARITY_MAP].mat, CV_8UC1);
disp32.convertTo(outputMaps[CAP_OPENNI_DISPARITY_MAP], CV_8UC1);
return outputMaps[CV_CAP_OPENNI_DISPARITY_MAP].getIplImagePtr();
return outputMaps[CAP_OPENNI_DISPARITY_MAP];
}
IplImage* CvCapture_OpenNI2::retrieveDisparityMap_32F()
Mat CvCapture_OpenNI2::retrieveDisparityMap_32F()
{
if (!streamFrames[CV_DEPTH_STREAM].isValid())
return nullptr;
return Mat();
if (!readCamerasParams())
return nullptr;
return Mat();
computeDisparity_32F(streamFrames[CV_DEPTH_STREAM], outputMaps[CV_CAP_OPENNI_DISPARITY_MAP_32F].mat, baseline, depthFocalLength_VGA, noSampleValue, shadowValue);
computeDisparity_32F(streamFrames[CV_DEPTH_STREAM], outputMaps[CAP_OPENNI_DISPARITY_MAP_32F], baseline, depthFocalLength_VGA, noSampleValue, shadowValue);
return outputMaps[CV_CAP_OPENNI_DISPARITY_MAP_32F].getIplImagePtr();
return outputMaps[CAP_OPENNI_DISPARITY_MAP_32F];
}
IplImage* CvCapture_OpenNI2::retrieveValidDepthMask()
Mat CvCapture_OpenNI2::retrieveValidDepthMask()
{
if (!streamFrames[CV_DEPTH_STREAM].isValid())
return nullptr;
return Mat();
cv::Mat d;
getDepthMapFromMetaData(streamFrames[CV_DEPTH_STREAM], d, noSampleValue, shadowValue);
outputMaps[CV_CAP_OPENNI_VALID_DEPTH_MASK].mat = d != CvCapture_OpenNI2::INVALID_PIXEL_VAL;
outputMaps[CAP_OPENNI_VALID_DEPTH_MASK] = d != CvCapture_OpenNI2::INVALID_PIXEL_VAL;
return outputMaps[CV_CAP_OPENNI_VALID_DEPTH_MASK].getIplImagePtr();
return outputMaps[CAP_OPENNI_VALID_DEPTH_MASK];
}
inline void getBGRImageFromMetaData( const openni::VideoFrameRef& imageMetaData, cv::Mat& bgrImage )
@ -1053,100 +1038,102 @@ inline void getGrayImageFromMetaData(const openni::VideoFrameRef& imageMetaData,
}
}
IplImage* CvCapture_OpenNI2::retrieveBGRImage()
Mat CvCapture_OpenNI2::retrieveBGRImage()
{
if( !streamFrames[CV_COLOR_STREAM].isValid() )
return 0;
return Mat();
getBGRImageFromMetaData(streamFrames[CV_COLOR_STREAM], outputMaps[CV_CAP_OPENNI_BGR_IMAGE].mat );
getBGRImageFromMetaData(streamFrames[CV_COLOR_STREAM], outputMaps[CAP_OPENNI_BGR_IMAGE] );
return outputMaps[CV_CAP_OPENNI_BGR_IMAGE].getIplImagePtr();
return outputMaps[CAP_OPENNI_BGR_IMAGE];
}
IplImage* CvCapture_OpenNI2::retrieveGrayImage()
Mat CvCapture_OpenNI2::retrieveGrayImage()
{
if (!streamFrames[CV_COLOR_STREAM].isValid())
return 0;
return Mat();
CV_Assert(streamFrames[CV_COLOR_STREAM].getVideoMode().getPixelFormat() == openni::PIXEL_FORMAT_RGB888); // RGB
cv::Mat rgbImage;
getBGRImageFromMetaData(streamFrames[CV_COLOR_STREAM], rgbImage);
cv::cvtColor( rgbImage, outputMaps[CV_CAP_OPENNI_GRAY_IMAGE].mat, cv::COLOR_BGR2GRAY );
cv::cvtColor( rgbImage, outputMaps[CAP_OPENNI_GRAY_IMAGE], cv::COLOR_BGR2GRAY );
return outputMaps[CV_CAP_OPENNI_GRAY_IMAGE].getIplImagePtr();
return outputMaps[CAP_OPENNI_GRAY_IMAGE];
}
IplImage* CvCapture_OpenNI2::retrieveIrImage()
Mat CvCapture_OpenNI2::retrieveIrImage()
{
if (!streamFrames[CV_IR_STREAM].isValid())
return 0;
return Mat();
getGrayImageFromMetaData(streamFrames[CV_IR_STREAM], outputMaps[CV_CAP_OPENNI_IR_IMAGE].mat);
getGrayImageFromMetaData(streamFrames[CV_IR_STREAM], outputMaps[CAP_OPENNI_IR_IMAGE]);
return outputMaps[CV_CAP_OPENNI_IR_IMAGE].getIplImagePtr();
return outputMaps[CAP_OPENNI_IR_IMAGE];
}
IplImage* CvCapture_OpenNI2::retrieveFrame( int outputType )
bool CvCapture_OpenNI2::retrieveFrame( int outputType, OutputArray arr )
{
IplImage* image = 0;
Mat image;
CV_Assert( outputType < outputMapsTypesCount && outputType >= 0);
if( outputType == CV_CAP_OPENNI_DEPTH_MAP )
if( outputType == CAP_OPENNI_DEPTH_MAP )
{
image = retrieveDepthMap();
}
else if( outputType == CV_CAP_OPENNI_POINT_CLOUD_MAP )
else if( outputType == CAP_OPENNI_POINT_CLOUD_MAP )
{
image = retrievePointCloudMap();
}
else if( outputType == CV_CAP_OPENNI_DISPARITY_MAP )
else if( outputType == CAP_OPENNI_DISPARITY_MAP )
{
image = retrieveDisparityMap();
}
else if( outputType == CV_CAP_OPENNI_DISPARITY_MAP_32F )
else if( outputType == CAP_OPENNI_DISPARITY_MAP_32F )
{
image = retrieveDisparityMap_32F();
}
else if( outputType == CV_CAP_OPENNI_VALID_DEPTH_MASK )
else if( outputType == CAP_OPENNI_VALID_DEPTH_MASK )
{
image = retrieveValidDepthMask();
}
else if( outputType == CV_CAP_OPENNI_BGR_IMAGE )
else if( outputType == CAP_OPENNI_BGR_IMAGE )
{
image = retrieveBGRImage();
}
else if( outputType == CV_CAP_OPENNI_GRAY_IMAGE )
else if( outputType == CAP_OPENNI_GRAY_IMAGE )
{
image = retrieveGrayImage();
}
else if( outputType == CV_CAP_OPENNI_IR_IMAGE )
else if( outputType == CAP_OPENNI_IR_IMAGE )
{
image = retrieveIrImage();
}
return image;
else
{
return false;
}
if (image.empty())
return false;
image.copyTo(arr);
return true;
}
cv::Ptr<cv::IVideoCapture> cv::create_OpenNI2_capture_cam( int index )
{
CvCapture_OpenNI2* capture = new CvCapture_OpenNI2( index );
Ptr<CvCapture_OpenNI2> capture = makePtr<CvCapture_OpenNI2>( index );
if( capture->isOpened() )
return cv::makePtr<cv::LegacyCapture>(capture);
delete capture;
return capture;
return 0;
}
cv::Ptr<cv::IVideoCapture> cv::create_OpenNI2_capture_file( const std::string &filename )
{
CvCapture_OpenNI2* capture = new CvCapture_OpenNI2( filename.c_str() );
Ptr<CvCapture_OpenNI2> capture = makePtr<CvCapture_OpenNI2>( filename.c_str() );
if( capture->isOpened() )
return cv::makePtr<cv::LegacyCapture>(capture);
delete capture;
return capture;
return 0;
}

View File

@ -46,6 +46,8 @@
#include "precomp.hpp"
#include "cap_interface.hpp"
using namespace cv;
#ifdef HAVE_PVAPI
#if !defined _WIN32 && !defined _LINUX
#define _LINUX
@ -71,25 +73,26 @@
/********************* Capturing video from camera via PvAPI *********************/
class CvCaptureCAM_PvAPI : public CvCapture
class CvCaptureCAM_PvAPI : public IVideoCapture
{
public:
CvCaptureCAM_PvAPI();
virtual ~CvCaptureCAM_PvAPI()
~CvCaptureCAM_PvAPI()
{
close();
}
virtual bool open( int index );
virtual void close();
virtual double getProperty(int) const CV_OVERRIDE;
virtual bool setProperty(int, double) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
virtual int getCaptureDomain() CV_OVERRIDE
bool open( int index );
void close();
double getProperty(int) const CV_OVERRIDE;
bool setProperty(int, double) CV_OVERRIDE;
bool grabFrame() CV_OVERRIDE;
bool retrieveFrame(int, OutputArray) CV_OVERRIDE;
int getCaptureDomain() CV_OVERRIDE
{
return CV_CAP_PVAPI;
return CAP_PVAPI;
}
bool isOpened() const CV_OVERRIDE { return Camera.Handle != 0; }
protected:
#ifndef _WIN32
@ -107,7 +110,7 @@ protected:
tPvFrame Frame;
} tCamera;
IplImage *frame;
Mat frame;
tCamera Camera;
tPvErr Errcode;
};
@ -115,7 +118,6 @@ protected:
CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI()
{
frame = NULL;
memset(&this->Camera, 0, sizeof(this->Camera));
}
@ -218,13 +220,14 @@ bool CvCaptureCAM_PvAPI::grabFrame()
}
IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int)
bool CvCaptureCAM_PvAPI::retrieveFrame(int, OutputArray arr)
{
if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess)
{
return frame;
frame.copyTo(arr);
return true;
}
else return NULL;
else return false;
}
double CvCaptureCAM_PvAPI::getProperty( int property_id ) const
@ -233,22 +236,23 @@ double CvCaptureCAM_PvAPI::getProperty( int property_id ) const
switch ( property_id )
{
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
PvAttrUint32Get(Camera.Handle, "Width", &nTemp);
return (double)nTemp;
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
PvAttrUint32Get(Camera.Handle, "Height", &nTemp);
return (double)nTemp;
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp);
return (double)nTemp;
case CV_CAP_PROP_FPS:
case CAP_PROP_FPS:
tPvFloat32 nfTemp;
PvAttrFloat32Get(Camera.Handle, "StatFrameRate", &nfTemp);
return (double)nfTemp;
case CV_CAP_PROP_PVAPI_MULTICASTIP:
char mEnable[2];
char mIp[11];
case CAP_PROP_PVAPI_MULTICASTIP:
{
char mEnable[4] {0};
char mIp[16] {0};
PvAttrEnumGet(Camera.Handle,"MulticastEnable",mEnable,sizeof(mEnable),NULL);
if (strcmp(mEnable, "Off") == 0)
{
@ -262,10 +266,13 @@ double CvCaptureCAM_PvAPI::getProperty( int property_id ) const
sscanf(mIp, "%d.%d.%d.%d", &a, &b, &c, &d); ip = ((a*256 + b)*256 + c)*256 + d;
return (double)ip;
}
case CV_CAP_PROP_GAIN:
}
case CAP_PROP_GAIN:
{
PvAttrUint32Get(Camera.Handle, "GainValue", &nTemp);
return (double)nTemp;
case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE:
}
case CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE:
char triggerMode[256];
PvAttrEnumGet(Camera.Handle, "FrameStartTriggerMode", triggerMode, 256, NULL);
if (strcmp(triggerMode, "Freerun")==0)
@ -280,19 +287,19 @@ double CvCaptureCAM_PvAPI::getProperty( int property_id ) const
return 4.0;
else
return -1.0;
case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL:
case CAP_PROP_PVAPI_DECIMATIONHORIZONTAL:
PvAttrUint32Get(Camera.Handle, "DecimationHorizontal", &nTemp);
return (double)nTemp;
case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL:
case CAP_PROP_PVAPI_DECIMATIONVERTICAL:
PvAttrUint32Get(Camera.Handle, "DecimationVertical", &nTemp);
return (double)nTemp;
case CV_CAP_PROP_PVAPI_BINNINGX:
case CAP_PROP_PVAPI_BINNINGX:
PvAttrUint32Get(Camera.Handle,"BinningX",&nTemp);
return (double)nTemp;
case CV_CAP_PROP_PVAPI_BINNINGY:
case CAP_PROP_PVAPI_BINNINGY:
PvAttrUint32Get(Camera.Handle,"BinningY",&nTemp);
return (double)nTemp;
case CV_CAP_PROP_PVAPI_PIXELFORMAT:
case CAP_PROP_PVAPI_PIXELFORMAT:
char pixelFormat[256];
PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
if (strcmp(pixelFormat, "Mono8")==0)
@ -321,7 +328,7 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
switch ( property_id )
{
case CV_CAP_PROP_FRAME_WIDTH:
case CAP_PROP_FRAME_WIDTH:
{
tPvUint32 currHeight;
@ -339,7 +346,7 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
break;
}
case CV_CAP_PROP_FRAME_HEIGHT:
case CAP_PROP_FRAME_HEIGHT:
{
tPvUint32 currWidth;
@ -358,12 +365,12 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
break;
}
case CV_CAP_PROP_EXPOSURE:
case CAP_PROP_EXPOSURE:
if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess))
break;
else
return false;
case CV_CAP_PROP_PVAPI_MULTICASTIP:
case CAP_PROP_PVAPI_MULTICASTIP:
if (value==-1)
{
if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "Off")==ePvErrSuccess))
@ -380,13 +387,13 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
else
return false;
}
case CV_CAP_PROP_GAIN:
case CAP_PROP_GAIN:
if (PvAttrUint32Set(Camera.Handle,"GainValue",(tPvUint32)value)!=ePvErrSuccess)
{
return false;
}
break;
case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE:
case CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE:
if (value==0)
error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun");
else if (value==1)
@ -403,7 +410,7 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
break;
else
return false;
case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL:
case CAP_PROP_PVAPI_DECIMATIONHORIZONTAL:
if (value >= 1 && value <= 8)
error = PvAttrUint32Set(Camera.Handle, "DecimationHorizontal", value);
else
@ -412,7 +419,7 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
break;
else
return false;
case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL:
case CAP_PROP_PVAPI_DECIMATIONVERTICAL:
if (value >= 1 && value <= 8)
error = PvAttrUint32Set(Camera.Handle, "DecimationVertical", value);
else
@ -421,19 +428,19 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
break;
else
return false;
case CV_CAP_PROP_PVAPI_BINNINGX:
case CAP_PROP_PVAPI_BINNINGX:
error = PvAttrUint32Set(Camera.Handle, "BinningX", value);
if(error==ePvErrSuccess)
break;
else
return false;
case CV_CAP_PROP_PVAPI_BINNINGY:
case CAP_PROP_PVAPI_BINNINGY:
error = PvAttrUint32Set(Camera.Handle, "BinningY", value);
if(error==ePvErrSuccess)
break;
else
return false;
case CV_CAP_PROP_PVAPI_PIXELFORMAT:
case CAP_PROP_PVAPI_PIXELFORMAT:
{
cv::String pixelFormat;
@ -524,10 +531,9 @@ bool CvCaptureCAM_PvAPI::resizeCaptureFrame (int frameWidth, int frameHeight)
tPvUint32 sensorHeight;
tPvUint32 sensorWidth;
if (frame)
if (!frame.empty())
{
cvReleaseImage(&frame);
frame = NULL;
frame.release();
}
if (PvAttrUint32Get(Camera.Handle, "SensorWidth", &sensorWidth) != ePvErrSuccess)
@ -566,33 +572,30 @@ bool CvCaptureCAM_PvAPI::resizeCaptureFrame (int frameWidth, int frameHeight)
PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize);
const cv::Size sz((int)frameWidth, (int)frameHeight);
if ( (strcmp(pixelFormat, "Mono8")==0) || (strcmp(pixelFormat, "Bayer8")==0) )
{
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 1);
frame->widthStep = (int)frameWidth;
Camera.Frame.ImageBufferSize = frameSize;
Camera.Frame.ImageBuffer = frame->imageData;
frame.create(sz, CV_8UC1);
Camera.Frame.ImageBufferSize = frame.total() * frame.elemSize();
Camera.Frame.ImageBuffer = frame.data;
}
else if ( (strcmp(pixelFormat, "Mono16")==0) || (strcmp(pixelFormat, "Bayer16")==0) )
{
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 1);
frame->widthStep = (int)frameWidth*2;
Camera.Frame.ImageBufferSize = frameSize;
Camera.Frame.ImageBuffer = frame->imageData;
frame.create(sz, CV_16UC1);
Camera.Frame.ImageBufferSize = frame.total() * frame.elemSize();
Camera.Frame.ImageBuffer = frame.data;
}
else if ( (strcmp(pixelFormat, "Rgb24")==0) || (strcmp(pixelFormat, "Bgr24")==0) )
{
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3);
frame->widthStep = (int)frameWidth*3;
Camera.Frame.ImageBufferSize = frameSize;
Camera.Frame.ImageBuffer = frame->imageData;
frame.create(sz, CV_8UC3);
Camera.Frame.ImageBufferSize = frame.total() * frame.elemSize();
Camera.Frame.ImageBuffer = frame.data;
}
else if ( (strcmp(pixelFormat, "Rgba32")==0) || (strcmp(pixelFormat, "Bgra32")==0) )
{
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 4);
frame->widthStep = (int)frameWidth*4;
Camera.Frame.ImageBufferSize = frameSize;
Camera.Frame.ImageBuffer = frame->imageData;
frame.create(sz, CV_8UC4);
Camera.Frame.ImageBufferSize = frame.total() * frame.elemSize();
Camera.Frame.ImageBuffer = frame.data;
}
else
return false;
@ -602,12 +605,10 @@ bool CvCaptureCAM_PvAPI::resizeCaptureFrame (int frameWidth, int frameHeight)
cv::Ptr<cv::IVideoCapture> cv::create_PvAPI_capture( int index )
{
CvCaptureCAM_PvAPI* capture = new CvCaptureCAM_PvAPI;
Ptr<CvCaptureCAM_PvAPI> capture = makePtr<CvCaptureCAM_PvAPI>();
if ( capture->open( index ))
return cv::makePtr<cv::LegacyCapture>(capture);
delete capture;
return capture;
return NULL;
}
#endif

View File

@ -154,12 +154,12 @@ the symptoms were damaged image and 'Corrupt JPEG data: premature end of data se
prevents bad images in the first place
11th patch: April 2, 2013, Forrest Reiling forrest.reiling@gmail.com
Added v4l2 support for getting capture property CV_CAP_PROP_POS_MSEC.
Added v4l2 support for getting capture property CAP_PROP_POS_MSEC.
Returns the millisecond timestamp of the last frame grabbed or 0 if no frames have been grabbed
Used to successfully synchronize 2 Logitech C310 USB webcams to within 16 ms of one another
12th patch: March 9, 2018, Taylor Lanclos <tlanclos@live.com>
added support for CV_CAP_PROP_BUFFERSIZE
added support for CAP_PROP_BUFFERSIZE
make & enjoy!
@ -361,7 +361,7 @@ struct Buffer
}
};
struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
struct CvCaptureCAM_V4L CV_FINAL : public IVideoCapture
{
int getCaptureDomain() /*const*/ CV_OVERRIDE { return cv::CAP_V4L; }
@ -373,7 +373,7 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
bool FirstCapture;
String deviceName;
IplImage frame;
Mat frame;
__u32 palette;
int width, height;
@ -381,7 +381,6 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
int bufferSize;
__u32 fps;
bool convert_rgb;
bool frame_allocated;
bool returnFrame;
// To select a video input set cv::CAP_PROP_CHANNEL to channel number.
// If the new channel number is than 0, then a video input will not change
@ -407,15 +406,15 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
timeval timestamp;
bool open(int _index);
bool open(const char* deviceName);
bool isOpened() const;
bool open(const std::string & filename);
bool isOpened() const CV_OVERRIDE;
void closeDevice();
virtual double getProperty(int) const CV_OVERRIDE;
virtual bool setProperty(int, double) CV_OVERRIDE;
virtual bool grabFrame() CV_OVERRIDE;
virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
virtual bool retrieveFrame(int, OutputArray) CV_OVERRIDE;
CvCaptureCAM_V4L();
virtual ~CvCaptureCAM_V4L();
@ -436,11 +435,9 @@ struct CvCaptureCAM_V4L CV_FINAL : public CvCapture
bool try_palette_v4l2();
bool try_init_v4l2();
bool autosetup_capture_mode_v4l2();
void v4l2_create_frame();
bool read_frame_v4l2();
bool convertableToRgb() const;
void convertToRgb(const Buffer &currentBuffer);
void releaseFrame();
bool havePendingFrame; // true if next .grab() should be noop, .retrive() resets this flag
};
@ -456,13 +453,12 @@ CvCaptureCAM_V4L::CvCaptureCAM_V4L() :
palette(0),
width(0), height(0), width_set(0), height_set(0),
bufferSize(DEFAULT_V4L_BUFFERS),
fps(0), convert_rgb(0), frame_allocated(false), returnFrame(false),
fps(0), convert_rgb(0), returnFrame(false),
channelNumber(-1), normalizePropRange(false),
type(V4L2_BUF_TYPE_VIDEO_CAPTURE),
num_planes(0),
havePendingFrame(false)
{
frame = cvIplImage();
memset(&timestamp, 0, sizeof(timestamp));
}
@ -696,86 +692,6 @@ bool CvCaptureCAM_V4L::convertableToRgb() const
return false;
}
void CvCaptureCAM_V4L::v4l2_create_frame()
{
CvSize size;
int channels = 3;
int depth = IPL_DEPTH_8U;
if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
CV_Assert(form.fmt.pix_mp.width <= (uint)std::numeric_limits<int>::max());
CV_Assert(form.fmt.pix_mp.height <= (uint)std::numeric_limits<int>::max());
size = {(int)form.fmt.pix_mp.width, (int)form.fmt.pix_mp.height};
} else {
CV_Assert(form.fmt.pix.width <= (uint)std::numeric_limits<int>::max());
CV_Assert(form.fmt.pix.height <= (uint)std::numeric_limits<int>::max());
size = {(int)form.fmt.pix.width, (int)form.fmt.pix.height};
}
if (!convert_rgb) {
switch (palette) {
case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_XBGR32:
case V4L2_PIX_FMT_ABGR32:
break;
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_UYVY:
channels = 2;
break;
case V4L2_PIX_FMT_YVU420:
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
channels = 1;
size.height = size.height * 3 / 2; // "1.5" channels
break;
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y16_BE:
case V4L2_PIX_FMT_Y12:
case V4L2_PIX_FMT_Y10:
depth = IPL_DEPTH_16U;
/* fallthru */
case V4L2_PIX_FMT_GREY:
channels = 1;
break;
case V4L2_PIX_FMT_MJPEG:
case V4L2_PIX_FMT_JPEG:
default:
channels = 1;
if(bufferIndex < 0)
size = cvSize(buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].length, 1);
else {
__u32 bytesused = 0;
if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
__u32 data_offset;
for (unsigned char n_planes = 0; n_planes < num_planes; n_planes++) {
data_offset = buffers[bufferIndex].planes[n_planes].data_offset;
bytesused += buffers[bufferIndex].planes[n_planes].bytesused - data_offset;
}
} else
bytesused = buffers[bufferIndex].buffer.bytesused;
size = cvSize(bytesused, 1);
}
break;
}
}
/* Set up Image data */
cvInitImageHeader(&frame, size, depth, channels);
/* Allocate space for pixelformat we convert to.
* If we do not convert frame is just points to the buffer
*/
releaseFrame();
// we need memory iff convert_rgb is true
if (convert_rgb) {
frame.imageData = (char *)cvAlloc(frame.imageSize);
frame_allocated = true;
}
}
bool CvCaptureCAM_V4L::initCapture()
{
if (!isOpened())
@ -840,8 +756,6 @@ bool CvCaptureCAM_V4L::initCapture()
return false;
}
v4l2_create_frame();
// reinitialize buffers
FirstCapture = true;
@ -993,7 +907,7 @@ bool CvCaptureCAM_V4L::open(int _index)
name = cv::format("/dev/video%d", _index);
}
bool res = open(name.c_str());
bool res = open(name);
if (!res)
{
CV_LOG_WARNING(NULL, "VIDEOIO(V4L2:" << deviceName << "): can't open camera by index");
@ -1001,9 +915,8 @@ bool CvCaptureCAM_V4L::open(int _index)
return res;
}
bool CvCaptureCAM_V4L::open(const char* _deviceName)
bool CvCaptureCAM_V4L::open(const std::string & _deviceName)
{
CV_Assert(_deviceName);
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << _deviceName << "): opening...");
FirstCapture = true;
width = DEFAULT_V4L_WIDTH;
@ -1012,7 +925,6 @@ bool CvCaptureCAM_V4L::open(const char* _deviceName)
bufferSize = DEFAULT_V4L_BUFFERS;
fps = DEFAULT_V4L_FPS;
convert_rgb = true;
frame_allocated = false;
deviceName = _deviceName;
returnFrame = true;
normalizePropRange = utils::getConfigurationParameterBool("OPENCV_VIDEOIO_V4L_RANGE_NORMALIZED", false);
@ -1519,46 +1431,45 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer &currentBuffer)
switch (palette)
{
case V4L2_PIX_FMT_YUV411P:
yuv411p_to_rgb24(imageSize.width, imageSize.height,
start, (unsigned char*)frame.imageData);
frame.create(imageSize, CV_8UC3);
yuv411p_to_rgb24(imageSize.width, imageSize.height, start, frame.data);
return;
default:
break;
}
// Converted by cvtColor or imdecode
cv::Mat destination(imageSize, CV_8UC3, frame.imageData);
switch (palette) {
case V4L2_PIX_FMT_YVU420:
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), destination,
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), frame,
COLOR_YUV2BGR_YV12);
return;
case V4L2_PIX_FMT_YUV420:
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), destination,
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), frame,
COLOR_YUV2BGR_IYUV);
return;
case V4L2_PIX_FMT_NV12:
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), destination,
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), frame,
COLOR_YUV2BGR_NV12);
return;
case V4L2_PIX_FMT_NV21:
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), destination,
cv::cvtColor(cv::Mat(imageSize.height * 3 / 2, imageSize.width, CV_8U, start), frame,
COLOR_YUV2BGR_NV21);
return;
#ifdef HAVE_JPEG
case V4L2_PIX_FMT_MJPEG:
case V4L2_PIX_FMT_JPEG:
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): decoding JPEG frame: size=" << currentBuffer.bytesused);
cv::imdecode(Mat(1, currentBuffer.bytesused, CV_8U, start), IMREAD_COLOR, &destination);
cv::imdecode(Mat(1, currentBuffer.bytesused, CV_8U, start), IMREAD_COLOR, &frame);
return;
#endif
case V4L2_PIX_FMT_YUYV:
cv::cvtColor(cv::Mat(imageSize, CV_8UC2, start), destination, COLOR_YUV2BGR_YUYV);
cv::cvtColor(cv::Mat(imageSize, CV_8UC2, start), frame, COLOR_YUV2BGR_YUYV);
return;
case V4L2_PIX_FMT_UYVY:
cv::cvtColor(cv::Mat(imageSize, CV_8UC2, start), destination, COLOR_YUV2BGR_UYVY);
cv::cvtColor(cv::Mat(imageSize, CV_8UC2, start), frame, COLOR_YUV2BGR_UYVY);
return;
case V4L2_PIX_FMT_RGB24:
cv::cvtColor(cv::Mat(imageSize, CV_8UC3, start), destination, COLOR_RGB2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC3, start), frame, COLOR_RGB2BGR);
return;
case V4L2_PIX_FMT_Y16:
{
@ -1567,7 +1478,7 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer &currentBuffer)
// Note: 10-bits precision is not supported
cv::Mat temp(imageSize, CV_8UC1, buffers[MAX_V4L_BUFFERS].memories[MEMORY_RGB].start);
cv::extractChannel(cv::Mat(imageSize, CV_8UC2, start), temp, 1); // 1 - second channel
cv::cvtColor(temp, destination, COLOR_GRAY2BGR);
cv::cvtColor(temp, frame, COLOR_GRAY2BGR);
return;
}
case V4L2_PIX_FMT_Y16_BE:
@ -1577,21 +1488,21 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer &currentBuffer)
// Note: 10-bits precision is not supported
cv::Mat temp(imageSize, CV_8UC1, buffers[MAX_V4L_BUFFERS].memories[MEMORY_RGB].start);
cv::extractChannel(cv::Mat(imageSize, CV_8UC2, start), temp, 0); // 0 - first channel
cv::cvtColor(temp, destination, COLOR_GRAY2BGR);
cv::cvtColor(temp, frame, COLOR_GRAY2BGR);
return;
}
case V4L2_PIX_FMT_Y12:
{
cv::Mat temp(imageSize, CV_8UC1, buffers[MAX_V4L_BUFFERS].memories[MEMORY_RGB].start);
cv::Mat(imageSize, CV_16UC1, start).convertTo(temp, CV_8U, 1.0 / 16);
cv::cvtColor(temp, destination, COLOR_GRAY2BGR);
cv::cvtColor(temp, frame, COLOR_GRAY2BGR);
return;
}
case V4L2_PIX_FMT_Y10:
{
cv::Mat temp(imageSize, CV_8UC1, buffers[MAX_V4L_BUFFERS].memories[MEMORY_RGB].start);
cv::Mat(imageSize, CV_16UC1, start).convertTo(temp, CV_8U, 1.0 / 4);
cv::cvtColor(temp, destination, COLOR_GRAY2BGR);
cv::cvtColor(temp, frame, COLOR_GRAY2BGR);
return;
}
case V4L2_PIX_FMT_SN9C10X:
@ -1601,40 +1512,39 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer &currentBuffer)
start, (unsigned char*)buffers[MAX_V4L_BUFFERS].memories[MEMORY_RGB].start);
cv::Mat cv_buf(imageSize, CV_8UC1, buffers[MAX_V4L_BUFFERS].memories[MEMORY_RGB].start);
cv::cvtColor(cv_buf, destination, COLOR_BayerRG2BGR);
cv::cvtColor(cv_buf, frame, COLOR_BayerRG2BGR);
return;
}
case V4L2_PIX_FMT_SRGGB8:
{
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), destination, COLOR_BayerBG2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), frame, COLOR_BayerBG2BGR);
return;
}
case V4L2_PIX_FMT_SBGGR8:
{
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), destination, COLOR_BayerRG2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), frame, COLOR_BayerRG2BGR);
return;
}
case V4L2_PIX_FMT_SGBRG8:
{
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), destination, COLOR_BayerGR2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), frame, COLOR_BayerGR2BGR);
return;
}
case V4L2_PIX_FMT_SGRBG8:
{
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), destination, COLOR_BayerGB2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), frame, COLOR_BayerGB2BGR);
return;
}
case V4L2_PIX_FMT_GREY:
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), destination, COLOR_GRAY2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, start), frame, COLOR_GRAY2BGR);
break;
case V4L2_PIX_FMT_XBGR32:
case V4L2_PIX_FMT_ABGR32:
cv::cvtColor(cv::Mat(imageSize, CV_8UC4, start), destination, COLOR_BGRA2BGR);
cv::cvtColor(cv::Mat(imageSize, CV_8UC4, start), frame, COLOR_BGRA2BGR);
break;
case V4L2_PIX_FMT_BGR24:
default:
memcpy((char *)frame.imageData, start,
std::min(frame.imageSize, (int)currentBuffer.bytesused));
Mat(1, currentBuffer.bytesused, CV_8U, start).copyTo(frame);
break;
}
}
@ -1921,7 +1831,7 @@ double CvCaptureCAM_V4L::getProperty(int property_id) const
case cv::CAP_PROP_FOURCC:
return palette;
case cv::CAP_PROP_FORMAT:
return CV_MAKETYPE(IPL2CV_DEPTH(frame.depth), frame.nChannels);
return frame.type();
case cv::CAP_PROP_MODE:
if (normalizePropRange)
return palette;
@ -2000,8 +1910,6 @@ bool CvCaptureCAM_V4L::setProperty( int property_id, double _value )
return convert_rgb;
}else{
convert_rgb = false;
releaseFrame();
v4l2_create_frame();
return true;
}
case cv::CAP_PROP_FOURCC:
@ -2063,18 +1971,8 @@ bool CvCaptureCAM_V4L::setProperty( int property_id, double _value )
return false;
}
void CvCaptureCAM_V4L::releaseFrame()
{
if (frame_allocated && frame.imageData) {
cvFree(&frame.imageData);
frame_allocated = false;
}
}
void CvCaptureCAM_V4L::releaseBuffers()
{
releaseFrame();
if (buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].start) {
free(buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].start);
buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].start = 0;
@ -2135,42 +2033,43 @@ bool CvCaptureCAM_V4L::streaming(bool startStream)
return startStream;
}
IplImage *CvCaptureCAM_V4L::retrieveFrame(int)
bool CvCaptureCAM_V4L::retrieveFrame(int, OutputArray ret)
{
havePendingFrame = false; // unlock .grab()
if (bufferIndex < 0)
return &frame;
frame.copyTo(ret);
/* Now get what has already been captured as a IplImage return */
const Buffer &currentBuffer = buffers[bufferIndex];
if (convert_rgb) {
if (!frame_allocated)
v4l2_create_frame();
convertToRgb(currentBuffer);
} else {
// for mjpeg streams the size might change in between, so we have to change the header
// We didn't allocate memory when not convert_rgb, but we have to recreate the header
CV_LOG_DEBUG(NULL, "VIDEOIO(V4L2:" << deviceName << "): buffer input size=" << currentBuffer.bytesused);
if (frame.imageSize != (int)currentBuffer.bytesused)
v4l2_create_frame();
frame.imageData = (char *)buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].start;
if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
// calculate total size
__u32 bytestotal = 0;
for (unsigned char n_planes = 0; n_planes < num_planes; n_planes++) {
const v4l2_plane & cur_plane = currentBuffer.planes[n_planes];
bytestotal += cur_plane.bytesused - cur_plane.data_offset;
}
// allocate frame data
frame.create(Size(bytestotal, 1), CV_8U);
// copy each plane to the frame
__u32 offset = 0;
for (unsigned char n_planes = 0; n_planes < num_planes; n_planes++) {
__u32 data_offset, bytesused;
data_offset = currentBuffer.planes[n_planes].data_offset;
bytesused = currentBuffer.planes[n_planes].bytesused - data_offset;
memcpy((unsigned char*)buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].start + offset,
(char *)currentBuffer.memories[n_planes].start + data_offset,
std::min(currentBuffer.memories[n_planes].length, (size_t)bytesused));
offset += bytesused;
const v4l2_plane & cur_plane = currentBuffer.planes[n_planes];
const Memory & cur_mem = currentBuffer.memories[n_planes];
memcpy(frame.data + offset,
(char*)cur_mem.start + cur_plane.data_offset,
std::min(currentBuffer.memories[n_planes].length, (size_t)cur_plane.bytesused));
}
} else {
memcpy(buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].start, currentBuffer.memories[MEMORY_ORIG].start,
std::min(buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].length, (size_t)currentBuffer.buffer.bytesused));
const Size sz(std::min(buffers[MAX_V4L_BUFFERS].memories[MEMORY_ORIG].length, (size_t)currentBuffer.buffer.bytesused), 1);
frame = Mat(sz, CV_8U, currentBuffer.memories[MEMORY_ORIG].start);
}
}
//Revert buffer to the queue
@ -2180,28 +2079,23 @@ IplImage *CvCaptureCAM_V4L::retrieveFrame(int)
}
bufferIndex = -1;
return &frame;
frame.copyTo(ret);
return true;
}
Ptr<IVideoCapture> create_V4L_capture_cam(int index)
{
cv::CvCaptureCAM_V4L* capture = new cv::CvCaptureCAM_V4L();
if (capture->open(index))
return makePtr<LegacyCapture>(capture);
delete capture;
Ptr<CvCaptureCAM_V4L> ret = makePtr<CvCaptureCAM_V4L>();
if (ret->open(index))
return ret;
return NULL;
}
Ptr<IVideoCapture> create_V4L_capture_file(const std::string &filename)
{
cv::CvCaptureCAM_V4L* capture = new cv::CvCaptureCAM_V4L();
if (capture->open(filename.c_str()))
return makePtr<LegacyCapture>(capture);
delete capture;
auto ret = makePtr<CvCaptureCAM_V4L>();
if (ret->open(filename))
return ret;
return NULL;
}
@ -2272,12 +2166,7 @@ bool VideoCapture_V4L_waitAny(const std::vector<VideoCapture>& streams, CV_OUT s
for (size_t i = 0; i < N; ++i)
{
IVideoCapture* iCap = internal::VideoCapturePrivateAccessor::getIVideoCapture(streams[i]);
LegacyCapture* legacyCapture = dynamic_cast<LegacyCapture*>(iCap);
CV_Assert(legacyCapture);
CvCapture* cvCap = legacyCapture->getCvCapture();
CV_Assert(cvCap);
CvCaptureCAM_V4L *ptr_CvCaptureCAM_V4L = dynamic_cast<CvCaptureCAM_V4L*>(cvCap);
CvCaptureCAM_V4L *ptr_CvCaptureCAM_V4L = dynamic_cast<CvCaptureCAM_V4L*>(iCap);
CV_Assert(ptr_CvCaptureCAM_V4L);
capPtr[i] = ptr_CvCaptureCAM_V4L;
}

File diff suppressed because it is too large Load Diff

View File

@ -213,13 +213,13 @@ class XINECapture : public IVideoCapture
switch (property_id)
{
case CV_CAP_PROP_POS_MSEC: return res ? pos_t : 0;
case CV_CAP_PROP_POS_FRAMES: return frame_number;
case CV_CAP_PROP_POS_AVI_RATIO: return length && res ? pos_l / 65535.0 : 0.0;
case CV_CAP_PROP_FRAME_WIDTH: return size.width;
case CV_CAP_PROP_FRAME_HEIGHT: return size.height;
case CV_CAP_PROP_FPS: return frame_rate;
case CV_CAP_PROP_FOURCC: return (double)xine_get_stream_info(stream, XINE_STREAM_INFO_VIDEO_FOURCC);
case CAP_PROP_POS_MSEC: return res ? pos_t : 0;
case CAP_PROP_POS_FRAMES: return frame_number;
case CAP_PROP_POS_AVI_RATIO: return length && res ? pos_l / 65535.0 : 0.0;
case CAP_PROP_FRAME_WIDTH: return size.width;
case CAP_PROP_FRAME_HEIGHT: return size.height;
case CAP_PROP_FPS: return frame_rate;
case CAP_PROP_FOURCC: return (double)xine_get_stream_info(stream, XINE_STREAM_INFO_VIDEO_FOURCC);
}
return 0;
}
@ -230,9 +230,9 @@ class XINECapture : public IVideoCapture
CV_Assert(vo_port);
switch (property_id)
{
case CV_CAP_PROP_POS_MSEC: return seekTime((int)value);
case CV_CAP_PROP_POS_FRAMES: return seekFrame((int)value);
case CV_CAP_PROP_POS_AVI_RATIO: return seekRatio(value);
case CAP_PROP_POS_MSEC: return seekTime((int)value);
case CAP_PROP_POS_FRAMES: return seekFrame((int)value);
case CAP_PROP_POS_AVI_RATIO: return seekRatio(value);
default: return false;
}
}

View File

@ -2,8 +2,8 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include "opencv2/videoio/container_avi.private.hpp"
#include <opencv2/core/utils/logger.hpp>
#include <fstream>
#include <limits>
#include <typeinfo>
@ -23,7 +23,8 @@ inline D safe_int_cast(S val, const char * msg = 0)
if (!in_range_r || !in_range_l)
{
if (!msg)
CV_Error_(Error::StsOutOfRange, ("Can not convert integer values (%s -> %s), value 0x%jx is out of range", typeid(S).name(), typeid(D).name(), (uintmax_t)val));
CV_Error(Error::StsOutOfRange,
cv::format("Can not convert integer values (%s -> %s), value 0x%jx is out of range", typeid(S).name(), typeid(D).name(), (uintmax_t)val));
else
CV_Error(Error::StsOutOfRange, msg);
}
@ -269,15 +270,15 @@ VideoInputStream::~VideoInputStream()
AVIReadContainer::AVIReadContainer(): m_stream_id(0), m_movi_start(0), m_movi_end(0), m_width(0), m_height(0), m_fps(0), m_is_indx_present(false)
{
m_file_stream = makePtr<VideoInputStream>();
m_file_stream = std::make_shared<VideoInputStream>();
}
void AVIReadContainer::initStream(const String &filename)
{
m_file_stream = makePtr<VideoInputStream>(filename);
m_file_stream = std::make_shared<VideoInputStream>(filename);
}
void AVIReadContainer::initStream(Ptr<VideoInputStream> m_file_stream_)
void AVIReadContainer::initStream(std::shared_ptr<VideoInputStream> m_file_stream_)
{
m_file_stream = m_file_stream_;
}

View File

@ -53,9 +53,8 @@
#include <unistd.h> // -D_FORTIFY_SOURCE=2 workaround: https://github.com/opencv/opencv/issues/15020
#endif
#include "opencv2/core/cvdef.h"
#include "opencv2/videoio.hpp"
#include "opencv2/videoio/legacy/constants_c.h"
#include "opencv2/core/utility.hpp"
#ifdef __OPENCV_BUILD
@ -75,7 +74,6 @@
#include "opencv2/imgproc.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/videoio/videoio_c.h"
#include <stdlib.h>
#include <stdio.h>

View File

@ -1,19 +0,0 @@
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs/legacy/constants_c.h>
#include <opencv2/videoio/legacy/constants_c.h>
#include <opencv2/photo/legacy/constants_c.h>
#include <opencv2/video/legacy/constants_c.h>
using namespace cv;
int main(int /*argc*/, const char** /*argv*/)
{
std::cout
<< (int)CV_LOAD_IMAGE_GRAYSCALE
<< (int)CV_CAP_FFMPEG
<< std::endl;
return 0;
}