OpenCv4.4.0+Qt:摄像头控制

2024-06-01 22:48
文章标签 qt 摄像头 控制 opencv4.4

本文主要是介绍OpenCv4.4.0+Qt:摄像头控制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

OpenCv4.4.0+Qt:摄像头控制

简介

在上一篇中讲解了 OpenCv4.4.0+Qt5.12.2+OpenCv-Contrib-4.4.0 的 安装与测试例程,这篇中讲解摄像头的控制,摄像头列表的选择,参数控制,拍照,视频录制。

OpenCv中摄像头的相关的主要有两个模块, VideoCapture / VideoWrite 视频捕捉与视频写入模块。

思路

利用思路利用Qt自带的QCamera相关类以及QLabel,利用OpenCv 的 VideoCapture 和 VideoWriter 负责视频捕捉以及录制。

摄像头选择

利用QCameraInfo 类提供的接口获取摄像头列表,列表ID即为OpenCv摄像头ID号。博主本人测试过两个摄像头,未测试3个以上。获取摄像头列表后与QComBox绑定,来设置选择摄像头。

视频捕捉

利用VideoCapture 打开摄像头,read定时获取当前帧,输出到QLabel显示视频。

参数设置

QCamera与QCameraInfo获取摄像头支持分辨率,帧率,编码格式支持列表,与QComBox绑定,来设置相关参数。

利用get与set获取 清晰度,白平衡,对比度,亮度,色调,增益等相关属性值并进行设置。

拍照

利用QImage将当前帧保存。

录像

利用VideoWrite 将视频帧挨个写入视频文件。

API接口详解

只解释说明关键性接口。

OpenCv

    /** @brief  Opens a video file or a capturing device or an IP video stream for video capturing.@overloadParameters are same as the constructor VideoCapture(const String& filename, int apiPreference = CAP_ANY)@return `true` if the file has been successfully opened*/CV_WRAP virtual bool open(const String& filename, int apiPreference = CAP_ANY);

上述接口,打开一个视频捕捉驱动或者视频流URL串。

/** @brief  Opens a camera for video capturing@overloadParameters are same as the constructor VideoCapture(int index, int apiPreference = CAP_ANY)@return `true` if the camera has been successfully opened.*/CV_WRAP virtual bool open(int index, int apiPreference = CAP_ANY);

上述接口。打开一个摄像头。其中Index为当摄像头设备接入PC时,底层驱动给做的一个设备排序。笔记本自带摄像头通常为 0,外接设备从1开始排序。通常大家都是使用DirtShow或者修改底层源码。在这里笔者使用了QCameraInfo来获取摄像头ID,笔者为笔记本,外接一个USB摄像头设备,驱动ID是正确的。三个及三个以上手头设备有限未做测试,留待以后。

    /** @brief Closes video file or capturing device.The method is automatically called by subsequent VideoCapture::open and by VideoCapturedestructor.The C function also deallocates memory and clears \*capture pointer.*/CV_WRAP virtual void release();

上述接口,关闭摄像头驱动或者视频文件,也可以清除已使用内存和清除摄像头节点。

   /** @brief Grabs, decodes and returns the next video frame.@param [out] image the video frame is returned here. If no frames has been grabbed the image will be empty.@return `false` if no frames has been grabbedThe method/function combines VideoCapture::grab() and VideoCapture::retrieve() in one call. This is themost convenient method for reading video files or capturing data from decode and returns the justgrabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no moreframes in video file), the method returns false and the function returns empty image (with %cv::Mat, test it with Mat::empty()).@note In @ref videoio_c "C API", functions cvRetrieveFrame() and cv.RetrieveFrame() return image stored inside the videocapturing structure. It is not allowed to modify or release the image! You can copy the frame usingcvCloneImage and then do whatever you want with the copy.*/CV_WRAP virtual bool read(OutputArray image);

