video capturing with opencv - c

I am coding an app in C for windows using openCV. I want to capture video from the webcam and show it in a window.
The app is almost finished but it doesn't work properly. I think it's because of the cvQueryFrame() that alwasy returns NULL and I don't know why. I tried capturing some frames before going into the while but didn't fix the problem.
The compiler doesn't show me any error. It's not a compiling problem but an execution one. I debugged it step by step and in the line
if(!originalImg) break;
it allways jumps out of the while. That's why the app doesn't remain in execution. It opens and closes very fast.
Here's the code:
void main()
{
cvNamedWindow("Original Image", CV_WINDOW_AUTOSIZE);
while (1)
{
originalImg = cvQueryFrame(capture);
if(!originalImg) break;
cvShowImage("Original Image", originalImg);
c = cvWaitKey(10);
if( c == 27 ) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Original Image");
}
Let's see if someone have some idea and can help me with this, thanks!

Assuming the compilation was ok (included all relevant libraries), it may be that the camera has not been installed properly. Can you check if you are able to use the webcam otherwise (using some other software)
If the compilation is actually the issue, please refer to the following related question:
https://stackoverflow.com/a/5313594/1218748
Quick summary:
Recompile opencv_highgui changing the "Preprocesser Definitions" in the C/C++ panel of the properties page to include: HAVE_VIDEOINPUT HAVE_DSHOW
There are other good answers that raise some relvant good points, but my gut feeling is that the above solution would work :-)

It seems you have not opened capture.
Add in the beginning of main:
CvCapture* capture = 0;
capture = cvCaptureFromCAM(0);

Related

C - Tried to start a text editor using exec system call but vim crashes due to "Error reading input" resembling issue with Nano

