Mouse Movement in OpenCV - c

i am trying to move mouse cursor using finger coordinate in opencv. i am not able to scale it to entire screen size which 1366*768. my webcam resolution is 640*480. my mouse pointer moves only to half of the screen. i do not know why.
this is the function call:
Mouse_Move(((1366*mouse_pointer.x)/640),((768*mouse_pointer.y)/480));
and this is the implementation:
void Mouse_Move(DWORD dx,DWORD dy)
{
DWORD event=0;
event = MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE;
mouse_event(event, dx*65535/Get_ScreenWidth(), dy*65535/Get_ScreenHight(), 0, 0);
}
this is my code segment.
mouse_pointer.x and mouse_pointer.y are the coordinate of my fore-finger.

Related

Get texture coordinates of mouse position in SDL2?

I have the strict requirement to have a texture with resolution (let's say) of 512x512, always (even if the window is bigger, and SDL basically scales the texture for me, on rendering). This is because it's an emulator of a classic old computer assuming a fixed texture, I can't rewrite the code to adopt multiple texture sizes and/or texture ratios dynamically.
I use SDL_RenderSetLogicalSize() for the purpose I've described above.
Surely, when this is rendered into a window, I can get the mouse coordinates (window relative), and I can "scale" back to the texture position with getting the real window size (since the window can be resized).
However, there is a big problem here. As soon as window width:height ratio is not the same as the texture's ratio (for example in full screen mode, since the ratio of modern displays would not match of the ratio I want to use), there are "black bars" at the sides or top/bottom. Which is nice, since I want always the same texture ratio, fixed, and SDL does it for me, etc. However I cannot find a way to ask SDL where is my texture rendered exactly inside the window based on the fixed ratio I forced. Since I need the position within the texture only, and the exact texture origin is placed by SDL itself, not by me.
Surely, I can write some code to figure out how those "black bars" would change the origin of the texture, but I can hope there is a more simple and elegant way to "ask" SDL about this, since surely it has the code to position my texture somewhere, so I can re-use that information.
My very ugly (can be optimized, and floating point math can be avoided I think, but as the first try ...) solution:
static void get_mouse_texture_coords ( int x, int y )
{
int win_x_size, win_y_size;
SDL_GetWindowSize(sdl_win, &win_x_size, &win_y_size);
// I don't know if there is more sane way for this ...
// But we must figure out where is the texture within the window,
// which can be changed since the fixed ratio versus the window ratio (especially in full screen mode)
double aspect_tex = (double)SCREEN_W / (double)SCREEN_H;
double aspect_win = (double)win_x_size / (double)win_y_size;
if (aspect_win >= aspect_tex) {
// side ratio correction bars must be taken account
double zoom_factor = (double)win_y_size / (double)SCREEN_H;
int bar_size = win_x_size - (int)((double)SCREEN_W * zoom_factor);
mouse_x = (x - bar_size / 2) / zoom_factor;
mouse_y = y / zoom_factor;
} else {
// top-bottom ratio correction bars must be taken account
double zoom_factor = (double)win_x_size / (double)SCREEN_W;
int bar_size = win_y_size - (int)((double)SCREEN_H * zoom_factor);
mouse_x = x / zoom_factor;
mouse_y = (y - bar_size / 2) / zoom_factor;
}
}
Where SCREEN_W and SCREEN_H are the dimensions of the my texture, quite misleading by names, but anyway. Input parameters x and y are the window-relative mouse position (reported by SDL). mouse_x and mouse_y are the result, the texture based coordinates. This seems to work nicely. However, is there any sane solution or a better one?
The code which calls the function above is in my event handler loop (which I call regularly, of course), something like this:
void handle_sdl_events ( void ) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION:
get_mouse_texture_coords(event.motion.x, event.motion.y);
break;
[...]

OpenCV in C - drawing a circle that should appear only in upper half of the image?

I have to draw a circle for several images. For each image to the radius of curvature is different with a constant center.
The problem is : no matter how big the circle is it shouldn't cross to upper half of the image. It's OK if it becomes invisible or only a part of it is visible in the lower half.
I am using OpenCV 2.4.4 in C lang.
The values for the circle is found by:
for(angle1 = 0; angle1<360; angle1++)
{
x [angle1]= r * sin(angle1) + axis_x;
y [angle1]= r * cos(angle1) + axis_y;
}
FYI:
cvCircle( img,center_circle, r,cvScalar( 0, 0, 255,0 ),2,8,0);
Draws circle in the entire image. Which I don't want to happen.
How can I do it? Rem: no part of the circle should appear in upper half of the image.
And the code should be in OpenCV's C lang.
In MALTAB is pretty easy. I only have to select the pixels and map them on the image.
I am new to OpenCV and operations like img->data.i/f/s/db[50] =50; is showing error.
A pretty naive approach is to create a copy of the upper half of image, draw the complete circle, and then copy back the upper half to original image. This may not be the best approach but it works. Here is how it can be achieved:
void drawCircleLowerHalf(IplImage* image, CvPoint center, int radius, CvScalar color, int thickness, int line_type, int shift)
{
CvRect roi = cvRect(0,0,image->width, image->height/2);
IplImage* upperHalf = cvCreateImage(cvSize(image->width, image->height/2), image->depth, image->nChannels);
cvSetImageROI(image, roi);
cvCopy(image,upperHalf);
cvResetImageROI(image);
cvCircle(image, center, radius, color, thickness, line_type, shift);
cvSetImageROI(image, roi);
cvCopy(upperHalf, image);
cvResetImageROI(image);
cvReleaseImage(&upperHalf);
}
Just call this function with the same arguments as of cvCircle.

Opengl shapes not drawing in callback function

In my opengl program, I want to make the screen turn red when a user hits a certain key. In my my_keyboard function, I have the following:
void my_keyboard( unsigned char key, int x, int y ) {
int feedback_code=0;
if (key == 49) {
feedback_code=1;
}
if (feedback_code==1) {
flash_screen();
}
My flash_screen method is as follows:
void screen_flash() {
float mat[16];
glGetFloatv(GL_MODELVIEW_MATRIX,mat);
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_POLYGON);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.0f, 640.0f);
glVertex2f(888.0f, 640.f);
glVertex2f(888.0f, 0.0f);
glEnd();
}
By the glGetFloatv call, I know that my transformation matrix is back at the lower left corner where it should be, at point (0,0). So the draw function should draw a red square 888x640px, the size of my window. When I run the program and hit the '1' key, however, I don't get a shape! I've used breakpoints and determined that the GlBegin-GlEnd statements DO run, they just don't seem to produce anything.
The only other shapes I have are done in my main display function, called before the main_loop starts.
What am I doing wrong?
It's a common newbie mistake. So here's the general rule: Never make OpenGL drawing calls from event handlers. Never!
When you want something on the screen happen in reaction to a input event, set some flag variables, and signal a redraw. Then in the drawing function draw according to the signal.

