Using method convertTo in opencv java wrapper - java

any body please help me to understand how to use method convertTo in JavaCV. i was trying and searching a lot of time and not find the proper answer. so my problem is, when i try to convert type of mat from gray image to CV_32F and try to display it in android screen it will give me no result. this my source :
Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGBA2GRAY, 1); // dst is gray image
dst.convertTo(dst_f, CvType.CV_32F, 1./255, 0); //convert dst to CV_32F with optional scale
Imgproc.cvtColor(dst_f, src, Imgproc.COLOR_GRAY2RGBA, 4); // to display it in android before convert to bitmap
I was trying also in opencv C++ with this code and it run smoothly :
imshow("dst", image);
cvtColor(image, dst, CV_BGR2GRAY);
dst.convertTo(dst_f, CV_32F, 1.0/255, 0);
imshow("dst_f", dst_f);
UPDATED :
I think i wrong when i try to display image online in android screen. i don't know how to display it altough i knew that android need 4 channel to display image in screen. but when i convert gray to CV_32F image type and i try to display with same code like above and it run smoothly without no result.

After some research and Experiment, i just got my golden answer, here it is :
Android can only display 4 channels image in the screen so you need to convert it to 4 channels (RGBA), but before you convert to RGBA/BGRA you have to change Mat image to CV_8U with same scaled. just look at this example :
Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGBA2GRAY, 1);
dst.convertTo(dst_f, CvType.CV_32F, 1./255, 0);
dst_f.convertTo(final, CvType.CV_8U, 255, 0);
Imgproc.cvtColor(final, src, Imgproc.COLOR_GRAY2RGBA, 4);
With above code, your code will work perfectly in Android screen, but it will give you a broken picture if you try to save it to jpg image or other picture extension. if you want to save it to sdcard you can use this source :
Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGB2GRAY, 1);
dst.convertTo(dst_f, CvType.CV_32F, 1.0/255, 0); // Convert Mat image to CV_32F and scale it to 1.0/255
dst_f.convertTo(final, CvType.CV_32F, 255, 0); //Convert it Back to Default type before
Imgproc.cvtColor(final, roi, Imgproc.COLOR_GRAY2RGB, 0);
Imgproc.cvtColor(roi, roi, Imgproc.COLOR_RGB2RGBA, 0);
above all is my own experiment, if you wanna ask me something, i will answer as good as i can. Thanks. Hope this help others a lot

Related

libGDX: Android doesn't save screenshot

The problem is that when you click, for example, on the display, a screenshot of the screen should be saved, but this does not happen, the image simply is not in the gallery or elsewhere, while if you test for the desktop version, the screen is successfully saved. I am making a drawing for android with saving work, but I do not know how else to save a picture on android.
if (Gdx.input.isTouched())
{
byte[] pixels = ScreenUtils.getFrameBufferPixels(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);
for (int i = 4; i < pixels.length; i += 4)
{
pixels[i - 1] = (byte) 255;
}
Pixmap pixmap = new Pixmap(Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), Pixmap.Format.RGBA8888);
BufferUtils.copy(pixels, 0, pixmap.getPixels(), pixels.length);
PixmapIO.writePNG(Gdx.files.local("mypixmap.png"), pixmap);
local = Gdx.files.getExternalStoragePath().toString();
System.out.println(Gdx.files.getLocalStoragePath());
System.out.println(Gdx.files.getExternalStoragePath());
pixmap.dispose();
}
Gdx.files.local is only for your internal files and can't be accessed by gallery.
You need to use Gdx.files.external, but the current libGDX version uses a path here that is also not accessible under normal circumstances. It is changed for the next version.
Depending on what you want to achieve, there are other ways to get going with platform specific code.
Do you want to save screenshots periodically? Use app-specific storage from 1.9.12
Do you want to share the screenshot to another app? Use local storage and androidx.core.content.FileProvider
Do you want to open a dialog and the user can save the image? Use Storage Access Framework

How can I segment a colored line?