上述接口,用来读取下一个视频帧。如果视频帧为空则为获取失败或者返回false.

    /** @brief Sets a property in the VideoCapture.@param propId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...)or one from @ref videoio_flags_others@param value Value of the property.@return `true` if the property is supported by backend used by the VideoCapture instance.@note Even if it returns `true` this doesn't ensure that the propertyvalue has been accepted by the capture device. See note in VideoCapture::get()*/CV_WRAP virtual bool set(int propId, double value);

上述接口,用来设置摄像头的一个相关属性。

    /** @brief Returns the specified VideoCapture property@param propId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...)or one from @ref videoio_flags_others@return Value for the specified property. Value 0 is returned when querying a property that isnot supported by the backend used by the VideoCapture instance.@note Reading / writing properties involves many layers. Some unexpected result might happensalong this chain.@code{.txt}VideoCapture -> API Backend -> Operating System -> Device Driver -> Device Hardware@endcodeThe returned value might be different from what really used by the device or it could be encodedusing device dependent rules (eg. steps or percentage). Effective behaviour depends from devicedriver and API Backend*/CV_WRAP virtual double get(int propId) const;

类比于ser,get使用来获取一个属性的当前的设置值。

/** @brief %VideoCapture generic properties identifier.Reading / writing properties involves many layers. Some unexpected result might happens along this chain.Effective behaviour depends from device hardware, driver and API Backend.@sa videoio_flags_others, VideoCapture::get(), VideoCapture::set()
*/
enum VideoCaptureProperties {CAP_PROP_POS_MSEC       =0, //!< Current position of the video file in milliseconds.CAP_PROP_POS_FRAMES     =1, //!< 0-based index of the frame to be decoded/captured next.CAP_PROP_POS_AVI_RATIO  =2, //!< Relative position of the video file: 0=start of the film, 1=end of the film.CAP_PROP_FRAME_WIDTH    =3, //!< Width of the frames in the video stream.CAP_PROP_FRAME_HEIGHT   =4, //!< Height of the frames in the video stream.CAP_PROP_FPS            =5, //!< Frame rate.CAP_PROP_FOURCC         =6, //!< 4-character code of codec. see VideoWriter::fourcc .CAP_PROP_FRAME_COUNT    =7, //!< Number of frames in the video file.CAP_PROP_FORMAT         =8, //!< Format of the %Mat objects (see Mat::type()) returned by VideoCapture::retrieve().//!< Set value -1 to fetch undecoded RAW video streams (as Mat 8UC1).CAP_PROP_MODE           =9, //!< Backend-specific value indicating the current capture mode.CAP_PROP_BRIGHTNESS    =10, //!< Brightness of the image (only for those cameras that support).CAP_PROP_CONTRAST      =11, //!< Contrast of the image (only for cameras).CAP_PROP_SATURATION    =12, //!< Saturation of the image (only for cameras).CAP_PROP_HUE           =13, //!< Hue of the image (only for cameras).CAP_PROP_GAIN          =14, //!< Gain of the image (only for those cameras that support).CAP_PROP_EXPOSURE      =15, //!< Exposure (only for those cameras that support).CAP_PROP_CONVERT_RGB   =16, //!< Boolean flags indicating whether images should be converted to RGB. <br/>//!< *GStreamer note*: The flag is ignored in case if custom pipeline is used. It's user responsibility to interpret pipeline output.CAP_PROP_WHITE_BALANCE_BLUE_U =17, //!< Currently unsupported.CAP_PROP_RECTIFICATION =18, //!< Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently).CAP_PROP_MONOCHROME    =19,CAP_PROP_SHARPNESS     =20,CAP_PROP_AUTO_EXPOSURE =21, //!< DC1394: exposure control done by camera, user can adjust reference level using this feature.CAP_PROP_GAMMA         =22,CAP_PROP_TEMPERATURE   =23,CAP_PROP_TRIGGER       =24,CAP_PROP_TRIGGER_DELAY =25,CAP_PROP_WHITE_BALANCE_RED_V =26,CAP_PROP_ZOOM          =27,CAP_PROP_FOCUS         =28,CAP_PROP_GUID          =29,CAP_PROP_ISO_SPEED     =30,CAP_PROP_BACKLIGHT     =32,CAP_PROP_PAN           =33,CAP_PROP_TILT          =34,CAP_PROP_ROLL          =35,CAP_PROP_IRIS          =36,CAP_PROP_SETTINGS      =37, //!< Pop up video/camera filter dialog (note: only supported by DSHOW backend currently. The property value is ignored)CAP_PROP_BUFFERSIZE    =38,CAP_PROP_AUTOFOCUS     =39,CAP_PROP_SAR_NUM       =40, //!< Sample aspect ratio: num/den (num)CAP_PROP_SAR_DEN       =41, //!< Sample aspect ratio: num/den (den)CAP_PROP_BACKEND       =42, //!< Current backend (enum VideoCaptureAPIs). Read-only propertyCAP_PROP_CHANNEL       =43, //!< Video input or Channel Number (only for those cameras that support)CAP_PROP_AUTO_WB       =44, //!< enable/ disable auto white-balanceCAP_PROP_WB_TEMPERATURE=45, //!< white-balance color temperatureCAP_PROP_CODEC_PIXEL_FORMAT =46,    //!< (read-only) codec's pixel format. 4-character code - see VideoWriter::fourcc . Subset of [AV_PIX_FMT_*](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/raw.c) or -1 if unknownCAP_PROP_BITRATE       =47, //!< (read-only) Video bitrate in kbits/s
#ifndef CV_DOXYGENCV__CAP_PROP_LATEST
#endif};

VideoCapture枚举属性列表。

