Capture image from webcam and display it - OpenCV - Eclipse - Windows - c

I'm new to OpenCV and I want to display what my webcam sees with OpenCV. I'm using the C Coding Language.
I've tried with this code:
#include <stdio.h>
#include <cv.h> // Include the OpenCV library
#include <highgui.h> // Include interfaces for video capturing
int main()
{
cvNamedWindow("Window", CV_WINDOW_AUTOSIZE);
CvCapture* capture =cvCreateCameraCapture(-1);
if (!capture){
printf("Error. Cannot capture.");
}
else{
cvNamedWindow("Window", CV_WINDOW_AUTOSIZE);
while (1){
IplImage* frame = cvQueryFrame(capture);
if(!frame){
printf("Error. Cannot get the frame.");
break;
}
cvShowImage("Window",frame);
}
cvReleaseCapture(&capture);
cvDestroyWindow("Window");
}
return 0;
}
My webcam's light turns on, but the result is a completely grey window, with no image.
Can you help me?

You need to add
cvWaitKey(30);
to the end of while-loop.
cvWaitKey(x) / cv::waitKey(x) does two things:
It waits for x milliseconds for a key press. If a key was pressed during that time, it returns the key's ASCII code. Otherwise, it returns -1.
It handles any windowing events, such as creating windows with cvNamedWindow(), or showing images with cvShowImage().
A common mistake for opencv newcomers is to call cvShowImage() in a loop through video frames, without following up each draw with cvWaitKey(30). In this case, nothing appears on screen, because highgui is never given time to process the draw requests from cvShowImage().
See What does OpenCV's cvWaitKey( ) function do? for more info.

Related

OpenCV fails to recognize webcam, but mplayer succeeds

As a first step on a larger project I was trying to display the imagem from my webcam using OpenCV:
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int
main()
{
cv::VideoCapture cap(-1);
if (!cap.isOpened())
exit(EXIT_FAILURE);
cv::Mat frame;
bool done = false;
while (!done) {
cap >> frame;
cv::imshow("webcam", frame);
done = (cv::waitKey(30) >= 0);
}
return EXIT_SUCCESS;
}
This returns an error code (!cap.isOpened() passes ,confirmed with gdb). Initially I had 0 instead of -1. When searching this site -1 was suggested, but it was to no avail. I also tried 1 through 3, as another user suggested it.
I can display my webcam using mplayer, more specifically mplayer tv:// -tv driver=v4l2.
v4l2 is the "video for linux" driver. I noticed OpenCV can be installed with such driver by compiling it with -DWITH_V4L and -DWITH_LIBV4L (v4l USE flag in Gentoo). After recompiling OpenCV with it, it successfully recognized the webcam. GTK support seems to be needed to display the image.

STM32CubeF7 BSP LCD attempt

