DShow camera as IVideoCapture object

This commit is contained in:
vbystricky 2014-07-08 12:21:54 +04:00
parent e79ceb4b45
commit eb8366bb0a
3 changed files with 169 additions and 178 deletions

View File

@ -41,6 +41,7 @@
#include "precomp.hpp" #include "precomp.hpp"
#include "cap_intelperc.hpp" #include "cap_intelperc.hpp"
#include "cap_dshow.hpp"
#if defined _M_X64 && defined _MSC_VER && !defined CV_ICC #if defined _M_X64 && defined _MSC_VER && !defined CV_ICC
#pragma optimize("",off) #pragma optimize("",off)
@ -115,9 +116,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
{ {
int domains[] = int domains[] =
{ {
#ifdef HAVE_DSHOW
CV_CAP_DSHOW,
#endif
#ifdef HAVE_MSMF #ifdef HAVE_MSMF
CV_CAP_MSMF, CV_CAP_MSMF,
#endif #endif
@ -175,8 +173,7 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
// try every possibly installed camera API // try every possibly installed camera API
for (int i = 0; domains[i] >= 0; i++) for (int i = 0; domains[i] >= 0; i++)
{ {
#if defined(HAVE_DSHOW) || \ #if defined(HAVE_MSMF) || \
defined(HAVE_MSMF) || \
defined(HAVE_TYZX) || \ defined(HAVE_TYZX) || \
defined(HAVE_VFW) || \ defined(HAVE_VFW) || \
defined(HAVE_LIBV4L) || \ defined(HAVE_LIBV4L) || \
@ -205,13 +202,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
switch (domains[i]) switch (domains[i])
{ {
#ifdef HAVE_DSHOW
case CV_CAP_DSHOW:
capture = cvCreateCameraCapture_DShow (index);
if (capture)
return capture;
break;
#endif
#ifdef HAVE_MSMF #ifdef HAVE_MSMF
case CV_CAP_MSMF: case CV_CAP_MSMF:
capture = cvCreateCameraCapture_MSMF (index); capture = cvCreateCameraCapture_MSMF (index);
@ -589,6 +579,9 @@ Ptr<IVideoCapture> VideoCapture::createCameraCapture(int index)
{ {
int domains[] = int domains[] =
{ {
#ifdef HAVE_DSHOW
CV_CAP_DSHOW,
#endif
#ifdef HAVE_INTELPERC #ifdef HAVE_INTELPERC
CV_CAP_INTELPERC, CV_CAP_INTELPERC,
#endif #endif
@ -607,18 +600,26 @@ Ptr<IVideoCapture> VideoCapture::createCameraCapture(int index)
// try every possibly installed camera API // try every possibly installed camera API
for (int i = 0; domains[i] >= 0; i++) for (int i = 0; domains[i] >= 0; i++)
{ {
#if defined(HAVE_INTELPERC) || \ #if defined(HAVE_DSHOW) || \
defined(HAVE_INTELPERC) || \
(0) (0)
Ptr<IVideoCapture> capture; Ptr<IVideoCapture> capture;
switch (domains[i]) switch (domains[i])
{ {
#ifdef HAVE_DSHOW
case CV_CAP_DSHOW:
capture = Ptr<IVideoCapture>(new cv::VideoCapture_DShow(index));
if (capture)
return capture;
break; // CV_CAP_DSHOW
#endif
#ifdef HAVE_INTELPERC #ifdef HAVE_INTELPERC
case CV_CAP_INTELPERC: case CV_CAP_INTELPERC:
capture = Ptr<IVideoCapture>(new cv::VideoCapture_IntelPerC()); capture = Ptr<IVideoCapture>(new cv::VideoCapture_IntelPerC());
if (capture) if (capture)
return capture; return capture;
break; // CV_CAP_INTEL_PERC break; // CV_CAP_INTEL_PERC
#endif #endif
} }
#endif #endif
@ -628,7 +629,6 @@ Ptr<IVideoCapture> VideoCapture::createCameraCapture(int index)
return Ptr<IVideoCapture>(); return Ptr<IVideoCapture>();
} }
VideoWriter::VideoWriter() VideoWriter::VideoWriter()
{} {}

View File

@ -42,6 +42,7 @@
#include "precomp.hpp" #include "precomp.hpp"
#if (defined WIN32 || defined _WIN32) && defined HAVE_DSHOW #if (defined WIN32 || defined _WIN32) && defined HAVE_DSHOW
#include "cap_dshow.hpp"
/* /*
DirectShow-based Video Capturing module is based on DirectShow-based Video Capturing module is based on
@ -455,13 +456,7 @@ class videoDevice{
}; };
////////////////////////////////////// VIDEO INPUT ///////////////////////////////////// ////////////////////////////////////// VIDEO INPUT /////////////////////////////////////
class videoInput{ class videoInput{
public: public:
@ -3098,131 +3093,53 @@ HRESULT videoInput::routeCrossbar(ICaptureGraphBuilder2 **ppBuild, IBaseFilter *
return hr; return hr;
} }
/********************* Capturing video from camera via DirectShow *********************/
class CvCaptureCAM_DShow : public CvCapture
{
public:
CvCaptureCAM_DShow();
virtual ~CvCaptureCAM_DShow();
virtual bool open( int index );
virtual void close();
virtual double getProperty(int);
virtual bool setProperty(int, double);
virtual bool grabFrame();
virtual IplImage* retrieveFrame(int);
virtual int getCaptureDomain() { return CV_CAP_DSHOW; } // Return the type of the capture object: CV_CAP_VFW, etc...
protected:
void init();
int index, width, height,fourcc;
int widthSet, heightSet;
IplImage* frame;
static videoInput VI;
};
struct SuppressVideoInputMessages struct SuppressVideoInputMessages
{ {
SuppressVideoInputMessages() { videoInput::setVerbose(false); } SuppressVideoInputMessages() { videoInput::setVerbose(false); }
}; };
static SuppressVideoInputMessages do_it; static SuppressVideoInputMessages do_it;
videoInput CvCaptureCAM_DShow::VI;
CvCaptureCAM_DShow::CvCaptureCAM_DShow() namespace cv
{ {
index = -1; videoInput VideoCapture_DShow::g_VI;
frame = 0;
width = height = fourcc = -1;
widthSet = heightSet = -1;
CoInitialize(0);
}
CvCaptureCAM_DShow::~CvCaptureCAM_DShow() VideoCapture_DShow::VideoCapture_DShow(int index)
: m_index(-1)
, m_frame(0)
, m_width(-1)
, m_height(-1)
, m_fourcc(-1)
, m_widthSet(-1)
, m_heightSet(-1)
{
CoInitialize(0);
open(index);
}
VideoCapture_DShow::~VideoCapture_DShow()
{ {
close(); close();
CoUninitialize(); CoUninitialize();
} }
void CvCaptureCAM_DShow::close() double VideoCapture_DShow::getProperty(int propIdx)
{ {
if( index >= 0 )
{ long min_value, max_value, stepping_delta, current_value, flags, defaultValue;
VI.stopDevice(index);
index = -1; switch (propIdx)
cvReleaseImage(&frame);
}
widthSet = heightSet = width = height = -1;
}
// Initialize camera input
bool CvCaptureCAM_DShow::open( int _index )
{
int devices = 0;
close();
devices = VI.listDevices(true);
if (devices == 0)
return false;
if (_index < 0 || _index > devices-1)
return false;
VI.setupDevice(_index);
if( !VI.isDeviceSetup(_index) )
return false;
index = _index;
return true;
}
bool CvCaptureCAM_DShow::grabFrame()
{
return true;
}
IplImage* CvCaptureCAM_DShow::retrieveFrame(int)
{
if( !frame || VI.getWidth(index) != frame->width || VI.getHeight(index) != frame->height )
{
if (frame)
cvReleaseImage( &frame );
int w = VI.getWidth(index), h = VI.getHeight(index);
frame = cvCreateImage( cvSize(w,h), 8, 3 );
}
if (VI.getPixels( index, (uchar*)frame->imageData, false, true ))
return frame;
else
return NULL;
}
double CvCaptureCAM_DShow::getProperty( int property_id )
{
long min_value,max_value,stepping_delta,current_value,flags,defaultValue;
// image format proprrties
switch( property_id )
{ {
// image format properties
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
return VI.getWidth(index); return g_VI.getWidth(m_index);
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
return VI.getHeight(index); return g_VI.getHeight(m_index);
case CV_CAP_PROP_FOURCC: case CV_CAP_PROP_FOURCC:
return VI.getFourcc(index); return g_VI.getFourcc(m_index);
case CV_CAP_PROP_FPS: case CV_CAP_PROP_FPS:
return VI.getFPS(index); return g_VI.getFPS(m_index);
}
// video filter properties // video filter properties
switch( property_id )
{
case CV_CAP_PROP_BRIGHTNESS: case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST: case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_HUE: case CV_CAP_PROP_HUE:
@ -3233,12 +3150,10 @@ double CvCaptureCAM_DShow::getProperty( int property_id )
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_BACKLIGHT: case CV_CAP_PROP_BACKLIGHT:
case CV_CAP_PROP_GAIN: case CV_CAP_PROP_GAIN:
if (VI.getVideoSettingFilter(index,VI.getVideoPropertyFromCV(property_id),min_value,max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value; if (g_VI.getVideoSettingFilter(m_index, g_VI.getVideoPropertyFromCV(propIdx), min_value, max_value, stepping_delta, current_value, flags, defaultValue))
} return (double)current_value;
// camera properties // camera properties
switch( property_id )
{
case CV_CAP_PROP_PAN: case CV_CAP_PROP_PAN:
case CV_CAP_PROP_TILT: case CV_CAP_PROP_TILT:
case CV_CAP_PROP_ROLL: case CV_CAP_PROP_ROLL:
@ -3246,33 +3161,33 @@ double CvCaptureCAM_DShow::getProperty( int property_id )
case CV_CAP_PROP_EXPOSURE: case CV_CAP_PROP_EXPOSURE:
case CV_CAP_PROP_IRIS: case CV_CAP_PROP_IRIS:
case CV_CAP_PROP_FOCUS: case CV_CAP_PROP_FOCUS:
if (VI.getVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),min_value,max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value; if (g_VI.getVideoSettingCamera(m_index, g_VI.getCameraPropertyFromCV(propIdx), min_value, max_value, stepping_delta, current_value, flags, defaultValue))
return (double)current_value;
} }
// unknown parameter or value not available // unknown parameter or value not available
return -1; return -1;
} }
bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
bool CvCaptureCAM_DShow::setProperty( int property_id, double value )
{ {
// image capture properties // image capture properties
bool handled = false; bool handled = false;
switch( property_id ) switch (propIdx)
{ {
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
width = cvRound(value); m_width = cvRound(propVal);
handled = true; handled = true;
break; break;
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
height = cvRound(value); m_height = cvRound(propVal);
handled = true; handled = true;
break; break;
case CV_CAP_PROP_FOURCC: case CV_CAP_PROP_FOURCC:
fourcc = (int)(unsigned long)(value); m_fourcc = (int)(unsigned long)(propVal);
if ( fourcc == -1 ) { if (-1 == m_fourcc)
{
// following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1 // following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1
// TODO - how to create a capture pin dialog // TODO - how to create a capture pin dialog
} }
@ -3280,38 +3195,38 @@ bool CvCaptureCAM_DShow::setProperty( int property_id, double value )
break; break;
case CV_CAP_PROP_FPS: case CV_CAP_PROP_FPS:
int fps = cvRound(value); int fps = cvRound(propVal);
if (fps != VI.getFPS(index)) if (fps != g_VI.getFPS(m_index))
{ {
VI.stopDevice(index); g_VI.stopDevice(m_index);
VI.setIdealFramerate(index,fps); g_VI.setIdealFramerate(m_index, fps);
if (widthSet > 0 && heightSet > 0) if (m_widthSet > 0 && m_heightSet > 0)
VI.setupDevice(index, widthSet, heightSet); g_VI.setupDevice(m_index, m_widthSet, m_heightSet);
else else
VI.setupDevice(index); g_VI.setupDevice(m_index);
} }
return VI.isDeviceSetup(index); return g_VI.isDeviceSetup(m_index);
} }
if ( handled ) { if (handled)
{
// a stream setting // a stream setting
if( width > 0 && height > 0 ) if (m_width > 0 && m_height > 0)
{ {
if( width != VI.getWidth(index) || height != VI.getHeight(index) )//|| fourcc != VI.getFourcc(index) ) if (m_width != g_VI.getWidth(m_index) || m_height != g_VI.getHeight(m_index) )//|| fourcc != VI.getFourcc(index) )
{ {
int fps = static_cast<int>(VI.getFPS(index)); int fps = static_cast<int>(g_VI.getFPS(m_index));
VI.stopDevice(index); g_VI.stopDevice(m_index);
VI.setIdealFramerate(index, fps); g_VI.setIdealFramerate(m_index, fps);
VI.setupDeviceFourcc(index, width, height, fourcc); g_VI.setupDeviceFourcc(m_index, m_width, m_height, m_fourcc);
} }
bool success = VI.isDeviceSetup(index); bool success = g_VI.isDeviceSetup(m_index);
if (success) if (success)
{ {
widthSet = width; m_widthSet = m_width;
heightSet = height; m_heightSet = m_height;
width = height = fourcc = -1; m_width = m_height = m_fourcc = -1;
} }
return success; return success;
} }
@ -3319,13 +3234,14 @@ bool CvCaptureCAM_DShow::setProperty( int property_id, double value )
} }
// show video/camera filter dialog // show video/camera filter dialog
if ( property_id == CV_CAP_PROP_SETTINGS ) { if (propIdx == CV_CAP_PROP_SETTINGS )
VI.showSettingsWindow(index); {
g_VI.showSettingsWindow(m_index);
return true; return true;
} }
//video Filter properties //video Filter properties
switch( property_id ) switch (propIdx)
{ {
case CV_CAP_PROP_BRIGHTNESS: case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST: case CV_CAP_PROP_CONTRAST:
@ -3337,11 +3253,11 @@ bool CvCaptureCAM_DShow::setProperty( int property_id, double value )
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_BACKLIGHT: case CV_CAP_PROP_BACKLIGHT:
case CV_CAP_PROP_GAIN: case CV_CAP_PROP_GAIN:
return VI.setVideoSettingFilter(index,VI.getVideoPropertyFromCV(property_id),(long)value); return g_VI.setVideoSettingFilter(m_index, g_VI.getVideoPropertyFromCV(propIdx), (long)propVal);
} }
//camera properties //camera properties
switch( property_id ) switch (propIdx)
{ {
case CV_CAP_PROP_PAN: case CV_CAP_PROP_PAN:
case CV_CAP_PROP_TILT: case CV_CAP_PROP_TILT:
@ -3350,30 +3266,56 @@ bool CvCaptureCAM_DShow::setProperty( int property_id, double value )
case CV_CAP_PROP_EXPOSURE: case CV_CAP_PROP_EXPOSURE:
case CV_CAP_PROP_IRIS: case CV_CAP_PROP_IRIS:
case CV_CAP_PROP_FOCUS: case CV_CAP_PROP_FOCUS:
return VI.setVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),(long)value); return g_VI.setVideoSettingCamera(m_index, g_VI.getCameraPropertyFromCV(propIdx), (long)propVal);
} }
return false; return false;
} }
bool VideoCapture_DShow::grabFrame()
CvCapture* cvCreateCameraCapture_DShow( int index )
{ {
CvCaptureCAM_DShow* capture = new CvCaptureCAM_DShow; return true;
}
bool VideoCapture_DShow::retrieveFrame(int, OutputArray frame)
{
frame.create(Size(g_VI.getWidth(m_index), g_VI.getHeight(m_index)), CV_8UC3);
cv::Mat mat = frame.getMat();
return g_VI.getPixels(m_index, mat.ptr(), false, true );
}
int VideoCapture_DShow::getCaptureDomain()
{
return CV_CAP_DSHOW;
}
bool VideoCapture_DShow::isOpened() const
{
return (-1 != m_index);
}
try void VideoCapture_DShow::open(int index)
{ {
if( capture->open( index )) close();
return capture; int devices = g_VI.listDevices(true);
} if (0 == devices)
catch(...) return;
{ if (index < 0 || index > devices-1)
delete capture; return;
throw; g_VI.setupDevice(index);
} if (!g_VI.isDeviceSetup(index))
return;
m_index = index;
}
void VideoCapture_DShow::close()
{
if (m_index >= 0)
{
g_VI.stopDevice(m_index);
m_index = -1;
cvReleaseImage(&m_frame);
}
m_widthSet = m_heightSet = m_width = m_height = -1;
}
delete capture;
return 0;
} }
#endif #endif

View File

@ -0,0 +1,49 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// This file is part of OpenCV project.
// 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.
//
// Copyright (C) 2014, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
//M*/
#ifndef _CAP_DSHOW_HPP_
#define _CAP_DSHOW_HPP_
#include "precomp.hpp"
#ifdef HAVE_DSHOW
class videoInput;
namespace cv
{
class VideoCapture_DShow : public IVideoCapture
{
public:
VideoCapture_DShow(int index);
virtual ~VideoCapture_DShow();
virtual double getProperty(int propIdx);
virtual bool setProperty(int propIdx, double propVal);
virtual bool grabFrame();
virtual bool retrieveFrame(int outputType, OutputArray frame);
virtual int getCaptureDomain();
bool isOpened() const;
protected:
void open(int index);
void close();
int m_index, m_width, m_height, m_fourcc;
int m_widthSet, m_heightSet;
IplImage* m_frame;
static videoInput g_VI;
};
}
#endif //HAVE_DSHOW
#endif //_CAP_DSHOW_HPP_