    /** @brief Initializes or reinitializes video writer.The method opens video writer. Parameters are the same as in the constructorVideoWriter::VideoWriter.@return `true` if video writer has been successfully initializedThe method first calls VideoWriter::release to close the already opened file.*/CV_WRAP virtual bool open(const String& filename, int fourcc, double fps,Size frameSize, bool isColor = true);/** @overload*/CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,Size frameSize, bool isColor = true);/** @overload*/CV_WRAP bool open(const String& filename, int fourcc, double fps, const Size& frameSize,const std::vector<int>& params);/** @overload*/CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,const Size& frameSize, const std::vector<int>& params);

设置视频保存属性-名称-帧率-编码-分辨率

    /** @brief Concatenates 4 chars to a fourcc code@return a fourcc codeThis static method constructs the fourcc code of the codec to be used in the constructorVideoWriter::VideoWriter or VideoWriter::open.*/CV_WRAP static int fourcc(char c1, char c2, char c3, char c4);
// FIXIT OpenCV 4.0: make inlineint VideoWriter::fourcc(char c1, char c2, char c3, char c4){return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);}

获取视频编码格式对应的枚举ID值

编码对应ID以及音视频支持格式

编码列表

//! 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 functionSimply 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](http://www.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
#define CV_FOURCC_DEFAULT CV_FOURCC('I', 'Y', 'U', 'V')

查看源代码**fourcc(char c1, char c2, char c3, char c4)**与 **CV_FOURCC(char c1, char c2, char c3, char c4)**相同,支持通用,建议还是不要设置为 -1,仅支持Windows,还是采用 返回值形式来设置编码格式。 例如:int fourcc = cv::VideoWriter::fourcc(‘M’, ‘J’, ‘P’, ‘G’)

Qt

QCameraInfo::availableCameras():返回位于本地所有有效的摄像头列表

[static] QList<QCameraInfo> QCameraInfo::availableCameras(QCamera::Position position = QCamera::UnspecifiedPosition)
Returns a list of available cameras on the system which are located at position.
If position is not specified or if the value is QCamera::UnspecifiedPosition, a list of all available cameras will be returned.

QList supportedViewfinderResolutions(const QCameraViewfinderSettings &settings = QCameraViewfinderSettings()) :返回摄像头支持分辨率列表。

QList<QSize> QCamera::supportedViewfinderResolutions(const QCameraViewfinderSettings &settings = QCameraViewfinderSettings()) const
Returns a list of supported viewfinder resolutions.
This is a convenience function which retrieves unique resolutions from the supported settings.
If non null viewfinder settings are passed, the returned list is reduced to resolutions supported with partial settings applied.
The camera must be loaded before calling this function, otherwise the returned list is empty.

