Alternative to waitKey() for updating window in OpenCV - opencv

All examples and books I've seen so far recommends using waitKey(1) to force repaint OpenCV window. That looks weird and too hacky. Why wait for even 1ms when you don't have to?
Are there any alternatives? I tried cv::updateWindow but it seems to require OpenGL and therefore crashes. I'm using VC++ on Windows.

I looked in to source and as #Dan Masek said, there doesn't seem to be any other functions to process windows message. So I ended up writing my own little DoEvents() function for VC++. Below is the full source code that uses OpenCV to display video frame by frame while skipping desired number of frames.
#include <windows.h>
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
bool DoEvents();
int main(int argc, char *argv[])
{
VideoCapture cap(argv[1]);
if (!cap.isOpened())
return -1;
namedWindow("tree", CV_GUI_EXPANDED | CV_WINDOW_AUTOSIZE);
double frnb(cap.get(CV_CAP_PROP_FRAME_COUNT));
std::cout << "frame count = " << frnb << endl;
for (double fIdx = 0; fIdx < frnb; fIdx += 50) {
Mat frame;
cap.set(CV_CAP_PROP_POS_FRAMES, fIdx);
bool success = cap.read(frame);
if (!success) {
cout << "Cannot read frame " << endl;
break;
}
imshow("tree", frame);
if (!DoEvents())
return 0;
}
return 0;
}
bool DoEvents()
{
MSG msg;
BOOL result;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
result = ::GetMessage(&msg, NULL, 0, 0);
if (result == 0) // WM_QUIT
{
::PostQuitMessage(msg.wParam);
return false;
}
else if (result == -1)
return true; //error occured
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
return true;
}

Related

opencv imread exit code 0xC0000409

The code is:
#include <iostream>
#include <opencv2/opencv.hpp>
int main (int argc, char** argv) {
auto path = "C:/Users/huhua/Pictures/11.jpg";
auto img = cv::imread(path);
if (img.empty()) {
std::cout << "is empty" << std::endl;
return 1;
}
cv::imshow("demo", img);
cv::waitKey(0);
return 0;
}
The 11.jpg exist. And if I use another 11.bmp. It works well.
After debug. The error is throw at libjpeg-trubo/src/jdatasr.c
fill_input_buffer(j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr)cinfo->src;
size_t nbytes;
// error is throw at here
nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
// ...
}
Is my libjpeg issue??
How to fix this?
The 11.jpg image:
Update:
The OpenCV info
Update on 2021/10/19:
The reason is I set the cmake_toolchain_path after project(xxx). I should set the cmake_toolchain_path before project.
https://github.com/microsoft/vcpkg/discussions/20802

openCV:capture images from webcam but only greysreen

Can anyone tell me what's wrong with my code? I can use my webcam by other code, so there is nothing do with the supported problem. In my code below, I must set the camera index into a loop so that i can motivate my camera(the led inductor is on, simply set "CvCapture* camera=cvCaptureFromCAM(0)" can not run! that's wierd!).However, I just can obtain a greysreen,why?
#include "highgui.h"
#include "cv.h"
int main(int grac, char** grav)
{
CvCapture* camera;
int index;
for (index = -1; index <1; index++)
{
camera = cvCaptureFromCAM(index);
if (camera)
{
printf("%d\n", index);
IplImage* f;
cvNamedWindow("camera", CV_WINDOW_AUTOSIZE);
while (1)
{
f = cvQueryFrame(camera);
cvShowImage("camera", f);
char c = cvWaitKey(33);
if (c == 27)break;
}
}
}
cvReleaseCapture(&camera);
cvDestroyAllWindows;
}

objectmaker.exe in haarclassification

