I've created an android application that produces an image as output. This image has pixel errors that are unavoidable. Images are held in an integer array with a size of the image's length*width. The pixels are in ARGB8888 color configuration. I've been searching for a method to both find and approximate what the correct value of the pixel should be based off the surrounding pixels. Here is an example output that needs to be color corrected.
Median filter is your best friend in this situation. This is called salt-and-pepper noise.
That doesn't look (or sound) like what is normally meant by "color correction". Look for a despeckle algorithm.
Gaussian filter might work, or Crimmins Speckle Removal. You'll probably want to understand how Kernel Filters work.
Related
I need the code to add invisible watermark to another image in Android
As the comments mentioned, Stackoverflow isn't a free coding service. I will provide you with a high level design advice from which you can implement your own code.
Invisible watermark could just be metadata. The point is to make your particular photo unique and identifiable, right? I would recommend you looking into image metadata manipulation for a simple solution.
That being said, if you are looking for some high tech stealthy watermarking, then you might be looking for pixel manipulation. You can change a few of the pixel colors so if it's compared with the original image with the naked eye, it looks identical but if compared with their base64 encoding you can see a difference. Simply create your own pattern as some sort of signature to attach to images to identify them.
Both method allows you to determine if an image is yours due to the "watermark" you leave on it.
I'm having trouble cleanly down-scaling images on Android. I'm looking to scale small PNG images between arbitrary sizes of about 10-100% of their original size.
I've created a sample image to demonstrate the problem and exacerbate the unusual behaviors I'm seeing in Android's image scaler:
The above image is a screenshot from an Android device with some annotations added. I've also added the same images in a second column on the left side showing how they are rendered with a linear scaling by "The GIMP" (GNU Image Manipulation Program).
The base image consists of a checkerboard pattern background of red and blue pixels. On that background I've drawn some 1px-wide yellow lines and fairly thin green text. The image is 288x288 pixels.
When scaling the image to 1/3 of its original dimensions, Android seems to simply grab one in nine pixels, throwing out all other data. Some of the yellow lines disappear entirely as a result. Remarkably, the checkerboard pattern remains intact (which is simply a result of every 3rd pixel being used).
When scaling the image to a dimension of near-but-not-exactly 50% of its original size, e.g., 142x142 or 143x143, the scaler creates some fairly large anomalies/artifacts on the image.
At 50% size (144x144), the image looks correct.
The test image does bring out the worst of the image scaler, but "normal" PNG icon images are severely impacted as well. From 10-33% or so the images aren't properly resampled, and thus appear extremely "bitmapped". And certain larger size images have very strange anomalies in them at certain sizes.
If anyone knows a means to disable this strange scaling behavior, even at a performance cost, I'd greatly appreciate knowing about it. It can certainly be solved by writing an algorithm that works directly on the pixels of bitmaps, but I'm hopeful that isn't the only option.
Also noteworthy is the fact that all image work is being done with ARGB_8888 Bitmap.Configs. I've tried manipulating image size by setting maxwidth/maxheight on ImageViews, by using Bitmap.createScaledBitmap(), and by using Bitmap.createBitmap with a Matrix. All attempts have this same result. Bitmap filtering is enabled.
Thanks again for any suggestions!
Using Bitmap.createScaledBitmap() and Bitmap.createBitmap with a Matrix is the same; see the source for Bitmap.createScaledBitmap (which hasn't changed since Android 2).
On Android 4.0+, using a matrix (as in Bitmap.createScaledBitmap) allows hardware-accelerated operations if enabled (enabled by default on 4.1+ IIRC), thus we doesn't have direct control over what is being done and how it is done.
That means you'll have to implement your own scaling method using the desired (here, linear) filtering; either by pixel processing; or using OpenGL ES with the good filter, but it may not be available on all devices.
I've written a camera app which allow users to capture image of paper bills, send to server where it'll be printed.
Problem:
when I print the image, the background is blackish due to noise in captured image. All I want is a clean white background. I've tried Bitmap's compress method to save the image in JPEG/PNG format on different scales (1-100) but not much helpful. I've seen camscanner app doing this fantastically but have no clue how.
Any pointer to achieve this will be helpful.
thanks.
If the issue is some random noise, there are some noise removing filters out there you can use (i.e. median filter or a bilateral filter).
Is the image already binarized (converted to strictly black and white pixels)? You'd want to do the filtering before this.
EDIT(after clarification on dark gray): Since the background is a dark gray I'm guessing the problem is just that it is a low contrast and since it will be a natural image, there will be variation on how bad the contrast is. I suggest using Sauvola binarization for this which will separate out the black and the dark gray to black and white. Here is some detail and example results of Sauvola: http://www.leptonica.com/binarization.html. To run some tests to see which binarization algorithm would be best you can find a library here
Changing compress ratio cannot give any help to this question. A strong filter will help you reduce the noise.
Try to have a look at this Link
In short I am unable to access all the pixels of a bitmap image.
I have used an intent to fire the native Camera app and returned a Bitmap image to my application activity. The data is definitely a bitmap object and I am able to display, get the height/width etc and access some pixels using getPixel(). However when I use the values of getHeight() and getWidth() I get an array out of bounds error. By trail and error I have found I can only access a reduced number of pixels of the image, for example with one image which returned a height and width value of 420,380, I could also access 200,100. I then do some image processing and used setPixel() on the original image. When I display the image it shows the, say 200,100, processing pixels and the rest normal, therefore the pixels are obviously there and accessible by android but not by me. I have to spoken to other people who have also had this problem with images.
Does anyone know anything more about this, reasons? or a work around?
Many thanks in advance.
It seems that there's no way around this, does anyone think it would be better/possible to access the image directly in memory maybe using the NDK?
You won't be able to access the pixel at (getWidth(),getHeight()) in any image because like everything else they are 0-indexed. The valid range of pixels is (0 to getWidth()-1, 0 to getHeight()-1), and thus the bottomrightmost pixel is obtained by b.getPixel(b.getWidth()-1, b.getHeight()-1).
Got an answer from Albert Pucciani on the Android forums. I now create an int buffer and copy the pixels to it, then use get() and put() to extract the pixels. It's also much quicker to use get() and put() instead of the get/setPixel() from the Bitmap class. Need to test now whether this does return all the pixels to the buffer for all images.
After more testing I have discovered this is simply a memory issue as the amount allocated for each process includes all bitmaps.
I'm writing an application for Android.
I need to make some image processing on the picture taken from camera.
I use Camera.PictureCallback to get the photo, and I get picture in byte array.
The problem is I want to make operations on every pixel of photo (some filtering and other stuff) so I guess, have photo in byte array is not a bad idea. But I don't know how interpret information in this byte array... The only way I know to make the processing is use BitmapFactory.decodeByteArray() and then use Bitmap object. Is this a good way to handle a lot of image processing?
Right now I use something look like this:
Bitmap mPhotoPicture mPhotoPicture = BitmapFactory.decodeByteArray(imageData, 0 , imageData.length);
mPhotoPicture = mPhotoPicture.copy(Bitmap.Config.RGB_565, true);
I appreciate any help.
I'm not sure if decoding into a byte array is the best way to do it on Android, but I can offer what I know about image processing in general.
If you're using RGB_565, that means each pixel is 16 bits, or two of those bytes. The first 5 bits are red, the next 6 are green, and the last 5 are blue. Dealing with that is hairy in Java. I suggest you work with an easier format like ARGB_8888, which will mean you have 32 bits, or four bytes per pixel, and each byte is its own value (alpha, red, green, blue).
To test, try setting every fourth byte, like [3], [7], [11], etc., to 0. That should take out all of a particular channel, in this case, all the blue.
[2], [6], [10], etc. would be all the green values for each pixel.
(Note, the four components might go in the opposite order because I'm not sure about endianness! So I might have just told you how to take out the alpha, not the blue…)