QList supportedViewfinderFrameRateRanges(const QCameraViewfinderSettings &settings = QCameraViewfinderSettings()) :返回摄像头支持的帧率范围。

QList<QCamera::FrameRateRange> QCamera::supportedViewfinderFrameRateRanges(const QCameraViewfinderSettings &settings = QCameraViewfinderSettings()) const
Returns a list of supported viewfinder frame rate ranges.
This is a convenience function which retrieves unique frame rate ranges from the supported settings.
If non null viewfinder settings are passed, the returned list is reduced to frame rate ranges supported with partial settings applied.
The camera must be loaded before calling this function, otherwise the returned list is empty.

QList< QVideoFrame::PixelFormat> supportedViewfinderPixelFormats(const QCameraViewfinderSettings &settings = QCameraViewfinderSettings()):返回摄像头支持格式。

QList<QVideoFrame::PixelFormat> QCamera::supportedViewfinderPixelFormats(const QCameraViewfinderSettings &settings = QCameraViewfinderSettings()) const
Returns a list of supported viewfinder pixel formats.
This is a convenience function which retrieves unique pixel formats from the supported settings.
If non null viewfinder settings are passed, the returned list is reduced to pixel formats supported with partial settings applied.
The camera must be loaded before calling this function, otherwise the returned list is empty.

源码详解

摄像头列表

获取摄像头列表

void MainWindow::GetCameraList()
{formatmeta = QMetaEnum::fromType<PixelFormat>();cameras = QCameraInfo::availableCameras();foreach(const QCameraInfo &cameraInfo, cameras){ui->comboBox_name->addItem(cameraInfo.description());GetCameraInfo(cameraInfo);COUT << cameraInfo.description() <<cameraInfo.deviceName() << cameraInfo.orientation();}
}

选择摄像头

    connect(ui->comboBox_name,SIGNAL(activated(int)),this,SLOT(slot_SetIndexCaptureCamera(int))); //信号槽连接
void MainWindow::slot_SetIndexCaptureCamera(int index) //摄像头选择
{if(cap.isOpened()){timer.stop();cap.release();}cap.open(index,cv::CAP_DSHOW);if(!cap.isOpened()){COUT << cameras.at(index).description() << "打开失败";return;}SetComboxValue(index); //默认值显示timer.start(20); //定时器启动
}

帧读取

void MainWindow::slot_CaptureImage()
{cv::Mat frame,image;cap.read(frame);if(frame.empty())return;emit signal_MatImage(frame);
}
    connect(&timer,&QTimer::timeout,this,&MainWindow::slot_CaptureImage); //定时器信号槽绑定

帧显示

    connect(this,&MainWindow::signal_MatImage,this,&MainWindow::slot_LabelShowImg);
void MainWindow::slot_LabelShowImg(cv::Mat image)
{cv::Mat out_image;cv::cvtColor(image,out_image,cv::COLOR_BGR2RGB); //转为Qt显示RGB值QImage qImg = QImage((const unsigned char*)(out_image.data),out_image.cols,out_image.rows,out_image.step,QImage::Format_RGB888); //转为QImageui->label_video->setPixmap(QPixmap::fromImage(qImg.mirrored(true,false)));ui->label_video->resize(qImg.size());ui->label_video->show();//拍照相关设置if(isSaveImage){QString image_name = QString("%1.png").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss"));if(qImg.save(image_name)){COUT << "拍照成功!" << image_name;isSaveImage = false;}else {COUT << "保存图片失败!"  << image_name;}}
}

Qt支持相关属性列表

void MainWindow::GetCameraInfo(QCameraInfo info)
{QCamera * camera = new QCamera(info);camera->start();GetCameraResolution(camera);GetCameraFormat(camera);GetCameraFrameRate(camera);camera->stop();delete camera;camera = nullptr;
}

分辨率列表

