Qt crashes when picture from OpenCV is too large [duplicate] - c++

This question already has an answer here:
How to efficiently display OpenCV video in Qt?
(1 answer)
Closed 6 years ago.
I've been trying to use OpenCV to capture a camera feed, and show it in Qt as a QLabel. Following a guide I found, this works to a certain degree. However, the application just outright crashes if I try to resize the Mat before making a QImage and setting the Pixmap. The crash is of the type "CameraSoftware.exe has stopped working", so it's hard to debug much other than finding out where it crashes.
Environment is 64 bit windows with QtCreator 3.6.0 (Qt 5.5.1) and OpenCV 3.10.
Here's the important bits of codes:
void VideoStreamOpenCVWorker::receiveGrabFrame()
{
if(!toggleStream) return;
(*cap) >> frameOriginal;
if(frameOriginal.empty()) return;
process();
qDebug() << frameProcessed.cols << "x" << frameProcessed.rows;
QImage output((const unsigned char *) frameProcessed.data, frameProcessed.cols, frameProcessed.rows, QImage::Format_RGBA8888);
emit sendFrame(output);
}
void VideoStreamOpenCVWorker::process()
{
cv::cvtColor(frameOriginal, frameProcessed, cv::COLOR_BGR2RGBA);
cv::Size size(641,481);
cv::resize(frameProcessed, frameProcessed, size);
}
This is sent back to a QLabel widget:
void VideoStreamWidget::receiveFrame(QImage frame){
this->setPixmap(QPixmap::fromImage(frame));
}
This is where it crashes specifically, on the "setpixmap" line.
The Qlabel is added to a QMainWindow with simply:
QVBoxLayout *pictureLayout = new QVBoxLayout;
VideoStreamWidget *video = new VideoStreamWidget();
pictureLayout->addWidget(video);
The original cap picture is 640x480 for whatever reason, the camera I'm using is a full HD camera. Any idea what's causing this? The Qt window size doesn't seem to matter, as I can add a large picture directly if I want to. I just can't resize anything without crashing.
If I haven't provided enough information, ask away.
EDIT: I updated my debugger and got this error message upon executing the setPixmap line:
The inferior stopped because it triggered an exception.
Stopped in thread 0 by: Exception at 0x7ffe38fdadbb, code: 0xc0000005:
read access violation at: 0x0, flags=0x0 (first chance).

Thanks to Mailerdaimon for providing the answer. Emitting the output as a copy
emit sendFrame(output.copy());
does the trick. I am still unsure why exactly this is happening in the first place and why this fixes the problem.

Related

Qt debugging stops on deserialize

hi i'm working with dlib and I have this error about deserialize.
My exe file works fine, but it only stops when I try to debug it on my Qt creator.
It doesn't give me any error message, it just stops and does not works. I can't even press exit on my project, I can only make it stop by pressing 'stop debugging' button on Qt.
It does works when I run my exe file, so I have no idea what can be wrong. I tried to find out where the error occurs, and this is my code.
if (set)
{
//DNN for shape predictor
dlib::shape_predictor sp;
qDebug("on_pushButton_clicked"); // I get this
dlib::deserialize("shape_predictor_5_face_landmarks.dat") >> sp;
qDebug("destination"); // I don't get this message
//shape detector extracts face images from image
auto shape = sp(spimg, dets[0]);
dlib::matrix<dlib::rgb_pixel> face_chip;
dlib::extract_image_chip(spimg, dlib::get_face_chip_details(shape, 150, 0.25), face_chip);
//Add face to global variable
std_faces.push_back(std::move(face_chip));
//send signal to open the mainwindow
emit Photo::ClosedProperly();
keep_sending = true;
}
as I get the first qDebug message and it stops, so I suspect that in deserialize function my debugging stops for some reason. I'm keep searching about dlib and deserialize but I couldn't get satisfactory answer yet.. I'll keep looking on it, but I post this question that someone might experienced similar problem and has a clue to figure this out.
Thanks for reading this.
p.s. I think my debugging breakpoint doesn't work around that spot... this code is a part of on_pushButton_clicked() and it gives a qDebug message but breakpoint doesn't work. I'm not sure it's relative to the problem I have, but I add this information so it might help.

Qlist<QCameraInfo> causes access violation in QList destructor

