Related
I have inserted custom gtk source gutter renderer pixbuf and I want to render icon on a specific line.
The reference API states that the interface is very similar to that on GtkTreeView, but doesn't work with a tree model.
So... how am I supposed to render data to a specific line if the GtkSourceGutter doesn't work with a tree model?
I checked every function in the entire library, every suggested api and child objects and nothing even hints about that.
It just doesn't make sense. The man page says that the GtkSourceGutterRendererPixbuf is used to display icon IN A CELL.
Doing gtk_source_gutter_renderer_pixbuf_set_pixbuf(renderer, pixbuf); will render the icon for all cells in the gutter.
And if the only way is to draw the pixbuf manually using cairo..what's the point in those renderers ?
How do I render pixbuf in a specific line using the gtksourcegutterrenderer?
I haven't worked with GtkSourceView, but I can give you some clues.
How it's done by GtkSourceView's author
First of all, we need some links:
GtkSourceGutterRendererMarks source code
GtkSourceGutterRendererPixbuf source code
GtkSourceGutterRenderer documentation
Let's start with GtkSourceGutterRendererPixbuf. From it's class_init method we find out, that it overrides only draw method. It's only purpose is to render a pixbuf or icon. Pure drawing.
However, GtkSourceGutterRenderer documentation says, that there is a query-data signal which can be used to tune Renderer's internal state. At this point we should take a look at GtkSourceGutterRendererMarks which is inherited from RendererPixbuf. It doesn't override draw, but overrides query_data. (For some reason GtkSourceGutterRendererClass is not described in the documentation. I don't know why.)
/* Read my comments. */
static void
gutter_renderer_query_data (GtkSourceGutterRenderer *renderer,
GtkTextIter *start,
GtkTextIter *end,
GtkSourceGutterRendererState state)
{
GSList *marks;
GdkPixbuf *pixbuf = NULL;
view = GTK_SOURCE_VIEW (gtk_source_gutter_renderer_get_view (renderer));
buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
marks = gtk_source_buffer_get_source_marks_at_iter (buffer,
start,
NULL);
/* If there are marks, we find a pixbuf for one of them.
* Otherwise pixbuf is NULL. */
if (marks != NULL)
{
size = measure_line_height (view);
pixbuf = composite_marks (view, marks, size);
g_slist_free (marks);
}
/* Now tell parent class to render certain pixbuf
* It will render nothing if pixbuf is NULL. */
g_object_set (G_OBJECT (renderer),
"pixbuf", pixbuf,
NULL);
}
My recommendations.
You want to draw marks at certain lines (e.g. want to highlight current debugger line). If I were you, I would have inherited from RendererPixbuf, overriden query_data and use gtk_text_iter_get_line on GtkTextIter *start. Looks like that's the bare minimum.
Feel free to ask any further questions.
I personally cannot simply agree with the allegation that creating custom objects is easy. It isn't easy, not to everyone.
Mainly, because, this question is tagged c and people who don't know Object-Oriented programming might be unfamiliar with its concepts.
It is a matter of reading and practice.
So do not panic if you don't know how to, for instance create your own widget.
The easiest solution I can think of, doesn't involve creating your own renderer, but rather tell the renderer how to query rendering data.
Just connect the query-data signal on your GtkSourceGutterRenderer to a signal handler that looks like this:
G_MODULE_EXPORT void gutter_renderer_query_data (GtkSourceGutterRenderer *renderer, GtkTextIter *start, GtkTextIter *end, GtkSourceGutterRendererState state)
{
GtkSourceView* view = NULL;
GtkSourceBuffer* buffer = NULL;
GSList* marks = NULL;
GdkPixbuf* pixbuf = NULL;
view = GTK_SOURCE_VIEW(gtk_source_gutter_renderer_get_view(renderer));
buffer = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)));
marks = gtk_source_buffer_get_source_marks_at_iter(buffer, start, NULL);
if(marks != NULL)
{
char *category = gtk_source_mark_get_category(marks->data);
if(!g_strcmp0(category, "CERTAIN_CATEGORY")) /* See note 1) */
pixbuf = gtk_image_get_pixbuf(gtk_image_new_from_file("icon_file_here")); /* See note 2) */
g_slist_free(marks);
}
g_object_set(G_OBJECT(renderer), "pixbuf", pixbuf, "yalign", 0.5, NULL);
}
Notes:
GtkSourceMark shares the GtkSourceGutterRenderer interface so you might want to filter your other source marks, by specifying the category of a source mark that is applied to the certain line. Otherwise your custom renderer pixbuf will also be rendered left to your other source marks.
You should specify the exact pixbuf you want to render internally. Doing this, you won't have to call gtk_source_gutter_renderer_pixbuf_set_pixbuf() . You let the API do the resource handling.
I've got a WinForms application that works great on older systems, but I'm having trouble making it look good on 4k monitors. There are multiple issues, and a lot written on the subject, but this question is focused on one specific problem. I can set different controls to use the same font, but on high DPI systems, the controls will look a lot different. How can I fix this?
Obviously I can change the font size, move controls around, etc. But Windows is adding a mysterious factor into my font sizes. Without knowing what Windows is doing, it's hard for me to undo it!
On an older system my test window looks perfect:
On a high DPI system, some controls have a different font size than others:
I've tried several things, including manually setting the font on some controls rather than inheriting from the form. As you can see, changing the font did not fix the problem:
After searching the Internet I've tried several things to fix this including:
Changing the application between PROCESS_DPI_UNAWARE, PROCESS_SYSTEM_DPI_AWARE, and PROCESS_PER_MONITOR_DPI_AWARE
Explicitly changing the font rather than using the form's font.
Building on an old system vs building on a high DPI system.
Building on a monitor set to 96 DPI / 100% vs building on a monitor set to 192 DPI / 200% on the same computer.
Building the form in visual studio's designer vs building it in pure C# code.
.Net 4.0 vs. .Net 4.6.1
Visual Studio 2010 vs Visual Studio 2015
I only found one thing that fixed my problem. Unfortunately I had to do it on the target machine, not on the machine where I'm building this. So it's not a practical solution. See the second item under "steps to repeat" for more details.
Steps to repeat:
This happens with a lot of controls on a lot of forms. See the code sample below for a small, simple demo. That's how I got the screenshots, above.
I can make this problem appear or disappear with one system setting. If you change the main monitor to 96 DPI / 100% scaling, then reboot, you'll get the good result where all fonts are as requested. If you change the main monitor to a different DPI setting, then reboot, you'll see the bad results.
private void newFormButton_Click(object sender, EventArgs e)
{
Font copyOfFont = new Font(Font, FontStyle.Strikeout);
Form form = new Form();
form.Font = Font;
string sample = "Abc 123 :)";
int padding = 6;
Label label = new Label();
label.Text = sample;
label.Top = padding;
label.Left = padding;
label.Font = copyOfFont;
label.Parent = form;
Button button = new Button();
button.Text = sample;
button.Top = label.Bottom + padding;
button.Left = padding;
button.Width = label.Width + padding * 2;
button.Height = label.Height + padding * 2;
button.Parent = form;
TextBox textBox = new TextBox();
textBox.Text = sample;
textBox.Size = button.Size;
textBox.Top = button.Bottom + padding;
textBox.Left = padding;
textBox.Parent = form;
ListBox listBox = new ListBox();
listBox.Items.Add(sample);
listBox.Items.Add(sample);
listBox.Width = button.Width;
listBox.Height = button.Height * 2;
listBox.Top = textBox.Bottom + padding;
listBox.Left = padding;
listBox.Font = copyOfFont;
listBox.Parent = form;
form.Show();
}
This is crazy but it works.
Everything I've seen on the internet about DPI Virtualization says that Windows will automatically set a process to PROCESS_DPI_UNAWARE by default. So unless you explicitly pick one of the other two settings, your application should look decent on a high resolution monitor. It might be a little fuzzy, but it shouldn't look as bad as the examples I've shown above.
Apparently that's not true. The default depends on the computer, and it depends on the day. My solution: Explicitly set the application to use PROCESS_DPI_UNAWARE. I've included a code sample below.
Note that you should be able to take care of this using the manifest. Some sources say that's the preferred way, rather than using C# code. We've had mixed results with that. The C# code option seems more reliable.
[DllImport("shcore.dll")]
static extern int SetProcessDpiAwareness(_Process_DPI_Awareness value);
enum _Process_DPI_Awareness
{
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}
public MainForm()
{
//int result = SetProcessDpiAwareness(_Process_DPI_Awareness.Process_System_DPI_Aware);
//int result = SetProcessDpiAwareness(_Process_DPI_Awareness.Process_Per_Monitor_DPI_Aware);
int result = SetProcessDpiAwareness(_Process_DPI_Awareness.Process_DPI_Unaware);
System.Diagnostics.Debug.Assert(result == 0);
This works on a number of different developer machines. We're about to start sending the fix out to beta testers.
Summary
The O/S provides a compatibility mode for old programs running on high DPI systems.
WinForms and the O/S provide tools for manually changing the sizes of your controls depending on the DPI of the system
or the current monitor.
Both #1 and #2 are both seriously buggy!
The details var a lot from one computer to the next.
Fixing #2 would be the more
powerful option, but as far as I can tell it would be impossible to
fix that.
Instead I fixed #1. That works reasonably well.
I'm having a problem where Octave will render figures just fine in the figure box, but then refuses to properly export to PNG when I use the print() command. This is also true when I try other formats like EPS or JPG.
My current version of Octave is 3.8.1-1ubuntu1, which is up to date at the time of this post. My Ubuntu version is also 14.04. I do not receive any error messages when the code runs.
The script commands used to plot are pretty basic. For example:
linewidth = 4;
xStr = 'Particle Diameter (\mum)';
yStr = 'Scattering Cross-Section (\mum^2)';
FontName = 'Times New Roman';
LabelFontSize = 22;
AxisFontSize = 18;
F1 = figure(1);
clf('reset');
plot(diameter*1e6,sigma_0*1e12,'k','linewidth',linewidth);
hold on
plot(diameter*1e6,sigma_1*1e12,'r','linewidth',linewidth);
X = xlabel(xStr);
set(X,'FontName',FontName,'fontsize',LabelFontSize);
Y = ylabel(yStr);
set(Y,'FontName',FontName,'fontsize',LabelFontSize);
axis([xMin xMax sigMin sigMax]);
set(gca,'fontsize',AxisFontSize,'linewidth',2);
legend('2.0 \mum','3.8 \mum',4);
print(F1,'Mie.png','-dpng');
The strange thing is that I have other images from months ago that rendered the LaTex bits just fine, and even used nearly identical code. That almost seems like some recent software upgrade may have killed my plotting.
I appreciate any help you can give me. This issue is driving me nuts.
This is a known problem when using the OpenGL toolkits (graphics_toolkit FLTK) which is default in octave3.8.x. Previous versions used gnuplot for printing.
So you have two choices:
Switch back to gnuplot with "graphics_toolkit gnuplot" before doing any plotting. You may also add this to your .octaverc so it's set every time you start octave
Use LaTex output: http://wiki.octave.org/Printing_with_FLTK
I am attempting to get the X Window at a certain location on screen. When I asked people for a function to do this, they said you would just call XQueryTree recursively.
This is the code snippet which I think is somehow wrong. When I debug it, it seems to work perfectly. The only problem is that the output it gives seems a little strange. When I do XQueryTree on the root window, I get hundreds of children, when I only have five or so open. Also, it seems to think that there is a top-level window somewhere where there simply isn't one, and returns it as a result. No matter how I move my actual windows around, XQueryTree seems to indicate that there is another window on top of my windows (not covering the entire screen.) When I look at where it says the window is, it is at some arbitrary point on my desktop.
If this is of any help:
The display is from XOpenDisplay(NULL), and the root window I originally pass it is XDefaultRootWindow(display). I am running gnome under debian with metacity.
point getwindowatloc(Display * display, Window root, jint x, jint y) {
Window returnedroot;
Window returnedparent;
Window * children;
unsigned int numchildren;
XQueryTree(display,root,&returnedroot,&returnedparent,&children, &numchildren);
XWindowAttributes w;
int i;
for(i=numchildren-1; i>=0; i--) {
XGetWindowAttributes(display,children[i],&w);
if(x>=w.x && x<=w.x+w.width && y>=w.y && y <= w.y+w.height) {
point result={w.x,w.y};
XFree(children);
return result;
} else {
point result=getwindowatloc(display,children[i],x-w.x,y-w.y);
if(result.x!=INT_MAX) {
result.x+=w.x;
result.y+=w.y;
XFree(children);
return result;
}
}
}
if(children) {
XFree(children);
}
return notfound;
}
Thanks!
EDIT: For anyone who is searching for similar information: I ended up looking into the source of xwininfo. The key function is Find_Client in dsimple.c, which somehow ignores window managers to get the window you are actually looking for. If you want to look into subwindows, this is some code I added to Select_Window in dsimple.c which will recursively look inside subwindows, using XTranslateCoordinates.
Window child;
do {
XTranslateCoordinates(dpy,target_temp,target_win,x,y,&x,&y,&child);
target_temp=target_win;
target_win=child;
} while(target_win);
return target_temp;
I think what you want to do is query the root window's _NET_CLIENT_LIST property. This will produce a list of Window IDs for all client windows, excluding all of the "virtual" windows created by the window manager. Most window managers apparently support _NET_CLIENT_LIST, but you can also query whether or not any given feature is supported.
Your code looks right (I haven't tested it), and the results you describe don't seem strange at all. Metacity (and other X window managers) will create lots of windows around and near the application-owned windows to show the window title, borders and other decorations.
Try running your test with some simpler window manager like TVM (or even none at all). TVM should create a lot less windows than current window managers. This should make things easier to understand.
Usually, however, it's a bad idea to fight against the window manager. Can't you solve your problem in a higher level way withour having to use xlib directly?
In my C/C++ program, I'm using OpenCV to capture images from my webcam. The camera (Logitech QuickCam IM) can capture at resolutions 320x240, 640x480 and 1280x960. But, for some strange reason, OpenCV gives me images of resolution 320x240 only. Calls to change the resolution using cvSetCaptureProperty() with other resolution values just don't work. How do I capture images with the other resolutions possible with my webcam?
I'm using openCV 1.1pre1 under Windows (videoinput library is used by default by this version of openCv under windows).
With these instructions I can set camera resolution. Note that I call the old cvCreateCameraCapture instead of cvCaptureFromCam.
capture = cvCreateCameraCapture(cameraIndex);
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, 640 );
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 );
videoFrame = cvQueryFrame(capture);
I've tested it with Logitech, Trust and Philips webcams
There doesn't seem to be a solution. The resolution can be increased to 640x480 using this hack shared by lifebelt77. Here are the details reproduced:
Add to highgui.h:
#define CV_CAP_PROP_DIALOG_DISPLAY 8
#define CV_CAP_PROP_DIALOG_FORMAT 9
#define CV_CAP_PROP_DIALOG_SOURCE 10
#define CV_CAP_PROP_DIALOG_COMPRESSION 11
#define CV_CAP_PROP_FRAME_WIDTH_HEIGHT 12
Add the function icvSetPropertyCAM_VFW to cvcap.cpp:
static int icvSetPropertyCAM_VFW( CvCaptureCAM_VFW* capture, int property_id, double value )
{
int result = -1;
CAPSTATUS capstat;
CAPTUREPARMS capparam;
BITMAPINFO btmp;
switch( property_id )
{
case CV_CAP_PROP_DIALOG_DISPLAY:
result = capDlgVideoDisplay(capture->capWnd);
//SendMessage(capture->capWnd,WM_CAP_DLG_VIDEODISPLAY,0,0);
break;
case CV_CAP_PROP_DIALOG_FORMAT:
result = capDlgVideoFormat(capture->capWnd);
//SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOFORMAT,0,0);
break;
case CV_CAP_PROP_DIALOG_SOURCE:
result = capDlgVideoSource(capture->capWnd);
//SendMessage(capture->capWnd,WM_CAP_DLG_VIDEOSOURCE,0,0);
break;
case CV_CAP_PROP_DIALOG_COMPRESSION:
result = capDlgVideoCompression(capture->capWnd);
break;
case CV_CAP_PROP_FRAME_WIDTH_HEIGHT:
capGetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
btmp.bmiHeader.biWidth = floor(value/1000);
btmp.bmiHeader.biHeight = value-floor(value/1000)*1000;
btmp.bmiHeader.biSizeImage = btmp.bmiHeader.biHeight *
btmp.bmiHeader.biWidth * btmp.bmiHeader.biPlanes *
btmp.bmiHeader.biBitCount / 8;
capSetVideoFormat(capture->capWnd, &btmp, sizeof(BITMAPINFO));
break;
default:
break;
}
return result;
}
and edit captureCAM_VFW_vtable as following:
static CvCaptureVTable captureCAM_VFW_vtable =
{
6,
(CvCaptureCloseFunc)icvCloseCAM_VFW,
(CvCaptureGrabFrameFunc)icvGrabFrameCAM_VFW,
(CvCaptureRetrieveFrameFunc)icvRetrieveFrameCAM_VFW,
(CvCaptureGetPropertyFunc)icvGetPropertyCAM_VFW,
(CvCaptureSetPropertyFunc)icvSetPropertyCAM_VFW, // was NULL
(CvCaptureGetDescriptionFunc)0
};
Now rebuilt highgui.dll.
I've done image processing in linux before and skipped OpenCV's built in camera functionality because it's (as you've discovered) incomplete.
Depending on your OS you may have more luck going straight to the hardware through normal channels as opposed to through openCV. If you are using Linux, video4linux or video4linux2 should give you relatively trivial access to USB webcams and you can use libavc1394 for firewire. Depending on the device and the quality of the example code you follow, you should be able to get the device running with the parameters you want in an hour or two.
Edited to add: You are on your own if its Windows. I imagine it's not much more difficult but I've never done it.
I strongly suggest using VideoInput lib, it supports any DirectShow device (even multiple devices at the same time) and is more configurable. You'll spend five minutes make it play with OpenCV.
Check this ticket out:
https://code.ros.org/trac/opencv/ticket/376
"The solution is to use the newer libv4l-based wrapper.
install libv4l-dev (this is how it's called in Ubuntu)
rerun cmake, you will see "V4L/V4L2: Using libv4l"
rerun make. now the resolution can be changed. tested with built-in isight on MBP."
This fixed it for me using Ubuntu and might aswell work for you.
Code I finally got working in Python once Aaron Haun pointed out I needed to define the arguments of the set function before using them.
#Camera_Get_Set.py
#By Forrest L. Erickson of VRX Company Inc. 8-31-12.
#Opens the camera and reads and reports the settings.
#Then tries to set for higher resolution.
#Workes with Logitech C525 for resolutions 960 by 720 and 1600 by 896
import cv2.cv as cv
import numpy
CV_CAP_PROP_POS_MSEC = 0
CV_CAP_PROP_POS_FRAMES = 1
CV_CAP_PROP_POS_AVI_RATIO = 2
CV_CAP_PROP_FRAME_WIDTH = 3
CV_CAP_PROP_FRAME_HEIGHT = 4
CV_CAP_PROP_FPS = 5
CV_CAP_PROP_POS_FOURCC = 6
CV_CAP_PROP_POS_FRAME_COUNT = 7
CV_CAP_PROP_BRIGHTNESS = 8
CV_CAP_PROP_CONTRAST = 9
CV_CAP_PROP_SATURATION = 10
CV_CAP_PROP_HUE = 11
CV_CAPTURE_PROPERTIES = tuple({
CV_CAP_PROP_POS_MSEC,
CV_CAP_PROP_POS_FRAMES,
CV_CAP_PROP_POS_AVI_RATIO,
CV_CAP_PROP_FRAME_WIDTH,
CV_CAP_PROP_FRAME_HEIGHT,
CV_CAP_PROP_FPS,
CV_CAP_PROP_POS_FOURCC,
CV_CAP_PROP_POS_FRAME_COUNT,
CV_CAP_PROP_BRIGHTNESS,
CV_CAP_PROP_CONTRAST,
CV_CAP_PROP_SATURATION,
CV_CAP_PROP_HUE})
CV_CAPTURE_PROPERTIES_NAMES = [
"CV_CAP_PROP_POS_MSEC",
"CV_CAP_PROP_POS_FRAMES",
"CV_CAP_PROP_POS_AVI_RATIO",
"CV_CAP_PROP_FRAME_WIDTH",
"CV_CAP_PROP_FRAME_HEIGHT",
"CV_CAP_PROP_FPS",
"CV_CAP_PROP_POS_FOURCC",
"CV_CAP_PROP_POS_FRAME_COUNT",
"CV_CAP_PROP_BRIGHTNESS",
"CV_CAP_PROP_CONTRAST",
"CV_CAP_PROP_SATURATION",
"CV_CAP_PROP_HUE"]
capture = cv.CaptureFromCAM(0)
print ("\nCamera properties before query of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
# camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
# print str(camera_values)
print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)
print ("\nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
img = cv.QueryFrame(capture)
cv.ShowImage("Camera", img)
if cv.WaitKey(10) == 27:
break
cv.DestroyWindow("Camera")
#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1024)
#cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 768)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1600)
cv.SetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 896)
print ("\nCamera properties after query and display of frame.")
for i in range(len(CV_CAPTURE_PROPERTIES_NAMES)):
# camera_valeus =[CV_CAPTURE_PROPERTIES_NAMES, foo]
foo = cv.GetCaptureProperty(capture, CV_CAPTURE_PROPERTIES[i])
camera_values =[CV_CAPTURE_PROPERTIES_NAMES[i], foo]
# print str(camera_values)
print str(CV_CAPTURE_PROPERTIES_NAMES[i]) + ": " + str(foo)
print ("/nOpen a window for display of image")
cv.NamedWindow("Camera", 1)
while True:
img = cv.QueryFrame(capture)
cv.ShowImage("Camera", img)
if cv.WaitKey(10) == 27:
break
cv.DestroyWindow("Camera")
I am using debian and ubuntu, i had the same problem, i couldn't change the resolution of video input using CV_CAP_PROP_FRAME_WIDTH and CV_CAP_PROP_FRAME_HEIGHT
I turned out that the reason was a missing library.
I installed lib4l-dev through synaptic, rebuilt OpenCV and the problem is SOLVED!
I am posting this to ensure that no one else wastes time on this setproperty function. I spent 2 days on this to see that nothing seems to be working. So I dug out the code (I had installed the library the first time around). This is what actually happens - cvSetCaptureProperty, calls setProperty inside CvCapture class and lo behold setProperty does nothing. It just returns false.
Instead I'll pick up using another library to feed OpenCV a capture video/images. I am using OpenCV 2.2
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, WIDTH );
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
cvQueryFrame(capture);
That will not work with OpenCV 2.2, but if you use OpenCV 2.1 it will work fine !
If you are on windows platform, try DirectShow (IAMStreamConfig).
http://msdn.microsoft.com/en-us/library/dd319784%28v=vs.85%29.aspx
Under Windows try to use VideoInput library:
http://robocraft.ru/blog/computervision/420.html
I find that in Windows (from Win98 to WinXP SP3), OpenCV will often use Microsoft's VFW library for camera access. The problem with this is that it is often very slow (say a max of 15 FPS frame capture) and buggy (hence why cvSetCaptureProperty often doesn't work). Luckily, you can usually change the resolution in other software (particularly "AMCAP", which is a demo program that is easily available) and it will effect the resolution that OpenCV will use. For example, you can run AMCAP to set the resolution to 640x480, and then OpenCV will use that by default from that point onwards!
But if you can use a different Windows camera access library such as the "videoInput" library http://muonics.net/school/spring05/videoInput/ that accesses the camera using very efficient DirectShow (part of DirectX). Or if you have a professional quality camera, then often it will come with a custom API that lets you access the camera, and you could use that for fast access with the ability to change resolution and many other things.
Just one information that could be valuable for people having difficulties to change the default capture resolution (640 x 480) ! I experimented myself a such problem with opencv 2.4.x and one Logitech camera ... and found one workaround !
The behaviour I detected is that the default format is setup as initial parameters when camera capture is started (cvCreateCameraCapture), and all request to change height or width :
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, ...
or
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, ...
are not possible afterwards ! Effectively, I discovered with adding return error of ioctl functions that V4l2 driver is returning EBUSY for thet requests !
Therefore, one workaround should be to change the default value directly in highgui/cap_v4l.cpp :
*#define DEFAULT_V4L_WIDTH 1280 // Originally 640*
*#define DEFAULT_V4L_HEIGHT 720 // Originally 480*
After that, I just recompiled opencv ... and arrived to get 1280 x 720 without any problem ! Of course, a better fix should be to stop the acquisition, change the parameters, and restart stream after, but I'm not enough familiar with opencv for doing that !
Hope it will help.
Michel BEGEY
Try this:
capture = cvCreateCameraCapture(-1);
//set resolution
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, frameWidth);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, frameHeight);
cvQueryFrame(capture);
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, any_supported_size );
cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, any_supported_size);
cvQueryFrame(capture);
should be just enough!