Make an Image In Perspective - java

As the title says I wonder how I can make my images to perspective view. Here's an image showing how they manage to do this in photoshop:
http://netlumination.com/blog/creating-perspective-and-a-mirror-image-in-photoshop
Is it possible to do something like this in android?

Yes.
Have a look at this page http://www.inter-fuser.com/2009/12/android-reflections-with-bitmaps.html.
You can then apply an AffineTransform (at least in AWT, but Android should have something similar, too) using a matrix to distort/skew the image.
Edit: see http://www.jhlabs.com/ip/filters/index.html for an implementation of a PerspectiveFilter.
Note that you could probably also use openGL to achieve a similar effect. See http://developer.android.com/reference/android/opengl/GLU.html and http://developer.android.com/reference/android/opengl/GLSurfaceView.html

This works pretty well for me, for values of rotation between 0 and 60:
Matrix imageMatrix = new Matrix();
float[] srcPoints = {
0, 0,
0, 200,
200, 200,
200, 0};
float[] destPoints = {
rotation, rotation/2f,
rotation, 200 - rotation/2f,
200 - rotation, 200,
200 - rotation, 0};
imageMatrix.setPolyToPoly(srcPoints, 0, destPoints, 0, 4);

Related

Is there a way to not stretch the Bitmap when using Matrix.polyToPoly() on a bitmap?