SDL - Move cursor with rect x and y smaller than zero

I implemented a custom cursor on my SDL game. When moving it across the screen I can go as far as I want to the right and to the bottom. But the cursor will not go beyond the ledt or the top wall. I'm using SDL_GetMouseState and passing the current x and y values to it.
How do I manage to allow a surface to move to the position (-5, 0)?
Here's some code:
typedef struct {
SDL_Surface *image;
SDL_Rect frame;
} Cursor;
void moveCursor(Cursor *cursor) {
Sint16 *x = &cursor->frame.x;
Sint16 *y = &cursor->frame.y;
Uint16 cursorWidth = cursor->frame.w;
Uint16 cursorHeight = cursor->frame.h;
SDL_GetMouseState((int *)x, (int *)y);
cursor->frame.w = cursorWidth;
cursor->frame.h = cursorHeight;
SDL_Rect temporaryFrame = cursor->frame;
SDL_BlitSurface(cursor->image, NULL, bufferSurface.surface, &temporaryFrame);
}
SDL doesn't detect mouse movements outside its window, so you cannot have negative mouse coordinates.
To simulate a mouse that can move offscreen, always keep the mouse centered and store it's relative motion. The relative motion is translated to your virtual mouse that can now move anywhere and is represented by a sprite.

Draw rectangle over optical flow feature points

I want to draw a rectangle over feature points get from optical flow process.
I'm using cvSeqPush method to draw it:
CvSeq* trackCarContour = cvCreateSeq(CV_32FC2, sizeof(CvSeq), sizeof(CvPoint2D32f), contour_storage );
for(int i=0;i<numberOfFeaturesFound;i++)
{
cvSeqPush( trackCarContour, &cur_feature[i] );
}
CvRect trackCarRect = cvBoundingRect(trackCarContour, 0);
However, the rectangle drawn is not bound over those points, instead it shows on the top left corner of the image.
Is there any other way to do this? Or, what's wrong with my way of doing this?

Resources