I'm trying to segment the blue and black line of this image.
original image
but I was unable to segment them separately (using the OpenCV library in Java) and it resulted in this:
binarized image
I tried this function:
mgproc.threshold(imgGray, imgThreshold, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);
How can I segment the blue and black lines separately using the OpenCV library?
If the colors of the lines are a given, you can define a color range and filter the image.
Here is a sample code (not mine; taken from this website: https://pythonprogramming.net/color-filter-python-opencv-tutorial/)
lower_red = np.array([30,150,50])
upper_red = np.array([255,255,180])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
Try using adaptiveThreshold, and tune to your needs.
// Adaptive Threshold
Imgproc.adaptiveThreshold(test_image, test_image, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C,
Imgproc.THRESH_BINARY_INV, 15,2);
See more Java examples

displaying a custom map and placing pin/images on the map

i wanted to create a directory app for a grocery. i already have the floor plan of the place. i just wanted to display it in a view and i want to put some markers/pins/images to it.. i have no idea where to start. someone told me to use bitmap and canvass but i have no idea how to use it as the other tutorials in google is quite vague and hard to understand..
what my app requires:
display a custom map from an image source
enable me to put markers,pins and some images on top of it
A simple way is to use use ImageView:
//make a bitmap from your floorPlanImage, example from file
Bitmap floorPlanImage = BitmapFactory.decodeFile(filePath, options);
//make a mutable bitmap, so it can be changed
Bitmap mutableFloorPlanImage = floorPlanImage.copy(Bitmap.Config.ARGB_8888, true);
//create a canvas to draw on your floorPlanImage
Canvas mCanvas = new Canvas(mutableFloorPlanImage);
//draw a marker or another image on the floorPlanImage, you can position it using left and top //coordinates, in this example both 0
mCanvas.drawBitmap(markerBitmap, 0, 0, null);
//show the resulting bitmap in ImageView
imageView.setImageBitmap(mutableFloorPlanImage);

Encoding transparent animated gif in Java

I am using GifDecoder to read an animated .gif file and AnimGifEncoder to write it. (link)
If I display the original frames read by GifDecoder they display correctly and are transparent, but if I display the frames created by AnimatedGifEncoder the transparency is all wrong.
GifDecoder gif = new GifDecoder();
gif.read("image.gif");
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.start("newimage.gif");
e.setTransparent(Color.BLACK);
for (int i=0;i<gif.getFrameCount();i++) {
anim.addFrame(gif.getFrame(i));
anim.setDelay(gif.getDelay(i));
}
anim.finish();
In this example I set the transparent color to black. But actually I want to get the transparent color information from the GifDecoder but I don't know how.
I'm using the following solution, although there are still some gif files that
are a mess after scaling... :
(At least it seems to get along with most non-transparent gifs)
Color transparentColor = null;
BufferedImage firstFrameImage = ImageIO.read([sourceFileHere]);
if (firstFrameImage.getColorModel() instanceof IndexColorModel) {
IndexColorModel cm = (IndexColorModel) firstFrameImage.getColorModel();
int transparentPixel = cm.getTransparentPixel();
transparentColor = new Color(cm.getRGB(transparentPixel), true);
}
e.setTransparent(transparentColor);
This was all a long time ago, but I did manage to get it working at the time. Without digging out the code again... I got it working by:
Scan the original image and set the transparent areas to a colour that does not exist inside the original image.
Set the transparent colour inside the AnimGifEncoder to the colour that was previously assigned to the transparent areas.

Median Filter a bi-level image with JAI

I'd like to apply a Median Filter to a bi-level image and output a bi-level image. The JAI median filter seems to output an RGB image, which I'm having trouble downconverting back to bi-level.
Currently I can't even get the image back into gray color-space, my code looks like this:
BufferedImage src; // contains a bi-level image
ParameterBlock pb = new ParameterBlock();
pb.addSource(src);
pb.add(MedianFilterDescriptor.MEDIAN_MASK_SQUARE);
pb.add(3);
RenderedOp result = JAI.create("MedianFilter", pb);
ParameterBlock pb2 = new ParameterBlock();
pb2.addSource(result);
pb2.add(new double[][]{{0.33, 0.34, 0.33, 0}});
RenderedOp grayResult = JAI.create("BandCombine", pb2);
BufferedImage foo = grayResult.getAsBufferedImage();
This code hangs on the grayResult line and appears not to return. I assume that I'll eventually need to call the "Binarize" operation in JAI.
Edit: Actually, the code appears to be stalling once I call getAsBufferedImage(), but returns nearly instantly when the second operation ("BandCombine") is removed.
Is there a better way to keep the Median Filtering in the source color domain? If not, how do I downconvert back to binary?
Unfortunately it seems like the BandCombine operation doesn't behave as expected here. The appropriate tactic for getting back to bilevel is to use a flavor of ColorConvertOp -- doing so enables use of the MedianFilter operation which will (again, unfortunately) always lead to an RGB image.

Categories