I am trying in vs2012 and opencv 2.4.11 to run the objectmaker.exe in my project file which is created by the code and successfully build in release but when i am trying to double click to open it there is a run time error i cant fix it any help please .. my code is :
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
// for filelisting
#include <stdio.h>
#include <io.h>
// for fileoutput
#include <string>
#include <fstream>
#include <sstream>
#include "dirent.h"
#include <sys/types.h>
using namespace std;
using namespace cv;
IplImage* image=0;
IplImage* image2=0;
//int start_roi=0;
int roi_x0=0;
int roi_y0=0;
int roi_x1=0;
int roi_y1=0;
int numOfRec=0;
int startDraw = 0;
char* window_name="<SPACE>add <ENTER>save and load next <ESC>exit";
string IntToString(int num)
{
ostringstream myStream; //creates an ostringstream object
myStream << num << flush;
/*
* outputs the number into the string stream and then flushes
* the buffer (makes sure the output is put into the stream)
*/
return(myStream.str()); //returns the string form of the stringstream object
};
void on_mouse(int event,int x,int y,int flag, void *param)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
if(!startDraw)
{
roi_x0=x;
roi_y0=y;
startDraw = 1;
} else {
roi_x1=x;
roi_y1=y;
startDraw = 0;
}
}
if(event==CV_EVENT_MOUSEMOVE && startDraw)
{
//redraw ROI selection
image2=cvCloneImage(image);
cvRectangle(image2,cvPoint(roi_x0,roi_y0),cvPoint(x,y),
CV_RGB(255,0,255),1);
cvShowImage(window_name,image2);
cvReleaseImage(&image2);
}
}
int main(int argc, char** argv)
{
int iKey=0;
string strPrefix;
string strPostfix;
string input_directory;
string output_file;
if(argc != 3) {
fprintf(stderr, "%s output_info.txt raw/data/directory/\n", argv[0]);
return -1;
}
input_directory = argv[2];
output_file = argv[1];
/* Get a file listing of all files with in the input directory */
DIR *dir_p = opendir (input_directory.c_str());
struct dirent *dir_entry_p;
if(dir_p == NULL) {
fprintf(stderr, "Failed to open directory %s\n", input_directory.c_str());
return -1;
}
fprintf(stderr, "Object Marker: Input Directory: %s Output File: %s\n", input_directory.c_str(), output_file.c_str());
// init highgui
cvAddSearchPath(input_directory);
cvNamedWindow(window_name,1);
cvSetMouseCallback(window_name,on_mouse, NULL);
fprintf(stderr, "Opening directory...");
// init output of rectangles to the info file
ofstream output(output_file.c_str());
fprintf(stderr, "done.\n");
while((dir_entry_p = readdir(dir_p)) != NULL)
{
numOfRec=0;
if(strcmp(dir_entry_p->d_name, ""))
fprintf(stderr, "Examining file %s\n", dir_entry_p->d_name);
/* TODO: Assign postfix/prefix info */
strPostfix="";
strPrefix=input_directory;
strPrefix+=dir_entry_p->d_name;
//strPrefix+=bmp_file.name;
fprintf(stderr, "Loading image %s\n", strPrefix.c_str());
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0)
{
// work on current image
do
{
cvShowImage(window_name,image);
// used cvWaitKey returns:
// <Enter>=13 save added rectangles and show next image
// <ESC>=27 exit program
// <Space>=32 add rectangle to current image
// any other key clears rectangle drawing only
iKey=cvWaitKey(0);
switch(iKey)
{
case 27:
cvReleaseImage(&image);
cvDestroyWindow(window_name);
return 0;
case 32:
numOfRec++;
printf(" %d. rect x=%d\ty=%d\tx2h=%d\ty2=%d\n",numOfRec,roi_x0,roi_y0,roi_x1,roi_y1);
//printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// currently two draw directions possible:
// from top left to bottom right or vice versa
if(roi_x0<roi_x1 && roi_y0<roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x0,roi_y0,roi_x1-roi_x0,roi_y1-roi_y0);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x0)+" "+IntToString(roi_y0)+" "+IntToString(roi_x1-roi_x0)+" "+IntToString(roi_y1-roi_y0);
}
if(roi_x0>roi_x1 && roi_y0>roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x1)+" "+IntToString(roi_y1)+" "+IntToString(roi_x0-roi_x1)+" "+IntToString(roi_y0-roi_y1);
}
break;
}
}
while(iKey!=13);
// save to info file as later used for HaarTraining:
// <rel_path>\bmp_file.name numOfRec x0 y0 width0 height0 x1 y1 width1 height1...
if(numOfRec>0 && iKey==13)
{
//append line
/* TODO: Store output information. */
output << strPrefix << " "<< numOfRec << strPostfix <<"\n";
}
cvReleaseImage(&image);
} else {
fprintf(stderr, "Failed to load image, %s\n", strPrefix.c_str());
}
}
output.close();
cvDestroyWindow(window_name);
closedir(dir_p);
return 0;
}