void MainWindow::GetCameraResolution(QCamera *camera)
{QStringList resolutions;QList<QSize> resSize = camera->supportedViewfinderResolutions();for(auto it : resSize){resolutions.push_back(QString("%1X%2").arg(it.width()).arg(it.height()));COUT << QString("%1X%2").arg(it.width()).arg(it.height());}camerasresolution.push_back(resolutions);
}

帧编码格式列表

void MainWindow::GetCameraFormat(QCamera *camera)
{QStringList formats;QList<QVideoFrame::PixelFormat> formatlist = camera->supportedViewfinderPixelFormats();for(auto it : formatlist){COUT << formatmeta.valueToKey(it) ;formats.push_back(formatmeta.valueToKey(it));}camerasformat.push_back(formats);
}

帧率列表

void MainWindow::GetCameraFrameRate(QCamera *camera)
{QStringList frames;QList<QCamera::FrameRateRange> framerate = camera->supportedViewfinderFrameRateRanges();for(auto it : framerate){frames.push_back(QString("%1").arg(it.minimumFrameRate));}camerasframerate.push_back(frames);
}

参数设置

参数初始化设置

void MainWindow::SetComboxValue(int index)
{ui->comboBox_resolution->clear();ui->comboBox_resolution->addItems(camerasresolution.at(index));QString resolution = QString("%1X%2").arg(cap.get(cv::CAP_PROP_FRAME_WIDTH)).arg(cap.get(cv::CAP_PROP_FRAME_HEIGHT));ui->comboBox_resolution->setCurrentIndex(ui->comboBox_resolution->findText(resolution));COUT << "resolution:" <<resolution;ui->comboBox_format->clear();ui->comboBox_format->addItems(camerasformat.at(index));QString format = QString("%1").arg(cap.get(cv::CAP_PROP_FORMAT));COUT << "format:" << format;ui->comboBox_framerate->clear();ui->comboBox_framerate->addItems(camerasframerate.at(index));QString framerate = QString("%1").arg(cap.get(cv::CAP_PROP_FPS));ui->comboBox_framerate->setCurrentIndex(ui->comboBox_framerate->findText(framerate));COUT << "framerate:" << framerate;QString pixelformat = QString("%1").arg(cap.get(cv::CAP_PROP_CODEC_PIXEL_FORMAT));COUT << "pixelformat:" << pixelformat;QString gain = QString("%1").arg(cap.get(cv::CAP_PROP_GAIN));COUT << "gain:" << gain;ui->spinBox_brightness->setValue(DoubleToInt(cap.get(cv::CAP_PROP_BRIGHTNESS))); //显示默认亮度ui->spinBox_contrast->setValue(DoubleToInt(cap.get(cv::CAP_PROP_CONTRAST))); //显示默认对比度ui->spinBox_exposure->setValue(DoubleToInt(cap.get(cv::CAP_PROP_EXPOSURE))); //显示默认曝光ui->spinBox_hue->setValue(DoubleToInt(cap.get(cv::CAP_PROP_HUE))); //显示默认色调ui->spinBox_saturation->setValue(DoubleToInt(cap.get(cv::CAP_PROP_SATURATION))); //显示默认饱和度ui->spinBox_wb->setValue(DoubleToInt(cap.get(cv::CAP_PROP_WHITE_BALANCE_BLUE_U))); //显示默认白平衡ui->spinBox_gain->setValue(DoubleToInt(cap.get(cv::CAP_PROP_GAIN))); //显示自动增益ui->checkBox_autoexposure->setCheckState((cap.get(cv::CAP_PROP_AUTO_EXPOSURE))?Qt::CheckState::Checked:Qt::CheckState::Unchecked); //是否自动曝光ui->checkBox_autowb->setCheckState((cap.get(cv::CAP_PROP_AUTO_WB))?Qt::CheckState::Checked:Qt::CheckState::Unchecked);
} //是否自动白平衡

