OpenCV读取与操作摄像头
OpenCV读取摄像头
OpenCV可以读取摄像头的图像,主要是流媒体,读取的类是cv::VideoCapture,输入参数为摄像头参数:
当使用USB摄像头时,输入0,1,2…等对应参数
当使用网络摄像头时,直接输入url地址。
OpenCV设置属性
使用cv::VieoCapture时,先生成一个实例,然后设置属性,此时有一点
要注意,当读取的图片原本只有400*300时,设置高宽800*600是无效的(即
超过输入的尺寸设置是无效的),然后不断使用>>读取,读取就显示。
cv::VideoCapture capture;
if(!capture.open(0))
{
qDebug() << __FILE__ << __LINE__ << "Failed to open camera: 0";
}else{
qDebug() << __FILE__ << __LINE__ << "Succeed to open camera: 0";
}
while(true)
{
cv::Mat mat;
capture >> mat;
int keyValue = cv::waitKey(1)
}
同时经过测试发现,此次打开的是上次的设置结果,所以可以判断opencv
实际是直接操作了设备的相关属性,所以调整的属性需要摄像头设备支持(USB 摄像头),并不是单纯的认为拿到图片后opencv自己对图像进行处理。
Demo函数源码
void OpenCVManager::testCamera()
{
cv::VideoCapture capture;
// 插入USB摄像头默认为0
if(!capture.open(0))
{
qDebug() << __FILE__ << __LINE__ << "Failed to open camera: 0"; }else{
qDebug() << __FILE__ << __LINE__ << "Succeed to open camera: 0"; }
capture.set(cv::CAP_PROP_FRAME_WIDTH , 800);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
// 初始亮度为0,范围为-50 ~ 50,范围区间100
double brightness = 0;
double contrast = 0;
double saturation = 0;
double hue = 0;
double gain = 0;
double exposure = 0;
brightness = capture.get(cv::CAP_PROP_BRIGHTNESS);
contrast = capture.get(cv::CAP_PROP_CONTRAST);
saturation = capture.get(cv::CAP_PROP_SATURATION);
hue = capture.get(cv::CAP_PROP_HUE);
gain = capture.get(cv::CAP_PROP_GAIN);
exposure = capture.get(cv::CAP_PROP_EXPOSURE);
qDebug() << "=========================";
qDebug() << "初始亮度:" << brightness;
qDebug() << "初始对比度:" << contrast;
qDebug() << "初始饱和度:" << saturation;
qDebug() << "初始色调:" << hue ;
qDebug() << "初始增益:" << gain;
qDebug() << "初始曝光度:" << exposure;
qDebug() << "=========================";
while(true)
{
cv::Mat mat;
capture >> mat;
if(!mat.empty())
{
cv::putText(mat, QString("brightness: %1").arg(brightness).toStdString(),
cvPoint(0, 30), cv::FONT_HERSHEY_COMPLEX, 1.0,
cv::Scalar(255));
cv::putText(mat, QString(" contrast: %1").arg(contrast ).toStdString(),
cvPoint(0, 60), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255)); cv::putText(mat, QString("saturation: %1").arg(saturation).toStdString(),
cvPoint(0, 90), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255)); cv::putText(mat, QString(" hue: %1").arg(hue ).toStdString(),
cvPoint(0, 120), cv::FONT_HERSHEY_COMPLEX, 1.0,
cv::Scalar(255));
cv::putText(mat, QString(" gain: %1").arg(gain ).toStdString(),
cvPoint(0, 150), cv::FONT_HERSHEY_COMPLEX, 1.0,
cv::Scalar(255));
cv::putText(mat, QString(" exposure: %1").arg(exposure ).toStdString(),
cvPoint(0, 180), cv::FONT_HERSHEY_COMPLEX, 1.0,
cv::Scalar(255));
cv::putText(mat, QString("press ESC out").toStdString(),
cvPoint(0, 210), cv::FONT_HERSHEY_COMPLEX, 1.0,
cv::Scalar(255));
cv::imshow(_windowTitle.toStdString(), mat);
}
int keyValue = cv::waitKey(1);
switch (keyValue)
{
case 27: // ESC
capture.release();
return;
break;
case '1': // 增加亮度
brightness += 1;
capture.set(cv::CAP_PROP_BRIGHTNESS, brightness);
qDebug() << __FILE__ << __LINE__ << "调整亮度:" << brightness; break;
case '2': // 降低亮度
brightness -= 1;
capture.set(cv::CAP_PROP_BRIGHTNESS, brightness);
qDebug() << __FILE__ << __LINE__ << "调整亮度:" << brightness; break;
case '3': // 增加对比度
contrast += 1;
capture.set(cv::CAP_PROP_CONTRAST, contrast);
qDebug() << __FILE__ << __LINE__ << "调整对比度:" << contrast; break;
case '4': // 降低对比度
contrast -= 1;
capture.set(cv::CAP_PROP_CONTRAST, contrast);
qDebug() << __FILE__ << __LINE__ << "调整对比度:" << contrast; break;
case '5': // 增加饱和度
saturation += 1;
capture.set(cv::CAP_PROP_SATURATION, saturation);
qDebug() << __FILE__ << __LINE__ << "调整饱和度:" << saturation; break;
case '6': // 降低饱和度
saturation -= 1;
capture.set(cv::CAP_PROP_SATURATION, saturation);
qDebug() << __FILE__ << __LINE__ << "调整饱和度:" << saturation; break;
case '7': // 增加色调
hue += 1;
capture.set(cv::CAP_PROP_HUE, hue);
qDebug() << __FILE__ << __LINE__ << "调整色调:" << hue;
break;
case '8': // 降低色调
hue -= 1;
capture.set(cv::CAP_PROP_HUE, hue);
qDebug() << __FILE__ << __LINE__ << "调整色调:" << hue;
break;
case '9': // 增加增益
gain += 1;
capture.set(cv::CAP_PROP_GAIN, gain);
qDebug() << __FILE__ << __LINE__ << "调整增益:" << gain;
break;
case '0': // 降低增益
gain -= 1;
capture.set(cv::CAP_PROP_GAIN, gain);
qDebug() << __FILE__ << __LINE__ << "调整增益:" << gain;
break;
case '-': // 增加曝光
exposure += 1;
capture.set(cv::CAP_PROP_EXPOSURE, exposure);
qDebug() << __FILE__ << __LINE__ << "调整曝光:" << exposure;
break;
case '=': // 降低曝光
exposure -= 1;
capture.set(cv::CAP_PROP_EXPOSURE, exposure);
qDebug() << __FILE__ << __LINE__ << "调整曝光:" << exposure;
break;
default:
break;
}
}
}
拓展:视频属性
OpenCV中提供了一个函数,来获取视频文件的一些属性:
cvGetCaptureProperty(Capture* cap,int property_index);
相机的画,可以直接使用cv::VedioCapture::get()。
同样也提供了对应的设置函数:
int cvSetCaptureProperty(CvCapture* capture, int property_id, double value);
相机的画,可以直接使用cv::VedioCapture::set()。
注意:目前这个函数对视频文件只支持以下三个属性:
CV_CAP_PROP_POS_MSEC:从文件开始的位置计算,单位为毫秒
CV_CAP_PROP_POS_FRAMES:当前帧的索引(基于0)
CV_CAP_PROP_POS_AVI_RATIO:视频文件的相对位置(0=开始,1=结束)
读/写属性涉及许多层。沿着这条链可能会发生一些意想不到的结果。行为是否有效取决于设备硬件、驱动程序和api后端。