I am writing a video grabbing application in c++ using Qt5. I am following their example code and looking at the documentation for getting the camera info:
http://doc.qt.io/qt-5/qcamerainfo.html
The problem I have is that after I use the prescribed technique for getting camera data (which works perfectly):
QList<QCameraInfo>cameraInfos = QCameraInfo::availableCameras();
I get an Access violation error whenever cameraInfos goes out of scope.
For example, if I do:
void readDeviceInfo(void) {
// Camera devices:
QList<QCameraInfo>cameraInfos = QCameraInfo::availableCameras()
for (QList<QCameraInfo>::Iterator it = cameraInfos.begin();
it != cameraInfos.end(); ++it)
std::cout << it->description().toStdString().c_str() << std::endl;
}
The crash occurs on the return of this function. If I do:
foreach(const QCameraInfo &ci, QCameraInfo::availableCameras());
The crash occurs in the evaluation of the foreach loop. Likewise, if I declare QList<QCameraInfo> cameraInfos as a field in a class, the crash happens when the class is destroyed. This is verified by the output of my call stack:
ntdll.dll!000000007750eef1() Unknown
kernel32.dll!00000000773c1a0a() Unknown
> VideoCapture.exe!free(void * pBlock) Line 51 C
VideoCapture.exe!QCameraInfo::`scalar deleting destructor'(unsigned int) C++
VideoCapture.exe!QList<QCameraInfo>::node_destruct(QList<QCameraInfo>::Node * from, QList<QCameraInfo>::Node * to) Line 484 C++
VideoCapture.exe!QList<QCameraInfo>::dealloc(QListData::Data * data) Line 857 C++
VideoCapture.exe!QList<QCameraInfo>::~QList<QCameraInfo>() Line 817 C++
I am using Visual Studio 2013 (windows obviously).
You need to compile Qt yourself, then run your test case under a debugger and see where it crashes. You also need a minimal, self-contained test case for this - and that must be the part of the question (SSCCE). As it is, it's more likely that you're corrupting memory elsewhere and the failure you're seeing is the outcome of a corrupted heap, not a Qt bug.
Sidebar: You need to be proficient in running small examples in Qt Creator. Arguably, the templates Qt Creator comes with aren't very good for that. You can use this template, available as Other Projects->Simple qmake, to make quick prototypes.
The following works fine for me with 1 camera on current Qt on both OS X 10.9 and Windows 10/VS 2015. The std::cout you're using is red herring, you can use qDebug() as well.
// https://github.com/KubaO/stackoverflown/tree/master/questions/camlist-37603946
#include <QtWidgets>
#include <QtMultimedia>
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QComboBox combo;
QObject::connect(&combo, &QComboBox::currentTextChanged, [&]{
std::cout << combo.currentText().toStdString() << std::endl;
});
for (auto const & info : QCameraInfo::availableCameras())
combo.addItem(info.description());
combo.show();
return app.exec();
}
So after following Kuba's advice and running his test program in my environment with a freshly built Qt library, I got the same errors. Then I had the bright idea to run it in release mode rather than debug. Lo and behold, it worked perfectly, with both the freshly built Qt5 (x86, as it happened) and the pre-built binaries (64 bit) gotten from Qt's downloads page.
It seems that linking to the qt debug libraries was causing this behavior. I'm now linking to the non-debug libraries in debug mode and am nice and happy -- for the most part -- I am still a little annoyed that the qt libs suffixed with 'd' don't seem to work properly on my system. Nevertheless, I can move on with developing this project.
Thanks to all that commented and answered!

How to fully/correctly exit a Qt program from the main form?

I'm writing a Qt program (using Qt 5.4) that reads frames from a webcam based on a QTimer, not a separate thread (interval set to 20 ms, of course it takes much longer than 1/50 of a second to read a frame from the webcam and process it, I'd approximate the frame rate is perhaps 20 fps. Anyhow, the function which runs when the timer cycles is a slot and is as follows:
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
QApplication::quit();
}
// process frame here . . .
The idea being if the webcam can be successfully read at the beginning of the program, but then cannot be (webcam stops working, user accidentally disconnects webcam, etc.) the program should show a message box to this effect and then close itself entirely.
With the above, if I unplug the webcam while the program is running for testing purposes, the message box appears as intended, but after choosing OK, a debug error screen appears. If I choose "Abort" the form is still there and will not respond. After attempting to close the form multiple times Windows asks "the program does not seem to be responding, would you like to close?" at which time I can close the form. Clearly this is not achieving the intended effect.
After various Googling I found the suggestion to modify as follows:
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
closeEvent(new QCloseEvent());
}
// process frame here . . .
When I first saw this code I was optimistic, however it gives me the same result as above (program hangs with the form still open). I'm using OpenCV 2.4.11 for my image processing and my program has 4 files:
frmmain.h (.h for the main form, which is a standard QMainWindow made with Qt Creator)
frmmain.cpp (.cpp for the main form, where the above code resides)
main.cpp (which I have not changed from how Qt Creator made it)
frmmain.ui (typical form with a small number of common widgets added via Qt Creator)
Yes, I realize that I could show an error message on one of the widgets that can show text, return from the function, and leave it to the user to close the program, but I'm looking for a more elegant solution. Can anybody offer further advice as to how to fully close a graphical Qt program? Please advise.
Two things that could possible solve your problem:
Before displaying the messagebox, stop the timer with the stop() method.
After the QApplication::quit(); exit the function with return; Your function might be running to the end one last time and accessing invalid objects.
For anybody else's reference Rafael Monteiro's answer was spot on. Here is the updated code (verified working):
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
if(qtimer->isActive()) qtimer->stop(); // had to stop timer here !!!!!!!!
QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal); // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) { // if we did not get a frame
QMessageBox::information(this, "", "unable to read from webcam \n\n exiting program\n");
closeEvent(new QCloseEvent());
return; // had to add return here !!!!!!!!!
}
// rest of function here . . .
I should mention I had to add both the return and stop the timer. Thanks Rafael!

Function call causes C++ program to freeze unless stepped-through in debugger

I have this short C++ program which takes snapshot images from a camera in a loop and displays them:
void GenericPGRTest::execute()
{
// connect camera
Camera *cam = Camera::Connect();
// query resolution and create view window
const Resolution res = cam->GetResolution();
cv::namedWindow("View");
c = 0;
// keep taking snapshots until escape hit
while (c != 27)
{
const uchar *buf = cam->SnapshotMono();
// create image from buffer and display it
cv::Mat image(res.height, res.width, CV_8UC1, (void*)buf);
cv::imshow("Camera", image);
c = cv::waitKey(1000);
}
}
This uses a class (Camera) for camera control I created using the Point Grey SDK and functions from the OpenCV library to display the images. I'm not necessarily looking for answers relating to the usage of either of these libraries, but rather some insight on how to debug a bizarre problem in general. The problem is that the application freezes (not crashes) on the cam->SnapshotMono() line. Of course, I ran through the function with a debugger. Here is the contents:
const uchar* Camera::SnapshotMono()
{
cam_.StartCapture();
// get a frame
Image image;
cam_.RetrieveBuffer(&image);
cam_.StopCapture();
grey_buffer_.DeepCopy(&image);
return grey_buffer_.GetData();
}
Now, every time I step through the function in the debugger, everything works OK. But the first time I do a "step over" instead of "step into" SnapshotMono(), bam, the program freezes. When I pause it at that time, I notice that it's stuck inside SnapshotMono() at the RetrieveBuffer() line. I know it's a blocking call so it theoretically can freeze (no idea why but it's possible), but why does it block when running normally and not when being debugged? This is one of the weirdest kinds of behaviour under debugging I've seen so far. Any idea why this could happen?
For those familiar with FlyCapture, the code above doesn't break as is, but rather only when I use StartCapture() in callback mode, then terminate it with StopCapture() before it.
Compiled with MSVC2010, OpenCV 2.4.5 and PGR FlyCapture 2.4R10.
Wild guess ... but may it be that StartCapture already starts the process that
ends up with having the buffer in ìmage, and if you step you leave it some
time until you get to RetrieveBuffer. That's not the case if you run it all at once ...

QAudioOutput always encountering UnderrunError

I'm using Qt 4.8 with Qt Creator 2.4.1 on Windows 7 Ultimate x64.
I'm taking audio input using QAudioInput class and playing it using QAudioOutput. There is a 2 seconds timeout after which I stop taking input and then setup the output as follows:
class MainWindow
{
// ...
QByteArray output_data;
QBuffer output_data_buffer;
QAudioOutput *audio_out;
// ...
};
MainWindow::MainWindow(QWidget *parent)
{
// ...
output_data_buffer.setBuffer(&output_data);
// ...
}
void MainWindow::audioInputStopped(QByteArray data)
{
output_data = data;
output_data_buffer.open(QIODevice::ReadOnly);
audio_out = new QAudioOutput(audio_format, this);
connect(audio_out, SIGNAL(stateChanged(QAudio::State)),
SLOT(audioOutputStateChanged(QAudio::State)));
audio_out->start(&output_data_buffer);
}
The audio format I'm using is supported by both input and output devices. I checked them using QAudioDeviceInfo::isFormatSupported(). The 2 seconds audio (data in audioInputStopped()) always plays fine.
In the slot audioOutputStateChanged, I'm always encountering QAudio::UnderrunError error from audio_out->error() after the buffer is finished playing. After audio_out->start() is called, the state (passed as parameter in audioOutputStateChanged()) and error goes as follows:
No error. Active state.
No error. Stopped state.
Underrun error. Idle state.
Note that I'm stopping audio_out in idle state following this example. Why the code is encountering underrun error? Is this normal?
This may seem kind of odd, but I've seen where the built-in arrays in Qt handle better when constructed on the heap, or at least when their elements are constructed on the heap (so they are just an array of pointers). The memory management is a little bit trickier, but items pushed into them don't go out of scope. The Qt Object Model also promotes putting most things on the heap and parenting them correctly. This might help.
After reading a little bit up on buffer underruns, it sounds like there is something still trying to read from the audio source while something else is writing to it or vice-versa. Check out some of the links below. You could try disconnecting the audio_in part from the buffer before reading the buffer. This is more likely to fix the error.
I would also construct your QAudioOutput pointer in the constructor for your main window (more as a style thing). Following some of how it is organized in the examples in Qt, it seems like a better organization. Here is the cpp for the QAudioInput example.
If you had a more complete example, I could try more with it to recreate the error and debug it.
Here is someone else to commiserate with:
http://qt-project.org/forums/viewthread/16729
And a wiki article:
http://en.wikipedia.org/wiki/Buffer_underrun
And the list of Multimedia examples on Qt:
http://doc.qt.nokia.com/4.7-snapshot/examples-multimedia.html
Hope that helps.