参数设置相关信号槽绑定

    connect(ui->comboBox_resolution,SIGNAL(activated(int)),this,SLOT(slot_SetIndexCameraResolution(int)));//分辨率connect(ui->comboBox_framerate,SIGNAL(activated(int)),this,SLOT(slot_SetIndexCameraFrameRate(int)));//帧率connect(ui->spinBox_brightness,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraBrightness(int)));//亮度connect(ui->spinBox_contrast,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraContrast(int)));//对比度connect(ui->spinBox_exposure,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraExposure(int)));//曝光connect(ui->spinBox_hue,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraHue(int)));//色调connect(ui->spinBox_saturation,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraSaturation(int)));//饱和度connect(ui->spinBox_gain,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraGain(int)));//增益connect(ui->spinBox_wb,SIGNAL(valueChanged(int)),this,SLOT(slot_SetCameraWhilteBalance(int)));//白平衡connect(ui->checkBox_autoexposure,&QCheckBox::stateChanged,this,&MainWindow::slot_SetCameraAutoExposure);//自动曝光connect(ui->checkBox_autowb,&QCheckBox::stateChanged,this,&MainWindow::slot_SetCameraAutoWb);//自动白平衡connect(ui->pushButton_setting,&QPushButton::clicked,this,&MainWindow::slot_SetCameraPram);//OpenCv自带参数设置

分辨率

void MainWindow::slot_SetIndexCameraResolution(int index)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}QString resolution = ui->comboBox_resolution->itemText(index);double width = resolution.split("X").at(0).toDouble();double height = resolution.split("X").at(1).toDouble();COUT << cap.get(cv::CAP_PROP_FRAME_WIDTH) << cap.get(cv::CAP_PROP_FRAME_HEIGHT);cap.set(cv::CAP_PROP_FRAME_WIDTH,width);cap.set(cv::CAP_PROP_FRAME_HEIGHT,height);
}

帧率

void MainWindow::slot_SetIndexCameraFrameRate(int index)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}QString framerate = ui->comboBox_framerate->itemText(index);cap.set(cv::CAP_PROP_FPS,framerate.toDouble());
}

亮度

void MainWindow::slot_SetCameraBrightness(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_BRIGHTNESS,value);
}

饱和度

void MainWindow::slot_SetCameraSaturation(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_SATURATION,value);
}

色调

void MainWindow::slot_SetCameraHue(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_HUE,value);
}

曝光

void MainWindow::slot_SetCameraExposure(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_EXPOSURE,value);COUT << "CAP_PROP_EXPOSURE:" << QString("%1").arg(cap.get(cv::CAP_PROP_EXPOSURE));
}

对比度

void MainWindow::slot_SetCameraContrast(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_CONTRAST,value);
}

增益

void MainWindow::slot_SetCameraGain(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_GAIN,value);
}

白平衡

void MainWindow::slot_SetCameraWhilteBalance(int value)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_WHITE_BALANCE_BLUE_U,value);
}

自动白平衡

void MainWindow::slot_SetCameraAutoWb(int status)
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_AUTO_WB,(status == Qt::CheckState::Checked) ? -1 : cap.get(cv::CAP_PROP_EXPOSURE));ui->spinBox_wb->setDisabled(status);
}

自动曝光

void MainWindow::slot_SetCameraAutoExposure(int status)
{COUT << "设置自动曝光" << status;if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}if(status == Qt::CheckState::Checked){cap.set(cv::CAP_PROP_AUTO_EXPOSURE,0);cv::VideoCaptureProperties();}else{cap.set(cv::CAP_PROP_AUTO_EXPOSURE,1);cap.set(cv::CAP_PROP_EXPOSURE,cap.get(cv::CAP_PROP_EXPOSURE));}ui->spinBox_exposure->setDisabled(status);COUT << "自动曝光:" << cap.get(cv::CAP_PROP_AUTO_EXPOSURE);COUT << "曝光:" << cap.get(cv::CAP_PROP_EXPOSURE);
}

设置参数属性-OpenCv

