急需在windows环境下的qt对UVC摄像头的开发源码,并且运行环境是64位的,只需实现简单拍照功能即可,但图片要求可以用opencv进行处理和计算。
cam.h 代码
#ifndef __CAM_H_
#define __CAM_H_
#include iostream>
#include sys/ioctl.h>
#include fcntl.h>
#include linux/videodev2.h>
#include sys/mman.h>
#include stdio.h>
#include string.h>
#include errno.h>
#include unistd.h>
#include QTimer>
using namespace std;
#define WEIGHT_DEFAULT 640
#define HEIGHT_DEFAULT 480
#define PROP_WEIGHT 0
#define PROP_HEIGHT 1
#define PROP_FPS 2
#define PROP_BRIGHTNESS 10
#define PROP_CONTRAST 11
#define PROP_HUE 12
#define PROP_GAIN 13
#define PROP_EXPOSURE 14
#define BUFFER_NUMS 2
#define STREAMON true
#define STREAMOFF false
#define CLEAR(x) memset (&(x), 0, sizeof (x))
typedef unsigned char uchar;//#define uchar unsigned char //
class Opera_Cam
{
public:
Opera_Cam();
Opera_Cam(int which_cam);
Opera_Cam(const string& cam_name);
bool Open(int which_cam=0);
bool Open(const string& cam_name);
bool IsOpened(){return Opened;}
bool Read();//(uchar **data, int& used_len);
bool Set(int propId, int value);
int Get(int propId);
int GetDataLen(){return data_len;};
//Opera_Cam& operator>>(uchar **dst);
virtual ~Opera_Cam();
struct DataInfo
{
uchar *data;
int real_len;
};
DataInfo df;
int weight,height;
void Free();
private:
void Init_Prop();
bool Init_V4l2();
bool Operation(bool on_off);
void GetFrameLoop();
int GetFrameV4l2();
//unsigned char* rgbbuf[CAM_MAX];
void *vsimg[BUFFER_NUMS] ;
struct v4l2_buffer mybuffer;
struct v4l2_capability mycap;
struct v4l2_format myfmt;
struct v4l2_requestbuffers myreq;
struct v4l2_streamparm mysetfps;
struct timeval timestamp;
int cam_fd,data_len;
bool MmapOK[BUFFER_NUMS];
bool Opened,getframeok;
};
#endif
-------------------------------------------------------------------------------------------------------------------
cam.cpp 的代码
#include "cam.h"
typedef unsigned char uchar;//#define uchar unsigned char //
Opera_Cam::Opera_Cam()
{
Init_Prop();
}
Opera_Cam::Opera_Cam(int which_cam)
{
Init_Prop();
Opened = Open(which_cam);
}
Opera_Cam::Opera_Cam(const string& cam_name)
{
Init_Prop();
Opened = Open(cam_name);
}
bool Opera_Cam::Open(int which_cam)
{
char cam_name[80];
sprintf(cam_name, "/dev/video", which_cam);
string str = cam_name;
return Open(str);
}
#if 1
bool Opera_Cam::Open(const string& cam_name)
{
if(IsOpened())
Free();
string str = cam_name;
if(0!=access(str.c_str(),F_OK))
{
return false;
}
cam_fd = open(str.c_str(),O_RDWR | O_NONBLOCK,0);
if(cam_fd<0)
return false;
if(!Init_V4l2())
return false;
data_len = weight*height*2;
Opened = true;
return Opened;
}
#endif
void Opera_Cam::Init_Prop()
{
cam_fd = -1;
Opened = false;
weight = WEIGHT_DEFAULT;
height = HEIGHT_DEFAULT;
data_len = -1;
for(int i=0;i
MmapOK[i] = false;
}
bool Opera_Cam::Init_V4l2()
{
CLEAR(mybuffer);
CLEAR(mycap);
if(ioctl(cam_fd,VIDIOC_QUERYCAP,&mycap)<0)
{
return false;
}
CLEAR(myfmt);
myfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
myfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;//V4L2_PIX_FMT_MJPEG;//V4L2_PIX_FMT_YUYV;//
myfmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
myfmt.fmt.pix.width = weight;
myfmt.fmt.pix.height = height;
if(ioctl(cam_fd,VIDIOC_S_FMT,&myfmt)<0)
{
printf("VIDIOC_S_FMT is failed!\n");
return false;
}
myfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl(cam_fd,VIDIOC_G_FMT,&myfmt);
if(myfmt.fmt.pix.pixelformat&V4L2_PIX_FMT_YUYV)//V4L2_PIX_FMT_YUYV)
CLEAR(myreq);
myreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
myreq.memory = V4L2_MEMORY_MMAP;
myreq.count = BUFFER_NUMS;
if(ioctl(cam_fd,VIDIOC_REQBUFS,&myreq)<0)
{
return false;
}
for(int i = 0; i< (int)myreq.count;i++)
{
CLEAR(mybuffer);
mybuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
mybuffer.memory = V4L2_MEMORY_MMAP;
mybuffer.index = i;
if(ioctl(cam_fd,VIDIOC_QUERYBUF,&mybuffer)<0)
{
return false;
}
vsimg[i] = mmap(0,mybuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,cam_fd,mybuffer.m.offset);
if(vsimg[i] == MAP_FAILED)
{
return false;
}
MmapOK[i] = true;
}
for(int i = 0;i< (int)myreq.count;i++)
{
CLEAR(mybuffer);
mybuffer.index = i;
mybuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
mybuffer.memory = V4L2_MEMORY_MMAP;
if(ioctl(cam_fd,VIDIOC_QBUF,&mybuffer)<0)
{
for(int i=0;i
{
if(MmapOK[i])
munmap(vsimg[i] ,mybuffer.length);
}
return false;
}
}
mybuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(cam_fd,VIDIOC_STREAMON,&(mybuffer.type))<0)
{
if(ioctl(cam_fd,VIDIOC_STREAMOFF,&(mybuffer.type))<0)
;
for(int i=0;i
{
if(MmapOK[i])
munmap(vsimg[i] ,mybuffer.length);
}
close(cam_fd);
return false;
}
mybuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
mybuffer.memory = V4L2_MEMORY_MMAP;
return true;
}
bool Opera_Cam::Read()//(uchar **data,int& used_len)
{
GetFrameLoop();
if(!getframeok)
return false;
df.real_len = mybuffer.bytesused; //used_len = mybuffer.bytesused;//mybuffer.length;
//data_len = mybuffer.length;
df.data = (uchar *)vsimg[mybuffer.index];/
printf ("VIDIOC_DQBUF FAILED\n");
return 1;
}
}
//printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n",
// buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused);
if (-1==ioctl (cam_fd, VIDIOC_QBUF, &mybuffer))
printf("VIDIOC_QBUF FAILED\n");
getframeok = true;
timestamp = mybuffer.timestamp;
return 2;
}
void Opera_Cam::Free()
{
Operation(STREAMOFF);
for(int i=0;i
{
if(MmapOK[i])
munmap(vsimg[i] ,mybuffer.length);
}
Opened = false;
if(cam_fd>0)
close(cam_fd);
}
Opera_Cam::~Opera_Cam()
{
Free();
}
-------------------------------------------------------------------------------------------------------------------
qt部分代码 widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include QWidget>
#include QPixmap>
#include QImage>
#include "cam.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
unsigned char *jpeg_buf = NULL;
private slots:
void on_pushButton_clicked();
void flush_cam();
private:
Ui::Widget *ui;
Opera_Cam ope;
QTimer *timer;
QPixmap mp;
QImage image;
};
#endif // WIDGET_H
-----------------------------------------------------------------------------------------------------------------
widget.cpp 代码
#include "widget.h"
#include "ui_widget.h"
#include QDebug>
int ii = 0;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
timer = new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(flush_cam()));
ui->label->setGeometry(10,10,320,240);
ui->label->setScaledContents(true);
ui->pushButton->setGeometry(320,530,30,20);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
qDebug()<<"111111111111";
ope.Open("/dev/video0");
usleep(100*1000);
ii = 0;
timer->start(20);
}
void Widget::flush_cam()
{
ii++;
ope.Read();
jpeg_buf = (unsigned char *)malloc(ope.df.real_len);
memcpy(jpeg_buf, ope.df.data, ope.df.real_len);
image.loadFromData(jpeg_buf,ope.df.real_len,"jpg");
mp = mp.fromImage(image);
ui->label->setPixmap(mp);
ui->label->show();
free(jpeg_buf);
if(ii == 200)
{
timer->stop();
ope.Free();
}
}
#ifdef Q_CC_MSVC
#include "Windows.h"
#include "dshow.h"
#include "strmif.h"
#include "ks.h"
#include "ksproxy.h"
#include "ksmedia.h"
# pragma comment(lib, "strmiids.lib")
# pragma comment(lib, "ole32.lib")
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
#endif // Q_CC_MSVC
#ifdef Q_CC_MSVC
IBaseFilter* srcFilter;
#endif
bool deviceFilter(const QString &device)
{
#ifdef Q_CC_MSVC
srcFilter = nullptr;
ICreateDevEnum* pDevEnum = nullptr;
IEnumMoniker* pEnum = nullptr;
// Create the System device enumerator
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr)) {
// Create the enumerator for the video capture category
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pEnum, 0);
if (S_OK == hr) {
pEnum->Reset();
// go through and find all video capture devices
IMoniker* pMoniker = nullptr;
IMalloc *mallocInterface = 0;
CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
while (pEnum->Next(1, &pMoniker, nullptr) == S_OK) {
BSTR strName = 0;
hr = pMoniker->GetDisplayName(nullptr, nullptr, &strName);
if (SUCCEEDED(hr)) {
QString output(QString::fromWCharArray(strName));
mallocInterface->Free(strName);
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag,
reinterpret_cast<void**>(&pPropBag));
if (SUCCEEDED(hr)) {
// Find the description
VARIANT varName;
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr)) {
output = QString::fromWCharArray(varName.bstrVal);
}
pPropBag->Release();
// qDebug() << output << device;
if( output == device ) {
hr = pMoniker->BindToObject(0,
0,
IID_IBaseFilter,
reinterpret_cast<void**>(&srcFilter));
qDebug() << "get device control:" << output;
}
}
}
pMoniker->Release();
}
mallocInterface->Release();
pEnum->Release();
}
pDevEnum->Release();
}
if( srcFilter == nullptr ) {
return false;
}
#endif
return true;
}
bool UVControl(const LONG &value)
{
#ifdef Q_CC_MSVC
if( srcFilter == nullptr ) {
return false;
}
IKsControl *pCtl = nullptr;
HRESULT hr;
hr = srcFilter->QueryInterface(IID_IKsControl, reinterpret_cast<void **>(&pCtl));
if( FAILED(hr) ) {
return false;
}
KSPROPERTY property;
ZeroMemory(&property, sizeof(property));
property.Set = PROPSETID_VIDCAP_CAMERACONTROL;
property.Id = KSPROPERTY_CAMERACONTROL_ZOOM;
property.Flags = KSPROPERTY_TYPE_SET;
ULONG valueSize = 0;
ULONG ksLength = 0;
ULONG dataLength = 0;
KSPROPERTY_CAMERACONTROL_S devCtl;
ZeroMemory(&devCtl, sizeof(devCtl));
ksLength = sizeof(devCtl);
dataLength = sizeof(devCtl);
devCtl.Property = property;
devCtl.Flags = KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
devCtl.Capabilities = KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
devCtl.Value = value;
hr = pCtl->KsProperty((PKSPROPERTY)&devCtl, ksLength, &devCtl, dataLength, &valueSize);
SAFE_RELEASE(pCtl);
#endif
return true;
}
最好是打包来的,有库文件直接可以编译的
前2个回答应该就是调用摄像头的源码,我就不再赘述。但是要保证图片可以被opencv使用,还需要保证文件的类型为opencv支持的图片类型
OpenCV目前支持的图像格式包括:
Windows位图文件 - BMP, DIB;
JPEG文件 - JPEG, JPG, JPE;
便携式网络图片 - PNG;
便携式图像格式 - PBM,PGM,PPM;
Sun rasters - SR,RAS;
TIFF文件 - TIFF,TIF;
OpenEXR HDR 图片 - EXR;
JPEG 2000 图片- jp2。
你可以试试下面的开源项目
https://github.com/erikmwerner/QUVCView
直接用开源的网页即可
UVC摄像头 是什么协议呀
OpenCV目前支持的图像格式包括:
Windows位图文件 - BMP, DIB;
JPEG文件 - JPEG, JPG, JPE;
便携式网络图片 - PNG;
便携式图像格式 - PBM,PGM,PPM;
Sun rasters - SR,RAS;
TIFF文件 - TIFF,TIF;
OpenEXR HDR 图片 - EXR;
JPEG 2000 图片- jp2。
你可以试试下面的开源项目https://github.com/erikmwerner/1UVCView
这个开源项目不错,看过了,挺适合的 https://github.com/erikmwerner/QUVCView