Reputation: 1471
I have created a very simple UI using Qt
which consists of a simple button and a label. When the button's clicked()
signal is emitted, a function which captures a frame from a webcam using OpenCV
is called. The code I am currently using to achieve this is:
cv::Mat MainWindow::captureFrame(int width, int height)
{
//sets the width and height of the frame to be captured
webcam.set(CV_CAP_PROP_FRAME_WIDTH, width);
webcam.set(CV_CAP_PROP_FRAME_HEIGHT, height);
//determine whether or not the webcam video stream was successfully initialized
if(!webcam.isOpened())
{
qDebug() << "Camera initialization failed.";
}
//attempts to grab a frame from the webcam
if (!webcam.grab()) {
qDebug() << "Failed to capture frame.";
}
//attempts to read the grabbed frame and stores it in frame
if (!webcam.read(frame)) {
qDebug() << "Failed to read data from captured frame.";
}
return frame;
}
After a frame has been captured, it must be converted into a QImage
in order to be displayed in the label. In order to achieve this, I use the following method:
QImage MainWindow::getQImageFromFrame(cv::Mat frame) {
//converts the color model of the image from RGB to BGR because OpenCV uses BGR
cv::cvtColor(frame, frame, CV_RGB2BGR);
return QImage((uchar*) (frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
}
The constructor for my MainWaindow
class looks like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(1280, 720);
move(QPoint(200, 200));
webcam.open(0);
fps = 1000/25;
qTimer = new QTimer(this);
qTimer->setInterval(fps);
connect(qTimer, SIGNAL(timeout()), this, SLOT(displayFrame()));
}
The QTimer
is supposed to display a frame by calling dislayFrame()
void MainWindow::displayFrame() {
//capture a frame from the webcam
frame = captureFrame(640, 360);
image = getQImageFromFrame(frame);
//set the image of the label to be the captured frame and resize the label appropriately
ui->label->setPixmap(QPixmap::fromImage(image));
ui->label->resize(ui->label->pixmap()->size());
}
each time its timeout()
signal is emitted.
However, while this appears to work to a degree, what actually happens is that the video capture stream from my webcam (a Logitech Quickcam Pro 9000) repeatedly opens and closes. This is evidenced by the fact that the blue ring, which indicates that the webcam is on, repeatedly flashes on and off. This leads to the refresh rate for the webcam video stream label to be very low, and is not desirable. Is there some way to make it so that the webcam stream remains open in order to prevent this "flickering" from occurring?
Upvotes: 2
Views: 5601
Reputation: 1471
I seem to have solved the problem of the webcam stream opening and closing by removing the lines:
webcam.set(CV_CAP_PROP_FRAME_WIDTH, width);
webcam.set(CV_CAP_PROP_FRAME_HEIGHT, height);
from the captureFrame()
function and setting the width and height of the frame to be captured in the MainWindow
constructor.
Upvotes: 1