void MainWindow::slot_SetCameraPram()
{COUT << "设置摄像头参数";if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}cap.set(cv::CAP_PROP_SETTINGS, 1);COUT << "自动曝光:" << cap.get(cv::CAP_PROP_AUTO_EXPOSURE);COUT << "曝光:" << cap.get(cv::CAP_PROP_EXPOSURE);COUT << "自动白平衡:" << cap.get(cv::CAP_PROP_AUTO_WB);COUT << "白平衡:" << cap.get(cv::CAP_PROP_WHITE_BALANCE_BLUE_U);
}

拍照

思路,按下拍照按钮时,将保存标志位置为True,将下一帧转为QImage类型,保存下一帧。

    connect(ui->pushButton_photo,&QPushButton::clicked,this,&MainWindow::slot_Photograph);
void MainWindow::slot_Photograph()
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}isSaveImage = true; //当标志位为True时,启动保存当前帧
}

视频录制

    connect(ui->pushButton_recordvideo,&QPushButton::clicked,this,&MainWindow::slot_RecordVideo);connect(this,&MainWindow::signal_MatImage,this,&MainWindow::slot_SaveVideo);
void MainWindow::slot_RecordVideo()
{if(!cap.isOpened()){COUT << "摄像头设备未打开!";return;}if(!videorecord.isOpened() && isRecordVideo == false){QString resolution = ui->comboBox_resolution->currentText();int width = resolution.split("X").at(0).toInt();int height = resolution.split("X").at(1).toInt();COUT << "video size:" << width << " " << height;cv::Size _size = cv::Size(width,height);QString video_name = QString("%1.mp4").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss"));videorecord.open(video_name.toStdString(),cv::VideoWriter::fourcc('M', 'J', 'P', 'G'),30,_size,true);//设置保存属性-编码-名字-分辨率if(videorecord.isOpened()){isRecordVideo = true;COUT << "开始视频录制";ui->pushButton_recordvideo->setText("结束录制");}}else if(videorecord.isOpened() && isRecordVideo){ui->pushButton_recordvideo->setText("视频录制");videorecord.release();isRecordVideo = false;COUT << "视频录制完成";}
}
void MainWindow::slot_SaveVideo(cv::Mat image) //写入帧文件
{if(isRecordVideo){videorecord.write(image);}
}

头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QCamera>
#include <QCameraInfo>
#include <opencv2/opencv.hpp>
#include <QList>
#include <QTimer>
#include <QMetaEnum>
#include <QDebug>#define COUT qDebug()<< __TIME__ << __FUNCTION__ << __LINE__ << " : " //日志输出,方便自己调试做的设置namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();enum PixelFormat{Format_Invalid,Format_ARGB32,Format_ARGB32_Premultiplied,Format_RGB32,Format_RGB24,Format_RGB565,Format_RGB555,Format_ARGB8565_Premultiplied,Format_BGRA32,Format_BGRA32_Premultiplied,Format_BGR32,Format_BGR24,Format_BGR565,Format_BGR555,Format_BGRA5658_Premultiplied,Format_AYUV444,Format_AYUV444_Premultiplied,Format_YUV444,Format_YUV420P,Format_YV12,Format_UYVY,Format_YUYV,Format_NV12,Format_NV21,Format_IMC1,Format_IMC2,Format_IMC3,Format_IMC4,Format_Y8,Format_Y16,Format_Jpeg,Format_CameraRaw,Format_AdobeDng,};Q_ENUM(PixelFormat)private:Ui::MainWindow *ui;QList<QCameraInfo> cameras;QList<QStringList> camerasresolution;QList<QStringList> camerasformat;QList<QStringList> camerasframerate;QTimer timer;QMetaEnum formatmeta;cv::VideoCapture cap;cv::VideoWriter videorecord;bool isSaveImage;bool isRecordVideo;void CamerasInit();void GetCameraList();void GetCameraInfo(QCameraInfo info);void GetCameraResolution(QCamera *camera);void GetCameraFormat(QCamera *camera);void GetCameraFrameRate(QCamera *camera);void SetComboxValue(int index);
public slots:void slot_SetIndexCaptureCamera(int index);void slot_CaptureImage();void slot_LabelShowImg(cv::Mat image);void slot_SetIndexCameraResolution(int index);void slot_SetIndexCameraFrameRate(int index);void slot_SetCameraBrightness(int value);void slot_SetCameraSaturation(int value);void slot_SetCameraHue(int value);void slot_SetCameraExposure(int value);void slot_SetCameraContrast(int value);void slot_SetCameraGain(int value);void slot_SetCameraWhilteBalance(int value);void slot_SetCameraAutoWb(int status);void slot_SetCameraAutoExposure(int status);void slot_SetCameraPram();void slot_Photograph();void slot_RecordVideo();void slot_SaveVideo(cv::Mat image);signals:void signal_MatImage(cv::Mat);
};#endif // MAINWINDOW_H

