Rotate image according to the mouse - c

I'm trying to rotate an image according to the mouse. The idea is a spaceship game. The tip of the spaceship follows the mouse cursor, depending on the cursor position the spacecraft rotates an angle.
The Allegro rotation function I am using:
al_draw_rotated_bitmap(OBJECT_TO_ROTATE,CENTER_X,CENTER_Y,X,Y,DEGREES_TO_ROTATE_IN_RADIANS);
This is the x and y position of the spaceship:
spaceship.x
spaceship.y
And the x and y position of the mouse cursor:
game_event.mouse.x
game_event.mouse.y
When the right angle to the rotation according to the mouse is identified just send the angle for the "DrawSpaceship" function. This function draws the spaceship in the main loop.
Obs: I'm using C and Allegro5

atan ((spaceship.y - game_event.mouse.y) / (spaceship.x - game_event.mouse.x));
With of course a test to avoid to / 0
You will need
#include <math.h>

double mouseangle = direction(xscreen - 45, yscreen, xmouse, ymouse);
animpos = (mouseangle/180.0)*(nframes-1);
This is more "from scratch" code with a better control and certainly a better practice and could be library independent. You can always adjust the literals.
nframes is the number of frames in the image
direction is a function that returns the direction between x1 x2 y1 y2 in angles
animpos is the animation frame you wish to show
xscreen x position of image, screen-related (yscreen is analogous)
xmouse mouse's horizontal position, screen-related (xmouse is analogous)

Related

openGL(c) draw square