Good day!
first time posting on stack overflow. Hope, I get this right.
For an exercise project, I would like my program to start vim or nano (doesn't matter for now) before proceeding.
Using the below code, vim starts. I.e. I can see the vim interface in the terminal window.
But: As soon as I start typing, after one or two characters, vim crashes giving me the following output:
Vim: Error reading input, exiting...
Vim: Finished.
Here's my code snippet:
pid_t childPid = fork();
if (childPid) {
// ...
}
else {
// open [filename.md] in vim
char * vim = "/bin/vim";
filePath = "/home/myusername/Documents/test.md";
execl(vim, vim, filePath, NULL);
}
Not sure, if I have to block the input recognition of the parent process or similar.
Guess I went a bit too far for my level of knowledge. It would be great to have a solution anyway. I think knowing a bit of how to solve this, might help when I encounter this topic later on.
I was able to fix this a little bit later. I had forgotten to make sure the parent process waits for the child process. After adding wait, everything worked as I expected.

TTF_OpenFont fails on Nth attempt

I'm trying to make a game in C using SDL_ttf to display the score every time the diplay is refreshed. The code looks like :
SDL_Surface *score = NULL;
TTF_Font *font;
SDL_Color color = { 255, 255, 255 };
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
if (font == NULL) {
printf("%s\n", TTF_GetError());
}
score = TTF_RenderText_Solid( font, "score to display", color );
SDL_BlitSurface( score, NULL, screen, NULL );
SDL_Flip(screen);
When I launch the game, everything works properly, but after a while the game crashes and I get the following error :
Couldn't open /home/sophie/Bureau/snake/data/ubuntu.ttf
libgcc_s.so.1 must be installed for pthread_cancel to work
Abandon (core dumped)
I tried different fonts but I still have this problem.
Then I used a counter in the main loop of the game and found that the game always crashes after the 1008th time, regardless of the speed I wanted it to work at (in snake everything goes faster when you score points).
I don't know where does the problem comes from, nor what exactly does the error message mean.
Please tell me if you have any ideas, or if my question is poorly formulated. I looked on several forums and found nothing corresponding to my case, I could use any help now !
Thanks in advance
It looks like you're repeatedly opening the font every time you go through this function:
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
While it may not be in the main game loop as Jongware suspected, you mentioned that after 1008 executions through this code path, the code crashes.
What is happening is that some resource is being leaked. Either the resource needs to be released by calling TTF_CloseFont() or (more efficient) hold onto the handle after the first time you open it and re-use it each time. Use a static declaration for the font and initialize to NULL:
static TTF_Font *font = NULL;
Then, if it hasn't been opened yet, open it:
if (!font) {
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
}
This will initialize font the first time while subsequent iterations over the code will not unnecessarily re-do the process and leak the resource.
You mentioned that the code crashes after 1008 times through this function. That's pretty close to 1024. As memory serves, Linux has a limit of 1024 file handles per process (this is probably tunable in the kernel but I have run into this limitation in debugging resource leaks before). There are probably 16 other file handles open by your process and then 1 process being leaked by each invocation of TTF_OpenFont. Once you go above 1024, boom.
You can check the number of open file handles of a particular process (<pid>) by inspecting the number of file descriptors in /proc/<pid>/fd/.

how to create a deinterlacer in xinimin.c (xine)

I've taken xinimin.c and added seek and osd functionality. The last big piece that I need to implement is deinterlacing, however, I'm finding very little documentation. I've been through the hacker's guide and of course I haved googled and googled. I found the deprecated method:
xine_set_param(stream, XINE_PARAM_VO_DEINTERLACE, 1);
which did not work. I saw that the current method involves post plugins, but my /usr/include/xine/post.h doesn't have the word deinterlace in it.
Can anyone provide an example of how to implement deinterlacing. It would be nice to have the flexibility down the road to change the deinterlacer, but something equivalent to the -D option on the command line is what I'm looking for to start with.
Is there a good resource for example source files?
Is this what you are looking for? src/post/deinterlace directory:
(4 links to pretty much the same:)
debian.org/hg/xine-lib
github || huceke/xine-lib-vaapi/tree/master/src/post/deinterlace
fossies dox ** xine-lib 1.2.1, deinterlace.h File Reference
xine_plugin.c File Reference
From hackersguide - Walking the source tree:
post
Video and audio post effect plugins live here. Post plugins
modify streams of video frames or audio buffers as they leave
the decoder to provide conversion or effects.
deinterlace (imported)
The tvtime deinterlacer as a xine video filter post.
hackersguide, Plugin system
Edit:
I have only installed libxine, not anything else.
It is however a good idea to download the source as the project in large part is documented in the code. If you use i.e. Vim it is nice to use it with cscope and/or ctags. (As show in this tutorial.). Then you can jump to functions, definitions, callers, ... (across files etc), simply by a couple of key strokes. (They map where every function is defined, called, etc.)
When compiling, if on linux at least, I have to add the lib's at end (after source file):
gcc -Wall -Wextra -pedantic -std=c89 -o muxine muxine.c -lX11 -lxine
Perhaps this'll get you further on the way: Using sample code, muxine.c,:
And reading source documentation, (mainly here): xine.h
I added in main:
const char* const *tmp;
xine_post_t *post_x;
xine_post_api_t *post_api;
xine_post_in_t *input_api;
xine_post_api_descr_t *param;
const char *post_plug_t = "tvtime";
/*const char *post_plug_d = "deinterlace"; perhaps this?? */
After the existing sample code:
ao_port = xine_open_audio_driver(xine , ao_driver, NULL);
stream = xine_stream_new(xine, ao_port, vo_port);
I added
/* get a list of all available post plugins */
if((tmp = xine_list_post_plugins(xine)) == NULL) {
fprintf(stderr, "Unable to get post plugins\n");
xine_exit(xine);
return 1;
}
printf("Post plugins:\n");
while (*tmp != NULL)
printf(" %s\n", *tmp++);
/* initialize a post plugin */
if ((post_x = xine_post_init(xine, post_plug_t, 1,
&ao_port, &vo_port)) == NULL) {
fprintf(stderr, " *ERR: Unable to 'post init' %s;\n",
post_plug_t);
xine_exit(xine);
return 1;
}
/* get a list of all outputs of a post plugin */
tmp = xine_post_list_outputs(post_x);
printf("Post List Outputs:\n");
while (*tmp != NULL)
printf(" %s\n", *tmp++);
! I get at least tvtime. Believe that is the deinterlacing plugin. (Sounds like it when reading the src/post/... comments.
One have the struct xine_post_api_t whic in turn has set_parameters(), that can be used to control the plugin (from the looks of it).

c - GTK3.0 GUI freezes when using "g_spawn_async_with_pipes()"

I've written a very simple front end for ffmpeg (converting stuff: video -> mp3) in GTK3.0/C for linux. For spawning ffmpeg I use g_spawn_async_with_pipes(). I thought this was the right way to execute stuff like that without having the GUI freeze up - but it does though. So - how can I prevent it from freezing - so I can f.e. display a spinner?
You might need to add something like"
while (gtk_events_pending ()) {
gtk_main_iteration_do (FALSE);
}
That is, to let GTK process the pending events (like drawing the UI).
I suppose you are processing the output of ffmpeg with g_io_add_watch
or similar.

How can I make the printer work in C in MS VC++ Express edition?

I am using VC++ 2008 express edition for C. When I try to run this:
/* Demonstrates printer output. */
#include <stdio.h>
main()
{
float f = 2.0134;
fprintf(stdprn, "This message is printed.\n\n");
fprintf(stdprn, "And now some numbers:\n\n");
fprintf(stdprn, "The square of %f is %f.", f, f*f);
/* Send a form feed */
fprintf(stdprn, "\f");
}
I get four of these errors: error C2065: 'stdprn' : undeclared identifier.
On this forum, they wrote that it works to define the printer as follows:
FILE *printer;
printer = fopen("PRN", "w");
EDIT
It builds with a warning that fopen is unsafe. When it runs the error appears:
Debug Assertion fails.
File: f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c
Line: 55
Expression: (str != NULL)
The stdprn stream was an extension provided by Borland compilers - as far as I know, MS have never supported it. Regarding the use of fopen to open the printer device, I don't think this will work with any recent versions of Windows, but a couple of things to try:
use PRN: as the name instead of PRN (note the colon)
try opening the specific device using (for example) LPT1: (once again, note the colon). This will of course not work if you don't have a printer attached.
don't depend on a printer dialog coming up - you are not really using the WIndows printing system when you take this approach (and so it probably won't solve your problem, but is worth a try).
I do not have a printer attached, but I do have the Microsoft XPS document writer installed, s it shoulod at least bring up the standard Windows Print dialog from which one can choose the printer.
No. It wouldn't bring up a dialogue. This is because you are flushing data out to a file. And not going through the circuitous Win32 API.
The print doesn't work because the data is not proper PDL -- something that the printer could understand. For the print to work fine, you need to push in a PDL file, with language specific constructs. This varies from printer to printer, a PS printer will need you to push in a PostScript snippet, a PCL -- a PCL command-set and in case of MXDW you will have to write up XML based page description markup and create a zip file (with all resources embedded in it) i.e. an XPS file to get proper printout.
The PDL constructs are important because otherwise the printer doesn't know where to put the data, which color to print it on, what orientation to use, how many copies to print and so on and so forth.
Edit: I am curious why you are doing this. I understand portability is probably something you are trying to address. But apart from that, I'd like to know, there may be better alternatives available. Win32 Print Subsytem APIs are something that you ought to lookup if you are trying to print programmatically on Windows with any degree of fidelity.
Edit#2:
EDIT It builds with a warning that fopen is unsafe.
This is because MS suggests you use the safer versions nowadays fopen_s . See Security Enhancements in the CRT.
When it runs the error appears:
Debug Assertion fails. File: f:\dd\vctools\crt_bld\self_x86\crt\src\fprintf.c Line: 55
Expression: (str != NULL)
This is because fopen (whose return value you do not check) returns a NULL pointer. The file open failed. Also, if it did succeed a matching fclose call is called for.
There's no such thing as stdprn in ANSI C, it was a nonstandard extension provided by some compilers many years ago.
Today to print you have to use the specific APIs provided on your platform; to print on Windows you have to use the printing APIs to manage the printing of the document and obtain a DC to the printer and the GDI APIs to perform the actual drawing on the DC.
On UNIX-like OSes, instead, usually CUPS is used.
You can substitute the printer using this command with net use, see here on the MSDN kb
NET USE LPT1 \\server_name\printer_name
There is an excellent chapter on printing in DOS using the BIOS, ok, its a bit antiquated but interesting to read purely for nostalgic sake.
Onto your problem, you may need to use CreateFile to open the LPT1 port, see here for an example, I have it duplicated it here, for your benefit.
HANDLE hFile;
hFile = CreateFile("LPT1", GENERIC_WRITE, 0,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
// handle error
}
OVERLAPPED ov = {};
ov.hEvent = CreateEvent(0, false, false, 0);
char szData[] = "1234567890";
DWORD p;
if (!WriteFile(hFile,szData, 10, &p, &ov))
{
if (GetLastError() != ERROR_IO_PENDING)
{
// handle error
}
}
// Wait for write op to complete (maximum 3 second)
DWORD dwWait = WaitForSingleObject(ov.hEvent, 3000);
if (dwWait == WAIT_TIMEOUT)
{
// it took more than 3 seconds
} else if (dwWait == WAIT_OBJECT_0)
{
// the write op completed,
// call GetOverlappedResult(...)
}
CloseHandle(ov.hEvent);
CloseHandle(hFile);
But if you insist on opening the LPT1 port directly, error checking is omitted...
FILE *prn = fopen("lpt1", "w");
fprintf(prn, "Hello World\n\f");
fclose(prn);
Hope this helps,
Best regards,
Tom.

Resources