I'm trying to display a string on stm32f769i-disco's LED with BSP libraries from STM32CubeF7. However, nothing happens. Here is the code:
#include "stm32f7xx_hal.h"
#include "stm32f769i_discovery.h"
#include "stm32f769i_discovery_lcd.h"
#include "stm32f7xx.h"
#include <stdio.h>
char str[] = "Hello from BSP LCD demo!";
void LCDInit() {
// Initialize the LCD using the BSP_LCD_Init() function.
BSP_LCD_Init();
// Select the LCD layer to be used using the BSP_LCD_SelectLayer() function.
//BSP_LCD_SelectLayer(0);
BSP_LCD_LayerDefaultInit(LTDC_DEFAULT_ACTIVE_LAYER, LCD_FB_START_ADDRESS);
BSP_LCD_SelectLayer(LTDC_DEFAULT_ACTIVE_LAYER);
// Enable the LCD display using the BSP_LCD_DisplayOn() function.
BSP_LCD_DisplayOn();
// Clear the whole LCD using BSP_LCD_Clear() function or only one specified string line using the BSP_LCD_ClearStringLine() function.
BSP_LCD_Clear(LCD_COLOR_LIGHTGRAY);
HAL_Delay(1000);
BSP_LCD_SetBackColor(LCD_COLOR_LIGHTGRAY);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
// Display a character on the specified line and column using the BSP_LCD_DisplayChar() function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
BSP_LCD_DisplayStringAt(100, 100, str, CENTER_MODE);
}
int main(void) {
LCDInit();
BSP_LED_Init(LED_GREEN);
while(1) {
for (int i=0;i<1000000;i++);
BSP_LED_Toggle(LED_GREEN);
}
return 0;
}
If I remove the call to LCDInit, my LED toggles, if I call the LCDInit, nothing happens (the LED doesn't toggle) and the LCD stays black. Any ideas?
I've basically tried following the instructions in stm32f769i_discovery_lcd.c, without luck:
2. Driver description:
---------------------
+ Initialization steps:
o Initialize the LCD using the BSP_LCD_Init() function.
o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function.
o Enable the LCD display using the BSP_LCD_DisplayOn() function.
+ Options
o Configure and enable the color keying functionality using the
BSP_LCD_SetColorKeying() function.
o Modify in the fly the transparency and/or the frame buffer address
using the following functions:
- BSP_LCD_SetTransparency()
- BSP_LCD_SetLayerAddress()
+ Display on LCD
o Clear the whole LCD using BSP_LCD_Clear() function or only one specified string
line using the BSP_LCD_ClearStringLine() function.
o Display a character on the specified line and column using the BSP_LCD_DisplayChar()
function or a complete string line using the BSP_LCD_DisplayStringAtLine() function.
o Display a string line on the specified position (x,y in pixel) and align mode
using the BSP_LCD_DisplayStringAtLine() function.
o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
on LCD using the available set of functions.
EDIT: When debugging with OpenOCD, gdb hangs if I set the breakpoint at the BSP_LCD_Init() line. If I run the debugger again, I can see the program is stuck at the WWDG_IRQHandler ().
In case this ever helps anyone, I'm going to post what turned out to be my issue (with the HAL library):
I have not particularly added any code that deals with overriding interrupt handlers, turns out even the HAL_init() call was blocked, because I had not added the following:
void SysTick_Handler(void)
{
HAL_IncTick();
}
Because of this, my HAL_Delay's would be waiting forever. Probably best to use the templates provided in the STM32CubeF7 templates folder, when starting out, so you don't make the same mistakes as I did..

OpenCV - CvVideoWriter codec error in raspbian

I'm making something like black box in raspberry pi.
I set OpenCV 2.4.3 and many video libraries.
( I referred this site - Opencv cannot acces my webcam )
And I compiled this sample code.
#include <stdio.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv/cxcore.h"
int main(void){
CvCapture* capture = cvCaptureFromCAM(0);
cvNameWindow("video", 1);
double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
CvSize frame_size = cvSize((int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
CvVideoWriter* writer = cvCreateVideoWriter("out.avi", -1, fps, frame_size, 1);
IpImage* frame;
while(1){
frame = cvQueryFrame(capture);
cvShowImage("video", frame);
if(cvWaitKey(38) == 27){
break;
}
}
cvReleaseVideoWriter(&writer);
cvReleaseCapture(&capture);
cvDestroyWindow("video");
return 0;
}
This code compiled successfully.
But when i run this process, there are some error.
OpenCV Error: Unsupported format or combination of formats (Gstreamer Opencv backend doesn't support this codec acutally.) in CvVideoWriter_GStreamer::open, file /home/pi/OpenCV-2.4.3/modules/highgui/src/cap_gstreamer.cpp, line 479
terminate called after throwing an instance of 'cv::Exception'
what(): /home/pi/OpenCV-2.4.3/modules/highgui/src/cap_gstreamer.cpp:479: error: (-210) Gstreamer Opencv backend doesn't support this codec acutally. in function CvVideoWriter_GStreamer::open
Aborted
So, i changed codec part in 'cvCreateVideoWriter' instead of -1.
I tried many types of codec like 'CV_FOURCC('M','J','P','G')' and so on..
but I cannot fix this problem.
How can i solve this problem? Please help me..

Function cvShowImage make program crash. Why? OpenCv

I am using OpenCV 2.3.1 with Windows 8. When I call function cvShowImage the program crashes. I am using codeblocks and I don't know why this happens.
If I comment the line the program runs well.
The code looks as follows:
IplImage *img1=NULL;
img1=cvLoadImage("LenaComFormas.pgm",CV_LOAD_IMAGE_GRAYSCALE);
cvShowImage("Original", img1);
cvWaitKey(0);
your code is working fine with Qt and opencv 2.4.3 on Windows7...possible checks you can do...
check links to the libraries...opencv_core231 , opencv_highgui231 , opencv_imgproc231...check includes to opencv2/opencv/core.hpp opencv2/opencv/highgui.hpp.
check the IplImage pointer img1
IplImage *img1 = cvLoadImage("",0);
if(img1==NULL)
return -1;
3 . check the support of *.pgm images...or else get the latest opencv and try...
EDIT..
4 . just for check try the following..
#include <opencv/opencv2/core.hpp>
#include <opencv/opencv2/highgui.hpp>
using namespace cv;
int main()
{
Mat image;
image = imread("",0);
imshow("TEST",image);
waitKey(0);
return 0;
}
Because image wasn't load (cvLoadImage returned NULL). You can use debugger to check it. Check the path to the file again.

xrandr related, C programming

Here is an example call to xrandr:
$ xrandr --output LVDS --mode 1680x1050 --pos 0x0 --rotate normal --output S-video --off --output DVI-0 --mode 1024x768 --pos 1680x104 --rotate normal
Think about a system where that call has success; there are two screens (LVDS and DVI-0) working with different resolutions. The DVI-0 one is on the right placed in the middle.
How can I get all this informations in a C program?
I checked the xrandr source code, but I found it difficult to read and there is no apparent way to query the --pos value (edit: it is hidden in plain sight, thanks to ernestopheles' answer I got it).
I know I can ask a _NET_WORKAREA with XGetWindowProperty, but as far as I saw it does not tell the screen positions, just the size of the ideal rectangle that contains them all.
After some other study of xrandr code, this code seems a step forward the solution.
Yet I am not convinced, xrandr.c around line 2940 assumes that crtc_info might be unavailable. I still miss the other way to get resolution and position.
#include <stdio.h>
#include <X11/extensions/Xrandr.h>
int main() {
Display *disp;
XRRScreenResources *screen;
XRROutputInfo *info;
XRRCrtcInfo *crtc_info;
int iscres;
int icrtc;
disp = XOpenDisplay(0);
screen = XRRGetScreenResources (disp, DefaultRootWindow(disp));
for (iscres = screen->noutput; iscres > 0; ) {
--iscres;
info = XRRGetOutputInfo (disp, screen, screen->outputs[iscres]);
if (info->connection == RR_Connected) {
for (icrtc = info->ncrtc; icrtc > 0;) {
--icrtc;
crtc_info = XRRGetCrtcInfo (disp, screen, screen->crtcs[icrtc]);
fprintf(stderr, "==> %dx%d+%dx%d\n", crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height);
XRRFreeCrtcInfo(crtc_info);
}
}
XRRFreeOutputInfo (info);
}
XRRFreeScreenResources(screen);
return 0;
}
You can get each screen resolution by doing this:
Display *dpy;
XRRScreenResources *screen;
XRRCrtcInfo *crtc_info;
dpy = XOpenDisplay(":0");
screen = XRRGetScreenResources (dpy, DefaultRootWindow(dpy));
//0 to get the first monitor
crtc_info = XRRGetCrtcInfo (dpy, screen, screen->crtcs[0]);
After that crtc_info->width will contain the width of the monitor and crtc_info->x the x position.
dont forget the includes:
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
and compile with -lX11 -lXrandr to link the libraries
I am not sure, whether I understand the question correctly. Assuming, you want to read out the parameters of the current state of the x-server, use the following command: xrandr -q and parse its output:
LVDS connected 1680x1050+0+0 (normal left inverted right x axis y axis) 123mm x 123mm
[...]
for the first screen and
TV_SVIDEO connected 1024x768+1680x104 (normal left inverted right x axis y axis) 123mm x 123mm
[...]
for the second. Running the command and parsing it can be done within a program written in C.
You can use info->crtc instead of screen->crtcs[icrtc].

Resources