i need to draw a square using c (openGL),
i only have 1 coordinate which is the center of the square (lets say 0.5,0.5) and i need to draw a square ABCD with each side 0.2 length (AB,BC,CD,DA),
I tried using the next function but it does not draw anything for some reson,
void drawSquare(double x1,double y1,double radius)
{
glColor3d(0,0,0);
glBegin(GL_POLYGON);
double locationX = x1;
double locationY = x2;
double r = radius;
for(double i=0; i <= 360 ; i+=0.1)
{
glVertex2d(locationX + radius*i, locationY + radius*i);
}
glEnd();
}
can someone please tell me why its not working\point me to the right direction (i do not want to draw polygon with 4 coordinated normally, but with only 1 coordinate with a givven radius,
thanks!
Your code will not even draw a circle. If anything, it will draw a diagonal line extending out of the view area very quickly. A circle plot would need to use sine and cosine, based on the radius and angle.
I have not tried this code, but it needs to be more like this to draw a square.
void drawSquare(double x1, double y1, double sidelength)
{
double halfside = sidelength / 2;
glColor3d(0,0,0);
glBegin(GL_POLYGON);
glVertex2d(x1 + halfside, y1 + halfside);
glVertex2d(x1 + halfside, y1 - halfside);
glVertex2d(x1 - halfside, y1 - halfside);
glVertex2d(x1 - halfside, y1 + halfside);
glEnd();
}
There are no normals defined: perhaps I should have travelled counter-clockwise.
Simple way to draw a square is to use GL_QUADS and the four vertices for the four corners of the square. Sample code is below-
glBegin(GL_QUADS);
glVertex2f(-1.0f, 1.0f); // top left
glVertex2f(1.0f, 1.0f); // top right
glVertex2f(1.0f, -1.0f); // bottom right
glVertex2f(-1.0f, -1.0f); // bottom left
glEnd();
Since in the case you have to draw square from the mid point which is interaction of two diagonals of square. You use the following facts and draw the same.
length of diagonal = x*square root of 2 (x=side of square)
diagonals of a square are perpendicular
diagonals of a square are the same length
If your point is at 0.5,0.5 which coordinate of interaction point, and side is 0.2. So you can easily determine the point coordinate of four corners as in the figure given below and code it accordingly.

OpenGL - circle not being drawn smooth

I am drawing a circle using OpenGL, with the set of calls being:
float delta_theta = 0.001;
glBegin(GL_POLYGON); // OR GL_LINE_LOOP
glEnable( GL_LINE_SMOOTH );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (angle = 0; angle < 2*3.1415; angle += delta_theta)
glVertex3f( radius*cos(angle), radius*sin(angle), 0 );
glEnd();
The problem is that the circle is not smooth. I am moving (translating) the circle along axes; at some points it becomes smooth, but mostly, it's like a blot, please see the attached screenshot.
Any suggestions as to what I could do to smoothen the circle?
I would suggest you not try to implement this with lines or a filled polygon for one thing.
Use a single GL_POINT and enable GL_POINT_SMOOTH. That will rasterize the point as a filled circle instead of the normal square. It will be much more efficient, provided you use a point size your implementation supports for anti-aliased points (often up to ~ 63.5 on NV implementations, more on others).

Standard deviation of pixel values in a masked image

I have a DICOM image with a mask on. It looks like a black background with a white circle in the middle (area not covered and zeroed with the mask).
The code for which is:
import numpy as np
import dicom
import pylab
ds = dicom.read_file("C:\Users\uccadmin\Desktop\James_Phantom_CT_Dec_16th\James Phantom CT Dec 16th\Images\SEQ4Recon_3_34\IM-0268-0001.dcm")
lx, ly = ds.pixel_array.shape
X, Y = np.ogrid[0:lx, 0:ly]
mask = (X - lx/2)**2 + (Y - ly/2)**2 > lx*ly/8 # defining mask
ds.pixel_array[mask] = 0
print np.std(ds.pixel_array) # trying to get standard deviation
pylab.imshow(ds.pixel_array, cmap=pylab.cm.bone) # shows image with mask
I want to get the standard deviation of the pixel values INSIDE the white circle ONLY i.e. exclude the black space outside the circle (the mask).
I do not think the value I am getting with the above code is correct, as it is ~500, and the white circle is almost homogenous.
Any ideas how to make sure that I get the standard deviation of the pixel values within the white circle ONLY in a Pythonic way?
I think the reason you are getting a big number is because your standard deviation is including all the zero values.
Is it enough for you to simply ignore all zero values? (This will be okay, providing that no or very few pixels in the circle have value 0.) If so
np.std([x for x in ds.pixel_array if x > 0])
should do the trick. If this isn't good enough, then you can reverse the condition in your mask to be
mask = (X - lx/2)**2 + (Y - ly/2)**2 < lx*ly/8 # defining mask, < instead of >
and do
mp.std(ds.pixel_array[mask])

What is the OpenCV FindChessboardCorners convention?

I'm using OpenCV 2.2.
If I use cvFindChessboardCorners to find the corners of a chessboard, in what order are the corners stored in the variable corners (e.g. top-left corner first, then row then column)?
Documentation (which didn't helped much).
It seems to me the doc is lacking this kind of details.
For 3.2.0-dev it seems to me it depends on the angle of rotation of the chessboard.
With this snippet:
cv::Size patternsize(4,3); //number of centers
cv::Mat cal = cv::imread(cal_name);
std::vector<cv::Point2f> centers; //this will be filled by the detected centers
bool found = cv::findChessboardCorners( cal, patternsize, centers, cv::CALIB_CB_ADAPTIVE_THRESH );
std::cout << found << "\n";
if(found){
cv::drawChessboardCorners(cal,patternsize,centers,found);
You will get these results:
First image:
First image rotated by 180 degrees:
Note the
colored corners connected with lines
drawn by drawChessboardCorners, they differ only by the color: in the original image the red line is at the bottom, in the rotated image the red line is at the top of the image.
If you pass to drawChessboardCorners a grayscale image you will loose this piece of information.
If I need the first corner at the top left of the image and if I can assume that:
the angle of the chessboard in the scene will be only close to 0 or close to 180;
the tilt of the camera will be negligible;
then the following snippet will reorder the corners if needed:
cv::Size patternsize(4,3); //number of centers
cv::Mat cal = cv::imread(cal_name);
std::vector<cv::Point2f> centers; //this will be filled by the detected centers
bool found = cv::findChessboardCorners( cal, patternsize, centers, cv::CALIB_CB_ADAPTIVE_THRESH );
std::cout << found << "\n";
if(found){
cv::drawChessboardCorners(cal,patternsize,centers,found);
// I need the first corner at top-left
if(centers.front().y > centers.back().y){
std::cout << "Reverse order\n";
std::reverse(centers.begin(),centers.end());
}
for(size_t r=0;r<patternsize.height;r++){
for(size_t c=0;c<patternsize.width;c++){
std::ostringstream oss;
oss << "("<<r<<","<<c<<")";
cv::putText(cal, oss.str(), centers[r*patternsize.width+c], cv::FONT_HERSHEY_PLAIN, 3, CV_RGB(0, 255, 0), 3);
}
}
}
I am pretty sure it orders the chessboard corners by rows, starting with the one closest to the top-left corner of the image.
The chessboard pattern has no specified origin (one of the deficiencies of that calibration device), so if you turn it 90 or 180 degrees the corners you get back won't be in the same order.
The way to make sure is to look at the actual point values you get back and see if they are what you expected.
Edit: at least in case of OpenCV 3.3.1 and 5x3 chessboard, the chessboard corners can be returned either starting top-left or bottom-right, depending on the rotation.

rotating one object according to point

O
position 2
O Y
object ( x,y,z )
position 1
I want rotate object according to fix point (x,y,z) with Q angle. With opengl, how can I do that ?
Object goes from position 1 to position 2 .
I know Q, (x,y,z).
I have done :
glPushMAtrix ()
glTranslatef ( -x, -y, -z ) ;
glRotatef ( Q, 1.0f, 0.0f, 0.0f );
glCylinder ( /*argument*/ )
glPopMatriX ()
If you are rotating in 3D space and know only object, angle and the center of rotation, then your task is undefined. In 3D space you can rotate only around some axis, not point.
From your code example you are rotating around X axis. Let me guess that's what you really want.
To achieve this you should translte orign of coordinate system to the center of rotation, perform rotation and translate coordinate system back.
glTranslatef(-x, -y, -z);
glRotatef(Q, 1.0, 0.0, 0.0);
glTranslatef(x, y, z);
// draw the object
If you know the initial and final position of your object, then you can calculate the axis of rotation. (Since 3 points always define a plane and its normal.) In vector notation it should look this way (May be wrong in axis direction. If object rotates on opposite direction change the sign of axis or angle).
axis = vec(center_of_rotation - initial_position, center_of_rotation - final_position)
Or a little bit more "for dummies"
float X1[3]; // initial position
float X2[3]; // final position
float O[3]; // orign of rotation
float OX1[3]; OX1[0] = X1[0] - O[0]; OX1[1] = X1[1] - O[1]; OX1[2] = X1[2] - O[2];
float OX2[3]; OX2[0] = X2[0] - O[0]; OX2[1] = X2[1] - O[1]; OX2[2] = X2[2] - O[2];
float axis[3]; // vector product OX1 and OX2
axis[0] = OX1[1]*OX2[2]-OX1[2]*OX2[1];
axis[1] = OX1[2]*OX2[0]-OX1[0]*OX2[2];
axis[2] = OX1[0]*OX2[1]-OX1[1]*OX2[0];

Resources