Displaying live camera feed
-
I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?std::string folder = "/path/of/images/*.jpg"; cv::glob(folder,images); void MainWindow::liveIMG::setReference(MainWindow *m) { this->m = m; } void MainWindow::liveIMG::run() { size_t i = 0; while (true) { if(i == m->images.size()) i = 0; m->img = cv::imread(m->images[i]); i++; QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888); emit updateImage(image); } }
-
I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?std::string folder = "/path/of/images/*.jpg"; cv::glob(folder,images); void MainWindow::liveIMG::setReference(MainWindow *m) { this->m = m; } void MainWindow::liveIMG::run() { size_t i = 0; while (true) { if(i == m->images.size()) i = 0; m->img = cv::imread(m->images[i]); i++; QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888); emit updateImage(image); } }
@shreya_agrawal said in Displaying live camera feed:
void MainWindow::liveIMG::run() {
size_t i = 0;
while (true)So, this is running in another thread (not the GUI thread)? And you also do not have any pause in this loop, so probably flooding the event queue with too many signals.
"But this approach crashes the application" - as always in such a situation run in debugger and post stack trace after crash to see where it is crashing.
-
I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?std::string folder = "/path/of/images/*.jpg"; cv::glob(folder,images); void MainWindow::liveIMG::setReference(MainWindow *m) { this->m = m; } void MainWindow::liveIMG::run() { size_t i = 0; while (true) { if(i == m->images.size()) i = 0; m->img = cv::imread(m->images[i]); i++; QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888); emit updateImage(image); } }
@shreya_agrawal Apart from @jsulm comments please read the docs about the QImage ctor you're using and fix your code accordingly.
-
I am doing camera calibration through qt. I have several windows for it, such as exposure, blur, distortion and so on. I want to show the live camera feed in the labels present in each of the windows.
For testing purpose, I have created a glob and stored several demo images in a vector. Then, I am running a while loop and emitting a signal with the current image, inside a thread. The other thread is used to initialize the UI. Then, the signal is connected to the slots of the individual window to set the images in their label. But this approach crashes the application for windows which perform costly operations on the image. Is there any other approach to address this issue?std::string folder = "/path/of/images/*.jpg"; cv::glob(folder,images); void MainWindow::liveIMG::setReference(MainWindow *m) { this->m = m; } void MainWindow::liveIMG::run() { size_t i = 0; while (true) { if(i == m->images.size()) i = 0; m->img = cv::imread(m->images[i]); i++; QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888); emit updateImage(image); } }
@shreya_agrawal
As @Christian-Ehrlicher has said, a very common error we see with that constructor ofQImage
. Understand that your situation is compounded by this being in a thread: that means theemit()
does not block calling any slots which may access the signal's image data, it proceeds immediately, making it certain it will go wrong; if it were a non-thread direct connection you might get away with it. -
@shreya_agrawal said in Displaying live camera feed:
void MainWindow::liveIMG::run() {
size_t i = 0;
while (true)So, this is running in another thread (not the GUI thread)? And you also do not have any pause in this loop, so probably flooding the event queue with too many signals.
"But this approach crashes the application" - as always in such a situation run in debugger and post stack trace after crash to see where it is crashing.
@jsulm
Thank you for your reply!
The issue was in fact flooding the event queue with too many signals. Now, I am using a boolean condition to start and stop the loop whenever necessary. -
-
@jsulm
Thank you for your reply!
The issue was in fact flooding the event queue with too many signals. Now, I am using a boolean condition to start and stop the loop whenever necessary.@shreya_agrawal
If you say so. However, be aware if you have code:m->img = cv::imread(m->images[i]); i++; QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888); emit updateImage(image);
If you hit the
m->img = ...
line a second time while theimage
passed inemit updateImage(image)
has not yet been fully processed by whatever slot (in another thread in your case, and you are not using e.g. connected withBlockingQueuedConnection
) it will/should go wrong. Maybe your new "boolean condition to start and stop the loop whenever necessary" prevents this happening, I don't know. -
@shreya_agrawal
If you say so. However, be aware if you have code:m->img = cv::imread(m->images[i]); i++; QImage image(m->img.data, m->img.cols, m->img.rows, m->img.step, QImage::Format_RGB888); emit updateImage(image);
If you hit the
m->img = ...
line a second time while theimage
passed inemit updateImage(image)
has not yet been fully processed by whatever slot (in another thread in your case, and you are not using e.g. connected withBlockingQueuedConnection
) it will/should go wrong. Maybe your new "boolean condition to start and stop the loop whenever necessary" prevents this happening, I don't know.@JonB
Ah! Thanks for the heads up, will look into it further.