I'm trying to do perspective transformation on my bitmap with a given quadrilateral. However, the Matrix.polyToPoly function stretches not only the part of the image I want but also the pixels outside the given area, so that a huge image is formed in some edge cases which crashes my app because of OOM.
Is there any way to sort of drop the pixels outside of the said area to not be stretched?
Or are there any other possibilities to do a perspective transform which is more memory friendly?
I`m currenty doing it like this:
// Perspective Transformation
float[] destination = {0, 0,
width, 0,
width, height,
0, height};
Matrix post = new Matrix();
post.setPolyToPoly(boundingBox.toArray(), 0, destination, 0, 4);
Bitmap transformed = Bitmap.createBitmap(temp, 0, 0, cropWidth, cropHeight, post, true);
where cropWidth and cropHeight are the size of the bitmap (I cropped it to the edges of the quadrilateral to save memory) and temp is said cropped bitmap.
Thanks to pskink I got it working, here is a post with the code in it:
Distorting an image to a quadrangle fails in some cases on Android

Convert RGB8888 to YUV420 with ColorMatrix.setRGB2YUV()

I'm trying to find a faster way of converting RGB to YUV using the Android SDK as the standard pixel for pixel methods are pretty slow in Java. ColorMatrices seem to be pretty efficient and I see there's a setRGB2YUV() method but I can't find any examples and the documentation simply says "Set the matrix to convert RGB to YUV" which is completely useless as usual.
Here's part of my initialization code, which is a little compicated slightly with arrays due to multithreading:
cacheBitmaps = new Bitmap[NumberOfThreads];
cacheCanvas = new Canvas[NumberOfThreads];
mRGB2YUV = new ColorMatrix();
cmfRGB2YUV = new ColorMatrixColorFilter(mRGB2YUV);
pRGB2YUV = new Paint();
pRGB2YUV.setColorFilter(cmfRGB2YUV);
for (int m=0; m< NumberOfThreads; m++) {
cacheBitmaps[m] = Bitmap.createBitmap(widthX,heightY, Config.ARGB_8888);
cacheCanvas[m] = new Canvas(cacheBitmaps[m]);
}
Later I use this to paint an RGB to a canvas with the specified paint:
cacheCanvas[n].drawBitmap(fb.frames[n].getAndroidBitmap(),0,0, pRGB2YUV);
I've also experimented using a standard matrix that shouldn't apply any changes to the RGB values like this:
float[] matrix = {
0, 1, 0, 0, 0, //red
0, 0, 1, 0, 0, //green
0, 0, 0, 1, 0, //blue
0, 0, 0, 0, 1 //alpha
};
mRGB2YUV.set(matrix);
Whatever I do I either get black, green or distorted frames in my output video (using JavaCV with FFMPEG and specifying AV_PIX_FMT_NV21 as a color format after copying the final bitmap to an IplImage).
Anyone know how to use this and if it's even possible or does what it says it does?

How can i set fixed shaperenderer rotation in libgdx?

I have a triangle like this;
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.setColor(1, 1, 0, 1);
shapeRenderer.polygon(new float[] { -10, 0, 10, 0, 0, 200 });
shapeRenderer.rotate(0, 0, 1, 1);
shapeRenderer.end();
and I rotate 1 degree in each render. But I want to fix rotation (e.g. 45) to an angle. How can I do this?
Thanks.
To have a fixed rotation you hav to rotate the ShapeRenderer only once.
There are 2 possible ways i can think about:
call shapeRenderer.rotate(0, 0, 1, 45); in the constructor or in create() / show() method
This call rotates your ShapeRenderer by 45° (last parameter) arround the Z-Axis (The 3rd parameter)
call shapeRenderer.rotate(0, 0, 1, 45); in the rendermethod, only if you did not rotate yet. So you have to keep a boolean rotated and only if it is false you call rotate() and set it to true.
To answer the question in your comment: You cannot directly set the rotation, you can only rotate (relative to the current rotation). So i would suggest to store a float rotation, and everytime you rotate your ShapeRenderer you set the new value. To set a rotation in degrees you have to rotate like:
shapeRenderer.rotate(0, 0, 1, newRotation - rotation);
rotation = newRotation;
This works only if you always rotate arround the same axis, in your case the Z-axis. Else you would have to store 3 rotations (x,y,z). If you rotate arround a custom axis, defined by for example (0.1, 0.3, 0.6) you would need to calculate the rotation for all axes. But i don't really know how to do that. I think some Vectormath would do that. But i don't think you need that.

Find circles image processing

I'm using opencv and java to find circles on an image, I have the image below so far.
I'm using Hough to find the circles with the code like this:
Imgproc.medianBlur(result, result, 3);
Imgproc.medianBlur(result, result, 3);
Imgproc.medianBlur(result, result, 3);
Mat circles = new Mat();
Imgproc.HoughCircles(result, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 1, 200, 100, 30, 40);
System.out.println(circles.dump());
But I get an empty Mat for result with and without the blur.
How should I fix this code?
EDIT :
Hi guys!
Thanks to you I have this picture now. I'm using these parameters:
Imgproc.HoughCircles(result, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 20, 50, 10, 10, 40);
I'm still using the medianBlur before the detection.
The only question left is why does it detect these small circles? I've attached the result of the canny detection, I think the circles are pretty seeable .
First of all, the circles structure should not be cv::Mat but should be std::vector<cv::Vec3f>; I think that is why you aren't getting any results.. Please refer to the documentation on the HoughCircles for details..
Playing around with the values for 5 minutes, I have this starting point for you:
The parameters I used are,
cv::medianBlur(test_Circle, test_Circle, 7);
std::vector<cv::Vec3f> circles; // <- not that "circles" is not cv::Mat
cv::HoughCircles(test_Circle, circles, CV_HOUGH_GRADIENT, 1, 1, 300, 10, 10, 50);
You can get much more defined result after you played around with the values a bit.
PS - Since I am a C++ user, please excuse me for putting all my structures in that format. You can easily extend the logic to Java. :)
Are you sure you are providing radius and not diameter? Try wider range of radiuses (10-100 for example).
Using OpenCV to cheat in Zuma? :)
I've tested my code, it writtent in C# (i think java is the same) and get the result:1
You can find my code in HoughAlgorithm.cs class
My demo Project Here
//DP_Resolution: 1
//MinDistance :32
//CannyThreshold: 10
//AccuThreshold: 10
//MinRadius: 13
//MaxRadius: 20
public static CvSeq DetectCircles(IplImage pImage, CamEnum _camName)
{
try
{
CvMemStorage memStorage = cvlib.CvCreateMemStorage(0);
return cvlib.CvHoughCircles(ref pImage, memStorage.ptr, 3, 1, 32, 10, 10, 13, 20);
}
catch
{
throw;
}
}
http://i.stack.imgur.com/pUqbh.png

OpenGL matrix not rotating properly

Alright, so I got this code for gluLookAt:
lookAt = new Vector3f(-player.pos.x, -player.pos.y, -player.pos.z);
lookAt.x += (float)Math.cos(Math.toRadians(player.yaw)) * Math.cos(Math.toRadians(player.pitch));
lookAt.y += (float)Math.sin(Math.toRadians(player.pitch));
lookAt.z += (float) Math.sin(Math.toRadians(player.yaw)) * Math.cos(Math.toRadians(player.pitch));
GLU.gluLookAt(-player.pos.x, -player.pos.y, -player.pos.z,
lookAt.x, lookAt.y, lookAt.z,
0, 1, 0);
And when I try to draw a rotated cube it does not rotate properly.
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glTranslatef(-cube.pos.x, -cube.pos.y, -cube.pos.z);
GL11.glRotatef(cube.yaw, 0, 1, 0);
GL11.glTranslatef(cube.pos.x, cube.pos.y, cube.pos.z);
/*draw the cube normally*/
GL11.glPopMatrix();
So my question is am I handling the alterations to the matrix done by glulookat properly? or am I doing somethign wrong? The result I am looking for is to return the cube to 0,0,0 and rotate it, then put it back where it was.
problem is here:
GL11.glTranslatef(-cube.pos.x, -cube.pos.y, -cube.pos.z);
GL11.glRotatef(cube.yaw, 0, 1, 0);
GL11.glTranslatef(cube.pos.x, cube.pos.y, cube.pos.z);
The cube is already 'at' 0,0,0. This is because the Medel matrix is identity (as you called glLoadIdentity()).
so you should do:
GL11.glRotatef(cube.yaw, 0, 1, 0);
GL11.glTranslatef(cube.pos.x, cube.pos.y, cube.pos.z);
which should have the desired effect. If not, try it with a fixed camera to see if the code you added before glulookat() is causing the lookat target to be too far away from 0,0,0 (where your cube is)
Calling glLoadIdentity before drawing your cube will wipe out whatever gluLookAt has setup in your view matrix, I don't think it should be there.

Categories

Resources