How can I read every pixel of a WritableImage with Raster? - java

I have to write a method that:
Create a histogram
read all pixel values from grayscale images (variable width and height)
fill the histogram
How can I do it? I wrote a bit of code but I'm deadlocked.
public histogram(BufferedImage image){
WritableRaster writableRaster = image.getRaster();
int width = image.getWidth();
int height = image.getHeight();
int pixelValue;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixelValue = writableRaster.setDataElements(x, y, width, height, );
}
}
}

The following code snippet should help:
Raster raster = image.getRaster();
int numBands = raster.getSampleModel().getNumBands();
int width = image.getWidth();
int height = image.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int[] pixelValue = new int[numBands];
raster.getPixel(x, y, pixelValue);
}
}
If you really have a grayscale image without alpha, the SampleModel will contain only one band. In this case the pixelValue array will contain your desired int value. You only have to add an histogram array of 256 int values and increase the value at the index of your pixel value.

Related

android RGB565 format bitmap

I am trying to display an image on Anki Vector robot.
My Android app draws the bitmap from a canvas and then uses "createBitmap" method to convert it to the RGB_565 format. Because the display is specified as RGB565 here:
https://vector.ikkez.de/generated/anki_vector.screen.html#module-anki_vector.screen
createBitmap(width, height, Bitmap.Config.RGB_565);
Result seems successful but color channels are not correct.
RGB was ordered like BRG.
As a workaround I swapped channels accordingly.
But now orange and yellow colors seems to be swapped.
When I draw orange , display shows yellow. When I draw yellow, it shows orange.
What may be the problem ?
FOr swapping channels I used following code:
public Bitmap swapC(Bitmap srcBmp) {
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
float srcHSV[] = new float[3];
float dstHSV[] = new float[3];
Bitmap dstBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int pixel = srcBmp.getPixel(col, row);
int alpha = Color.alpha(pixel);
int redC = Color.red(pixel);
int greenC = Color.green(pixel);
int blueC = Color.blue(pixel);
dstBitmap.setPixel(col, row, Color.argb(alpha,blueC,redC,greenC));
}
}
return dstBitmap;
}
I have used a workaround as a solution; dividing color channel values by 8 :
public Bitmap swapC(Bitmap srcBmp) {
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
float srcHSV[] = new float[3];
float dstHSV[] = new float[3];
Bitmap dstBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int pixel = srcBmp.getPixel(col, row);
int alpha = Color.alpha(pixel);
int redC = Color.red(pixel);
int greenC = Color.green(pixel);
int blueC = Color.blue(pixel);
dstBitmap.setPixel(col, row, Color.argb(alpha,blueC/8,redC/8,greenC/8));
}
}
return dstBitmap;
}

Tensorflow in Android: java.lang.illegalArgumentsException