OpenCV -- Function to grab frame

I'm trying to create a function that gives the frame at the moment the function is called. So when i call the function, it should give the picture of the object that is in front of the camera at the moment the function is called.
I have been trying for hours, but i can't succeed. Anyone?
main file:
#include "camera.h"
#include <iostream>
#include <unistd.h>
int main(int argc, const char *argv[])
{
Camera cam;
cam.setVideoSource(0);
cv::Mat image;
cv::Mat image2;
cam.openCamera();
cam.grabFrame(image); // grap first frame
sleep(5); // wait 5 seconds
cam.grabFrame(image2); // capture seconds frame
cv::namedWindow("1",CV_WINDOW_KEEPRATIO);
cv::imshow("1",image);
cv::namedWindow("2",CV_WINDOW_KEEPRATIO);
cv::imshow("2",image2);
cv::waitKey();
return 0;
}
camera.h file
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
class Camera{
private:
int videoSource; //video source
cv::VideoCapture cap; //capture of camera
public:
//constructor default videoSourceNumber
Camera() : videoSource(0) {};
//Setter: videoSourceNumber
void setVideoSource(int sourceNumber){
videoSource = sourceNumber;
}
//function OPEN CAMERA
//opens the video capture
//returns true if successfull
bool openCamera() {
cap.open(videoSource);
if (!cap.isOpened()){
std::cout << "---- Error ----" << std::endl;
return false;
}
return true;
}
//function GRAB FRAME
//grabs the frame of the video capture
//returns true if successfull
bool grabFrame(cv::Mat& cameraFrame){
cap >> cameraFrame;
if (cameraFrame.empty()){
std::cout << "---- Error ----" << std::endl;
return false;
}
return true;
}
};
A somewhat unsatisfying solution:
//function GRAB FRAME
//grabs the frame of the video capture
//returns true if successfull
bool grabFrame(cv::Mat& cameraFrame){
int attempts = 0;
do {
cap >> cameraFrame;
attempts++;
} while (cameraFrame.empty() && attempts < 10);
if (cameraFrame.empty()){
std::cout << "---- Error ----" << std::endl;
return false;
}
return true;
}
I also played with this for a while and could not find a solution. My instinct was to give the camera more "warm-up" time before asking for the first frame. A sleep of 10 seconds seems to do so reliably, but that is not acceptable. If I don't give it any sleep before the first grabFrame() call, the while loop I added only seems to run twice.
Credit to: https://stackoverflow.com/a/9285151/2518451

access webcam fail

i am still new on opencv, i make simple program based on sample to access webcam but always fails. i change variable id to 0,1,2...100 but i got same result. this is my program:
#include "cv.h"
#include "highgui.h"
#include "stdio.h"
#include "iostream"
// A Simple Camera Capture Framework
int main()
{
IplImage* img = NULL;
CvCapture* cap = NULL;
int id=0;
cap = cvCaptureFromCAM(id);
cvNamedWindow("Images",CV_WINDOW_AUTOSIZE);
if ( !cap )
printf("ERROR\n\n");
else
for(;;)
{
img = cvQueryFrame(cap);
cvShowImage("Imagenes", img);
cvWaitKey(10);
}
cvReleaseImage(&img);
cvReleaseCapture(&cap);
return 0;
}
thank you for your help
Do yourself a favor and check the return of the functions. Maybe some of them are failing and you'll never know why.
Another tip: try with id = -1.
#include <iostream>
#include <sstream>
#include <string>
#include <cv.h>
#include <highgui.h>
int main()
{
CvCapture* capture = NULL;
if ((capture = cvCaptureFromCAM(-1)) == NULL)
{
fprintf(stderr, "ERROR: capture is NULL \n");
return -1;
}
cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE);
cvQueryFrame(capture); // Sometimes needed to get correct data
IplImage* frame = NULL;
while (1)
{
if ((frame = cvQueryFrame(capture)) == NULL)
{
fprintf( stderr, "ERROR: cvQueryFrame failed\n");
break;
}
if (frame == NULL)
{
usleep(100000);
continue;
}
cvShowImage("mywindow", frame); // Do not release the frame!
int key = cvWaitKey(10);
if (key == 27) // ESC was pressed
break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("mywindow");
return 0;
}

Resources