Crop a YUV image - android

I have camera preview callback. On onPreviewFrame I will get YUV data. By default my image format is NV21. If I am not wrong data[] is YUV format.
Let I have a preview of 640*480.How can I crop this YUV to get a byte[] containing 480*480 YUV image.
How can I rotate a YUV Image.
If this is difficult to archive how can I crop a IplImage.I am using Javacv to encode a video. Bad luck its greenish.
Is there any other way to archive that?
Thanks in Advance
Amlan.

Assuming you want a left most 480 pixels of a column while cropping, you could loop over the the image height (480 rows) and just copy the first 480 pixels for the Y plane. For the UV plane, just copy the first 480 pixels from the original UV plane (this would consist of 240 U and 240 V values), looped over half of image height (240 rows).
Generate a rotational transformation matrix for the given rotation angle. It will be something like
[cos(theta) -sin(theta)
sin(theta) cos(theta)]
Check wiki for more info on that. Take it's inverse matrix and for every (x, y) pair of the resultant rotated empty image, apply that transformation to get the corresponding (x, y) coordinated in the original image. Use nearest-neighbor or bi-linear interpolation to get the final pixel value.

Related

How can I convert Otaliastudios Frame object into OpenCV Mat object?

I am using com.otaliastudios.cameraview.CameraView component from otaliastudios Library. I need to convert some of the frames to Mat objects to process using OpenCV. How can I convert Otaliastudios Frame object into OpenCV Mat object?
Edit: The frame class I am using is located here: github.com/natario1/CameraView/blob/master/cameraview/src/main/java/com/otaliastudios/cameraview/Frame.java
How can I know which Image format this is? Does it make a difference?
You need to know the source format of your phone camera frame.
The Frame object contains a byte[] data field.This field is probably in the same ImageFormat of your camera. The two most common formats are NV21 and YUV_420_888.
The YUV format is composed by a component that is the luminance Y and another component that is called chrominance (U-V).
Typically the relation (and consequently the real bit/byte size) of these two components is defined by methods that reduce the chrominance component because human eyes are more sensible to luminance variations than color variations (see Chroma Subsampling). The reduction is expressed by a set of numbers like 4:2:0.
In this case the part related to chrominance is half the size of luminance.
So the byte size of a Frame has probably a part for the luminance that is equal to width X height bytes and a part of chrominance that is width X (height/2) bytes. This means that the byte size is heavily dependent on the image format that you are acquiring and you have to modify the mat size and choose the CvType according to this.
You have to allocate a mat that has the same size of your frame and put the data into it(from this answer):
mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2,
getFrameWidth(), CvType.CV_8UC1);
....
mYuv.put(0, 0, data);
And then you have your Mat. If you need also to convert to an RGB format check the bottom of this page.
Hope this will help you.

Calculating position in Bitmap Image

I have floor plan image and draw it into UI with bitmap in scaled example 500 x 500 pixel. The actual image is 700x700 pixel.
With normal size (700px x 700px) floorplan i could draw circle in direct position example (50px , 75px) and it give the corect result in normal size of floorplan.
This circle is for show current location of user.
The question is how to position that circle if the image is scaled into 500x500 pixel with correct position same as (50px ,75px) in (700px x 700px) floorplan ?
Dosn't this come down to a simple math problem?
The coordinates 50,75 in a 700*700 image would correspond to the coordinates 35(,71..), 53(,57..) in a 500*500 image. Fraction can be omitted, since, well, they're pixels.
The scaling factor would be 500/700 which is roughly 0,714. IE
ScalingFactor = NewDimension / OriginalDimension
ScaledPosition = OriginalPosition * ScalingFactor
This is obviously simplified because it is a square image, and scaling is the same among both sides.

How to modify the picture size using OpenCV for Android?

Does anybody know how to modify the picture size using OpenCV for Android ?
It seems that sizes are set to a maximum that I didn't managed to change.
Using the tutorial ImageManipulations which is based on JavaCameraView, here are the maximum resolutions that I can get:
camera Preview Size. Width: 960 Height : 720
camera Picture Size. Width: 640 Height : 480
The problem is that I need a much higher resolution for the picture (I don't care about the preview size).
Maybe there's an answer in the opencv forum but I can't access to this answer since it seems there are works over there (OpenCVForum)
You can resize a Mat as follows:
Size szSource = new Size(640,480);
Size szResized = new Size(2592,1944);
Mat mSource= new Mat(szSource, CvType.CV_8U);// Read or Fill Something in your mSource
Mat mResised = new Mat();
Imgproc.resize( mSource, mResised, szResized,0,0,INTER_NEAREST);//mSource-> Your Source image
interpolation – interpolation method can be any of the above
INTER_NEAREST - a nearest-neighbor interpolation
INTER_LINEAR - a bilinear interpolation (used by default)
INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood
For further reference please see this.

Gradiant and angle visualisation of an image with HOGDescriptor (OpenCV for Android)

I try to visualize the gradiants and angles of an image which computed by the HOGDescriptor of the OpenCV Lib for Android. At the begin i have an 3 channel image Mat() with 8 bit unsigned int (CV_8UC3). The result of the computation is a MAT() (CV_32FC2) of the gradiants and a Mat() (CV_8UC2) of the angles. How can i visualize this results? What represent the values? Why have the angle Mat() 2 channels? Are the 2 channels of the gradiant Mat() the x and y component of the gradiant? I cant find documentation of the computeGradiant-Method.
HOG descriptor is an histogram of oriented gradient: it is an histogram where each bin reprezent the vote for gradient in corresponding orientation.
In order to compute this descriptor, you should first convert you 3 channels color image into a grayscale image
cv::cvtColor(CV_BGR2GRAY);
The result of "ComputeGradient" method is for exemple two images (same size as the original): x-component and y-component.
You should then be able to compute for each pixel the gradient magnitude and orientation.
mag=sqrt(x*x+y*y)
alpha=atan(y/x)
Then you can fill you histogram. Note that HOG descritpor is computed by blocks and cells. See this for more detail.

how to use background image for texture in openGL

i want to use background image with texture but texture get images with power of 2 so i made image size (800x480 to 512x512).
but now it is showing image with some blank space.
how can i show image on entire screen. and also want to horizontally scrollable .
Well, if this is on Android, that means you don't have glDrawPixels, so the only way you could be "showing" an image would be to render a textured quad. So just make the quad whatever size you need.
You can also draw multiple textures, just by drawing one texture to one location, then drawing another texture to another location.
You need to use the right texture coordinates when rendering your background. You need to compute the texture coordinates so that you are having an offset for the axis perpendicular to the black borders.
I guess you resized your 800x480 image so that it fits in 512x512 pixels, making you end up with the actual background image (inside the 512x512 texture) being 512x307?
This would mean that your u texture coordinate offset would need to be (512.0 - 307.0) / 2.0 / 512.0 ~ 0.2, so your texture coordinates would need to be (0.0,0.0), (0.0,0.2), (1.0,0.2), (1.0,0.0).

Categories

Resources