I want to put a tensorflow model on Anroid.
I recently noticed that the results of running the same data in Python and Android, respectively, are inconsistent.
After several trial and error, I found that the input data I entered when I ran the model on Android was wrong.
It was just a java.lang.IllegalArgumentException error, and I think I put the data correctly, but I have no idea what went wrong.
I used images that were transformed into image resizing and gray scale as learning data. in Python
I did the same preprocessing on Android.
My image type is .jpg
I attached my source.
Source related to image preprocessing
btntrans.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
image_bitmap = resizeBitmapImage(image_bitmap, 28);
image_bitmap = RGB2GRAY(image_bitmap);
image.setImageBitmap(image_bitmap);
byte[] byteArrayRes = bitmapToByteArray(image_bitmap);
float[] inputArray = bytetofloat(byteArrayRes);
activityPrediction(inputArray);
}
catch(Exception e){
}
}
});
Everything happens when I click the button
resizeBitmapImage method
public Bitmap resizeBitmapImage(Bitmap source, int maxResolution)
{
int width = source.getWidth();
int height = source.getHeight();
int newWidth = width;
int newHeight = height;
float rate = 0.0f;
if(width > height)
{
if(maxResolution < width)
{
rate = maxResolution / (float) width;
newHeight = (int) (height * rate);
newWidth = maxResolution;
}
}
else
{
if(maxResolution < height)
{
rate = maxResolution / (float) height;
newWidth = (int) (width * rate);
newHeight = maxResolution;
}
}
return Bitmap.createScaledBitmap(source, newWidth, newHeight, true);
}
RGB2GRAY method
public Bitmap RGB2GRAY(Bitmap image){
int width = image.getWidth();
int height = image.getHeight();
Bitmap bmOut;
bmOut = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
for(int x = 0; x < width; x++){
for(int y = 0 ; y < height; y++){
int pixel = image.getPixel(x, y);
int A = Color.alpha(pixel);
int R = Color.red(pixel);
int G = Color.green(pixel);
int B = Color.blue(pixel);
R = G = B = (int)(0.299 * R + 0.587 * G + 0.114 * B);
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
bitmap to byte array method
private byte[] bitmapToByteArray(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}
bytetofloat method
public float[] bytetofloat(byte[] array){
int[] returnArr = new int[array.length/4];
float[] returnArr1 = new float[array.length/4];
for(int i = 0 ; i < returnArr.length; i++){
//array[i] = 0;
returnArr[i] = array[i*4] & 0xFF;
if(returnArr[i] < 0 || returnArr[i]>255)
Log.d("ARRAY", returnArr[i]+" ");
returnArr1[i] = (float)returnArr[i];
}
return returnArr1;
}
When I run it with the above source, I get this error exactly.
java.lang.IllegalArgumentException: buffer with 308 elements is not
compatible with a Tensor with shape [1, 28, 28]
28 * 28 is Input image size
Before image resizing, it had an average width of 20 and a height of 36.
The strange thing is that the number 308 is changed to 306, 307 and fixed.
What can i do?
Here is my method for converting Java BufferedImage to Tensor object:
private static Tensor<?> convertImageToArray(BufferedImage bf) {
int width = bf.getWidth();
int height = bf.getHeight();
float[][][][] rgbArray = new float[1][height][width][3];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
bf.getRaster().getPixel(i, j, rgbArray[0][i][j]);
}
}
return Tensor.create(rgbArray);
}
Your problem is probably in missed channels of your image. Float array length must be equal to
height * width * channels
of the image.

Index pixels to color certain location of pictures

I'm creating a method that takes two parameters with 2 indexes a start and an end that takes a location of the picture being edited and turn those pixels to a different color. Using a while loop to index start and end.
The problem I'm having is I'm only a getting a really small portion to change color:
Don't mind some of the code that is commented out. I was trying a bunch of different things.
public void negative(int start, int end)
{
Pixel[] pixelArray = this.getPixels(); //pixelarray index
Pixel pixel = null;
// int height = this.getHeight();
//int paintPoint = height / 2;
//int width = this.getWidth();
int i = 0;
int red, green, blue = 0;
// int x = 0;
Pixel topPixel = null;
Pixel bottomPixel = null;
//int startY;
//int startX;
int y = start;
int x = end;
//int count;
while( y < this.getHeight())
{
y++;
while (x < this.getWidth()) //loops through index
{
pixel = this.getPixel(x,y);
red = pixel.getRed();
green = pixel.getGreen();//collects color green
blue = pixel.getBlue();//collects color blue
Color negColor = new Color( 255 - red, 255 - green, 255 - blue);//sets new values of pixels
pixel.setColor(negColor);
x++;
//count = count + 1;
i++;//indexes continuing
}
}
}
A picture is 2D yet you are treating it as 1D (notice after once through your inner x loop it never is reset to its min value). If you wish to color an arbitrary rectangle within a given photo the parms should include two points : minx, miny and maxx maxy then your pair of 2D loops visits each point in that region line by line.
// do sanity checks on your parms
if (this.getWidth() < maxx) {
maxx = this.getWidth();
}
if (this.getHeight() < maxy) {
maxy = this.getHeight();
}
if (minx < 0) {
minx = 0;
}
if (miny < 0) {
miny = 0;
}
for (y = mixy; y < maxy; y++) {
for (x = mixx; x < maxx; x++) {
// now your have valid x and y values
}
}

How to get average RGB value of Bitmap on Android?

I know how to get the RGB values of individual pixels of a bitmap. How can I get the average RGB value for all of the pixels of a bitmap?
I think below code for exact answer to you.
Get the Average(Number of pixels)of Red, Green and Blue value for the given bitmap.
Bitmap bitmap = someBitmap; //assign your bitmap here
int redColors = 0;
int greenColors = 0;
int blueColors = 0;
int pixelCount = 0;
for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
int c = bitmap.getPixel(x, y);
pixelCount++;
redColors += Color.red(c);
greenColors += Color.green(c);
blueColors += Color.blue(c);
}
}
// calculate average of bitmap r,g,b values
int red = (redColors/pixelCount);
int green = (greenColors/pixelCount);
int blue = (blueColors/pixelCount);
The answer from john sakthi does not work correctly if the Bitmap has transparency (PNGs). I modified the answer for correctly getting the red/green/blue averages while accounting for transparent pixels:
/**
* Calculate the average red, green, blue color values of a bitmap
*
* #param bitmap
* a {#link Bitmap}
* #return
*/
public static int[] getAverageColorRGB(Bitmap bitmap) {
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
int size = width * height;
int pixelColor;
int r, g, b;
r = g = b = 0;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
pixelColor = bitmap.getPixel(x, y);
if (pixelColor == 0) {
size--;
continue;
}
r += Color.red(pixelColor);
g += Color.green(pixelColor);
b += Color.blue(pixelColor);
}
}
r /= size;
g /= size;
b /= size;
return new int[] {
r, g, b
};
}
you can use this method for this purpose: Bitmap.createBitmap
For instance:
int[] colors = new int[yourWidth * yourHeight];
Arrays.fill(colors, Color.Black);
Bitmap bitamp = Bitamp.createBitmap(colors, yourWidth, yourHeight, Bitmap.Config.ARGB_8888);
Check for typo

Grab x,y coordinates for a given pixel RGB?

I have a screenshot method in my code and a BufferedImage instance. I'm wondering if it's possible to search the image data for a specific RGB, then return the X,Y coordinates for the pixel.
What could I use for that? Is it possible at all?
public int[] searchForColor(BufferedImage bi, int searchColor)
{
for (int x = 0; x < bi.getWidth(); ++x)
for (int y = 0; y < bi.getHeight(); ++y)
{
if ((bi.getRGB(x, y) & 0x00FFFFFF) == searchColor)
return new int[]{x, y};
}
}
Usage:
BufferedImage bi = takeScreenShot();
int searchColor = 0x2D5E83; // A random color
int[] coordinate = searchForColor(bi, searchColor);
int x = coordinate[0];
int y = coordinate[1];
http://www.roseindia.net/java/java-get-example/get-color-of-pixel.shtml and loop thru the image data

Categories

Resources