运行结果

UI界面

UI界面
有点乱不想放图片的-----

运行界面

OpenCv参数设置
运行界面-176X144.jpg
运行界面-640X680.jpg
运行界面-1280X720.jpg

运行结果

拍照与录像.jpg

源码

GitHub

问题

OpenCv设置自动曝光是,取消自动曝光设置是成功的,但是设置为自动曝光没有生效。UI界面的自适应没有做很好,但是不想浪费精力还有代码的优化,还可以优化很多,但是都是工作量了,不做进一步改进。目前这个代码结构,基本的设置或者工程应用应该是足够的,更加复杂的场景,暂时没有涉及到也不做相关建议了。
UI自适应思路:根据Label大小,将窗口resize,来实现自动缩放。
代码优化定时器时间设置:这一块不够严谨,应该时间设置为,1000/rate ,笔者设置为了固定值,20ms,相当于50帧,在时序比较严谨的场景中,会导致帧率错位或者帧时间不匹配的问题。还有视频录制相关。相关代码和分辨率设置差不多,也不做添加了。
自动曝光设置:准备查看源码,但是第一遍搜索的时候,没有找到相关,如果有建议,欢迎留言。
设置参数:摄像头没有打开时,所有设置参数属性控件都是可以点击的,可以默认为disable,在打开摄像头在设置为enable。在每次进行摄像头参数设置时,都有一个摄像头是否打开判断,其实没有必要,在外边随定时器进行判断就好,不好的点是浪费了性能,但是这样设置保证安全,但是代码有些冗余看个人选择了。
有其他问题,欢迎探讨。

下一章节

OpenCv 文字识别或者大家有什么建议吗?学习方向还是没整理好。

更新

2021.04.29
代码放在github了,之前没有想着放在git上边,就当自己随手写的一个小Demo,有点不规范。以后所有代码都会放在github上边。尽量会做到规范,

这篇关于OpenCv4.4.0+Qt:摄像头控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1022315

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

使用Qt编程QtNetwork无法使用

使用 VS 构建 Qt 项目时 QtNetwork 无法使用的问题 - 摘叶飞镖 - 博客园 (cnblogs.com) 另外,强烈建议在使用QNetworkAccessManager之前看看这篇文章: Qt 之 QNetworkAccessManager踏坑记录-CSDN博客 C++ Qt开发:QNetworkAccessManager网络接口组件 阅读目录 1.1 通用API函数

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、

Qt多语种开发教程

Qt作为跨平台的开发工具,早已应用到各行各业的软件开发中。 今天讲讲,Qt开发的正序怎么做多语言开发。就是说,你设置中文,就中文显示;设置英语就英文显示,设置繁体就繁体显示,设置发育就显示法语等。 开发环境(其实多语种这块根环境没太大关系):win10,Qt.5.12.10 一.先用QtCreator创建一个简单的桌面程序 1.工程就随便命名“LanguageTest”,其他默认。 2.在设计师

vue2实践:el-table实现由用户自己控制行数的动态表格

需求 项目中需要提供一个动态表单,如图: 当我点击添加时,便添加一行;点击右边的删除时,便删除这一行。 至少要有一行数据,但是没有上限。 思路 这种每一行的数据固定,但是不定行数的,很容易想到使用el-table来实现,它可以循环读取:data所绑定的数组,来生成行数据,不同的是: 1、table里面的每一个cell,需要放置一个input来支持用户编辑。 2、最后一列放置两个b