Within C++ (also using OpenCV) I'm creating a loop which displays a new image from file each iteration. To achieve this I've had to add in waitKey(1) otherwise only a blank window is displayed. I was just wondering why this millisecond delay must be included for the image to show each iteration and, if possible, if there is a method to display the image without requiring this delay.
Thanks in advance!
The function waitKey() waits for key event for a "delay" (here, 30
milliseconds). As explained in the OpenCV documentation, HighGui
(imshow() is a function of HighGui) need a call of waitKey reguraly,
in order to process its event loop.
Ie, if you don't call waitKey, HighGui cannot process windows events
like redraw, resizing, input event etc. So just call it, even with a
1ms delay :)
what does waitKey (30) mean in OpenCV?
Related
I want to process frames with Qt. I use QMediaplayer to load a video.
I used the implmentation I found here. I have additional data stored as "frame by frame values" in a .csv file.
For this I want to get the exact frame number of the current frame which is processed in the "present" function of my QAbstractVideoSurface implementation. It works while playing/stopping and pausing the video, but not when I attach a slider to the video...it seems that the QMediaplayer is out of sync with the data which is displayed. I tried getting the current time of the QMediaplayer while being in the QAbstractVideoSurface::present() function but it just won't work. Setting the time from outside while the slider is being moved was also no success for me.
My main problem is that QVideoFrame::startTime() and QVideoFrame::stopTime() does not deliver correct results after QMediaPlayer::setPosition(int) was called!
Does anyone have ideas how I get the current frame number for a QVideoFrame?
Has anyone figured out how to display smooth video (i.e. a series of bitmaps) in a FireMonkey application, HD or 3D? In VCL you could write to a canvas from a thread and this would work perfectly, but this does not work in FMX. To make things worse, the apparently only reliable way is to use TImage, and that seems to be updated from the main thread (open a menu and video freezes temporarily). All EMB examples I could find all either write to TImage from the main thread, or use Synchronize(). These limitations make FMX unusable for decent video display so I am looking for a hack or possibly bypass of FMX. I use XE5/C++ but welcome any suggestions. Target OS is both Windows 7+ & OS X. Thanks!
How about putting a TPaintbox on your form to hold the video. In the OnPaint method you simply draw the next frame to the paintbox canvas. Now put a TTimer on the form, set the interval to the frame rate required. In the OnTimer event for the timer just write paintbox1.repaint
This should give you regular frames no matter what else the program is doing.
For extra safety, you could increment a frame number in the OnTimer event. Now in the paintbox paint method you know which frame to paint. This means you won't jump frames if something else calls the paint method as well as the timer - you will just end up repainting the same frame for the extra call to OnPaint.
I use this for marching ants selections although I go one step further and use an overlaid canvas so I can draw independently to the selection and the underlying paintbox canvas to remove the need to repaint the main canvas when the selection changes. That requires calls to API but I guess you won't need it unless you are doing videos with a transparent colour.
Further research, including some talks with the Itinerant developer, has unfortunately made it clear that, due to concurrency restrictions, FM has been designed so that all GPU access goes through the main thread and therefore painting will always be limited. As a result I have decided FM is not suitable for my needs and I am re-evaluating my options.
I am having problem to implement the following scenario. My problem statement goes like this:
I have 3 threads. ThreadCamera for grabbing frames from a camera. ThreadProcess for processing (doing some image processing with OpenCV on the image/frame grabbed) the frame and main GUI Thread for displaying the image.
I don't know how much time ThreadProcess will take to process an image. So I want to pass the image from ThreadCamera to ThreadProcess , do some image processing on the image and pass it to the main GUI Thread for display.
When ThreadProcess processes the image the ThreadCamera should sleep. I.e. it should not grab further frames from the camera. When the ThreadProcess finishes the image processing task it should pass the image and some information to the main GUI Thread. After this only the ThreadCamera should wake up and grab the next frame/image from the camera runnig in that(ThreadCamera) thread.
Thanx Guys...after some comments to put Camera and Image Processing job in a single thread i would like to know another point..which is..
What if don't want to sleep the camera while the processing is going on?It does not matter to me if I loose some of the frames grabbed by CameraThread(which in any case I am loosing if i sleep or not sleep the camera)
I am using QObject for each process(Camera Process and Image Processing job) and movetoThread command to make it run in a particular thread.
Any insight about the implementation and signal/slot design will be helpful..
What you're looking for is a simple "Publish/Subscribe" pattern. In this type of 'distribution' pattern, all messages are sent and just dropped by the client when it's not in a state to receive images
I would implement this as the following in your application:
Have all separate threads (Camera,Processing,Gui) like you already do.
Have the CameraThread peridocally (through a qTimer signal maybe if you want to make it simple) capture an image and sent it over a signal/slot connection to the processingThread.
When the processingThread is processing an image, it sets a state flag (can just be a member variable, a bool would work) to say that its currently processing an image. When you're done processing the image you set the flag to say that you're not processing.
In the processingThreads slot, which receives the images from the CameraThread, you will first check to see if you're currently processing an image. If you are, you do not do anything with the signals data and you just return. If you are not processing an image, you will store the signals data and call the process function.
The trick to making this work is to include this function call (QCoreApplication::processEvents()) in your ProcessingThreads main loop in the processing function. This will allow your ProcessingThread to process any signals it gets WHILE it's doing something useful.
The state variable checking will allow you to 'drop' all new images sent to you while you're processing a current one and not queue them up.
I am writing a GUI program using Qt and doing some video processing with OpenCV. I am displaying the result of the OpenCV process (which is in a separate thread) in a label in the main GUI thread.
The problem I am having is cv::waitKey doesn't work unless I open a native OpenCV window opened using cv::namedWindow or cv::imshow. Does anybody know how to solve this?
Short example:
void Thread::run()
{
//needed variables
cv::VideoCapture capture(0);
cv::Mat image;
//main loop
//cv::namedWindow("test");
forever
{
capture>> image;
if(!image.data)
break;
emit paintToDisplay(convertToQImage(image));
cv::waitKey(40);
}
}
With //cv::namedWindow("test"); i.e. commented, the program crashes with access violation error.
With cv::namedWindow("test"); i.e. uncommented, the program displays perfect but there's a window (named test) I don't want or need. Anybody?
cv::waitKey() only works with OpenCV windows, which is not what you are using right now.
I suggest you investigate a QT alternative, most probably qSleep(), which is provided by the QTest module:
QTest::qSleep(40);
cv::waitkey is part of opencv's gui loop for show window
If you simply want to wait for a key press see QWaitcondition.
OR you could display another named window with no image in it, or a small 1,1 pixel image and just ignore the window
I found a solution to use msleep(). It's easy to use since it's a member of the class QThread.
Just thought i'd update this in case someone with a similar problem finds this thread.
You can call
qApp->processEvents();
instead of
cv::waitKey(40);
in the loop to make your application responsive and let the rest of the loop do their job.
I've made a project with Qt and OpenGL.
In Qt paintGL() was repeatedly call I beleive, so I was able to change values outside of that function and call update() so that it would paint a new image.
I also believe that it called initializeGL() as soon as you start up the program.
Now my question is:
I want that same functionality in a different program. I do not need to draw any images, etc. I just was wondering if there was a way to make a function like paintGL() that keeps being called so the application never closes. I tried just using a while(true) loop that kept my program running, but the GUI was inactive because of the while loop.
Any tips, other than threading preferably.
Thanks.
The exact mechanism will depend on which GUI toolkit you are using. In general, your app needs to service the run loop constantly for events to be dispatched. That is why your app was unresponsive when you had it running in a while loop.
If you need something repainted constantly, the easiest way is to create a timer when your window is created, and then in the timer even handler or callback, you invalidate your window which forces a repaint. Your paint handler can then be called at the frequency of your timer, such as 25 times per second.