gray image log transformation in java - java

I am trying to get a log transformation from a gray image. But with whatever c value I will get a black image. Any idea?
that is my method:
///---------------------------------------------------
public static BufferedImage log_trans (int[][] imageData , int c){
BufferedImage LogImage = new BufferedImage(imageData.length, imageData[0].length, BufferedImage.TYPE_BYTE_GRAY);
double temp;
for (int i =0 ; i<imageData.length ; i ++){
for (int j=0 ; j<imageData[0].length ; j++){
int rgb = imageData[i][j];
rgb = (rgb<<16)|(rgb<<8)|(rgb);
temp = Math.log10(rgb+1);
rgb = (int) (c * temp);
LogImage.setRGB(i, j, rgb);
}}
return LogImage;
}
--------------------------------------------------------------
public static int[][] readimage(File filename){
BufferedImage img;
try {
img = ImageIO.read(filename);
// Gray_scaled Image output
int width = img.getWidth();
int height = img.getHeight();
ImagePro.fw=width;
ImagePro.fh = height;
int [][] readimageVal = new int [width][height];
for (int i = 0; i<height ; i++){
for (int j =0 ; j<width ; j++){
Color c = new Color(img.getRGB(j, i));
int r= (int)(c.getRed() * 0.299)&0xff;
int g = (int)(c.getGreen() * 0.587)&0xff;
int b = (int)(c.getBlue() *0.114)&0xff;
int avg = ((r+b+g));
readimageVal[j][i] = avg;
}
}
return readimageVal;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

It seems that "rgb" is always negative, so temp is always Nan, so in the end "rgb" after:
rgb = (int) (c * temp);
is always 0 and this is why you always get black picture.
After changing your 8th line to:
rgb = (((byte)rgb & 0xFF)<<16)|(((byte)rgb & 0xFF)<<8)|(((byte)rgb & 0xFF));
I get some very dark output, but it's not very nice. I tested for value of "c" being 1, 18000, 180000 and 0x00FFFFFF.

Related

How do I create an image for every color in the ARGB spectrum in java?

I wanna make a pixel image for every color, but this code only makes (255,255,255,255) images. It loops through the entire for loop before it uses the int values for the creation of the images. How do I stop it at each integer during the for loop so I can make images that start at (0,0,0,0) then go to (0,0,0,1) and then (0,0,0,2) and so on all the way to (255,255,255,255)? so, I need to make 4,294,967,296 images in total.
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
int width = 1;
int height = 1;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
File f = null;
try{
for(int i = 0; i < 4294967297; i++) {
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++){
for(int alpha = 0; alpha < 256; alpha++){
for(int red = 0; red < 256; red++){
for(int green = 0; green < 256; green++){
for(int blue = 0; blue < 256; blue++) {
int a = alpha;
int r = red;
int g = green;
int b = blue;
int p = (a << 24) | (r << 16) | (g << 8) | b;
img.setRGB(x, y, p);
}
}
}
}
}
}
f = new File("/Users/dimensionalengineer/Downloads/Colors/Color" + i + ".png");
ImageIO.write(img, "png", f);
}
} catch(IOException e) {
System.out.println("Error: " + e);
}
}
}
If you change the order of the for loops it will create one image for each possible colors. But beware that your file manager might not be able to handle that many files inside of one directory.
BufferedImage img = null;
File f = null;
int width = 1;
int height = 1;
int i = 0;
// loop for every possible color
for(int alpha = 0; alpha < 256; alpha++){
for(int red = 0; red < 256; red++){
for(int green = 0; green < 256; green++){
for(int blue = 0; blue < 256; blue++) {
// create one image filled with one color
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int a = alpha;
int r = red;
int g = green;
int b = blue;
int p = (a << 24) | (r << 16) | (g << 8) | b;
// loop every pixel
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++){
img.setRGB(x, y, p);
}
}
// save to file
f = new File("/Users/dimensionalengineer/Downloads/Colors/Color" + i++ + ".png");
ImageIO.write(img, "png", f);
// free ram
img.dispose();
}
}
}
}

Tensorflow in Android: java.nio.BufferOverFlowException

Good morning. I'm a developer trying to put a tensorflow model into Android.
I've encountered an error that I've never seen before while trying to fix it with multiple errors.
The java.nio.BufferOverFlowException error i'm facing now is that it didn't happen before, but it happened suddenly.
My code uses a byte array, but i cannot specify which part is the problem.
This source that takes a float array as input and returns an array with 10 classes after passing through the model.
The returned values have softmax value.
public float[] hypothesis(float[] inputFloats, int nFeatures, int nClasses, Context context)
{
try {
int nInstance = inputFloats.length / nFeatures;
// FloatBuffer.wrap(inputFloats);
Toast.makeText(context, "", Toast.LENGTH_LONG).show();
inferenceInterface.feed(INPUT_NODE, FloatBuffer.wrap(inputFloats), INPUT_SIZE);
inferenceInterface.run(OUTPUT_NODES_HYPO);
float[] result = new float[nInstance * nClasses];
inferenceInterface.fetch(OUTPUT_NODE_HYPO, result);
return result;
}
catch(Exception e){
Toast.makeText(context, e+" ...", Toast.LENGTH_LONG).show();
return null;
}
}
The length of the inputfloats is 720 and the nFeatures is 720. nClasses is 10.
Although the value is not correct, it worked before.
e in the catch statement prints java.nio.BufferOverFlowException.
Could there be a problem in the middle of converting a byte array to a float array?
Related source.
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;
}
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.2126 * R + 0.7152 * G + 0.0722 * B);
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
private void activityPrediction(float[] inputArray){
try {
float[] result = activityInference.hypothesis(inputArray, 20*36, 10, getApplicationContext());
predictionView.setText(Arrays.toString(result));
}
catch (Exception e){
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private byte[] bitmapToByteArray(Bitmap bitmap)
{
int chunkNumbers = 10;
int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
byte[] imageBytes = new byte[bitmapSize];
int rows, cols;
int chunkHeight, chunkWidth;
rows = cols = (int) Math.sqrt(chunkNumbers);
chunkHeight = bitmap.getHeight() / rows;
chunkWidth = bitmap.getWidth() / cols;
int yCoord = 0;
int bitmapsSizes = 0;
for (int x = 0; x < rows; x++)
{
int xCoord = 0;
for (int y = 0; y < cols; y++)
{
Bitmap bitmapChunk = Bitmap.createBitmap(bitmap, xCoord, yCoord, chunkWidth, chunkHeight);
byte[] bitmapArray = getBytesFromBitmapChunk(bitmapChunk);
System.arraycopy(bitmapArray, 0, imageBytes, bitmapsSizes, bitmapArray.length);
bitmapsSizes = bitmapsSizes + bitmapArray.length;
xCoord += chunkWidth;
bitmapChunk.recycle();
bitmapChunk = null;
}
yCoord += chunkHeight;
}
return imageBytes;
}
private byte[] getBytesFromBitmapChunk(Bitmap bitmap)
{
int bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(bitmapSize);
bitmap.copyPixelsToBuffer(byteBuffer);
byteBuffer.rewind();
return byteBuffer.array();
}
'e.printStackTrace()' result
at com.example.leehanbeen.platerecognize.ActivityInference.hypothesis(ActivityInference.java:58)
at com.example.leehanbeen.platerecognize.MainActivity.activityPrediction(MainActivity.java:148)
at com.example.leehanbeen.platerecognize.MainActivity.access$100(MainActivity.java:28)
at com.example.leehanbeen.platerecognize.MainActivity$2.onClick(MainActivity.java:69)
around MainActivity.java:69
byte[] byteArrayRes = bitmapToByteArray(image_bitmap);
float[] inputArray = bytetofloat(byteArrayRes);
activityPrediction(inputArray);
MainActivity.java:28
public class MainActivity extends AppCompatActivity {
MainActivity.java:148
float[] result = activityInference.hypothesis(inputArray, 20*36, 10, getApplicationContext());
around ActivityInference.java:58
float[] result = new float[nInstance * nClasses];
inferenceInterface.fetch(OUTPUT_NODE_HYPO, result);

Convert an open cv mat to an integer array

I am trying to convert an open cv mat of type CV_8UC3 (RGB) to an integer array.
void copyMatToJIntArray(Mat m,jint* jia)
{
Mat tempMat;
cvtColor(m,tempMat,CV_BGRA2RGB);
jint size = tempMat.rows*tempMat.cols* tempMat.elemSize();
u_char * uchars = new u_char[size];
for(int r=0;r<tempMat.rows;r++)
{
for(int c=0;c<tempMat.cols;c++)
{
u_char r=*(tempMat.data+ r*tempMat.step + c);
u_char g=*(tempMat.data+ r*tempMat.step + c+1);
u_char b=*(tempMat.data+ r*tempMat.step + c+2);
uchars[r*tempMat.step+c]=r;
uchars[r*tempMat.step+c+1]=g;
uchars[r*tempMat.step+c+2]=b;
}
}
for (int i = 0; i < tempMat.rows*tempMat.cols; i++)
{
jia[i] = uchars[i];
}
}
I pass this inteher array via JNI to android java where it is converted into an a bitmap
croppedImageBitmap.setPixels(BGRA, 0, width, 0, 0, width, height);
imageView1.setImageBitmap(croppedImageBitmap);
But when I view it on my android test phone, there is a blue tint over the image
I don't know Java but it is almost the same as opencv in c++, you can use my c++ version:
typedef std::vector<std::vector<int> > Matrix;
Matrix int_Im(3, std::vector<int>(m.cols*m.rows,0));
Matrix copyMatToJIntArray(Mat m,jint* jia)
{
for(auto j=0, k = 0;j<m.rows;j++)
for(auto i=0;i<m.cols;i++)
{
int_Im[k][0] = m.at<uchar>(j,i)[0];
int_Im[k][1] = m.at<uchar>(j,i)[1];
int_Im[k][2] = m.at<uchar>(j,i)[2];
k++;
}
return int_Im;
}
Try this
jintArray resultImage = env->NewIntArray(h.total());
jint *_data = new jint[h.total()];
for (int i = 0; i < h.total(); i++) {
char b = h.data[h.channels() * i];
char g = h.data[h.channels() * i + 1];
char r = h.data[h.channels() * i + 2];
char a = 255;
_data[i] = (((jint) a << 24) & 0xFF000000) + (((jint) r << 16) & 0x00FF0000) +
(((jint) g << 8) & 0x0000FF00) + ((jint) b & 0x000000FF);
}
env->SetIntArrayRegion(resultImage, 0, h.total(), _data);
delete[]_data;
And on your java side
int[] result = yourfunction();
Bitmap bitmap = Bitmap.createBitmap(result, yourimagewidth, yourimageheight, Bitmap.Config.ARGB_8888);
Array data format should correspond to the Mat's type according to this table
public static Mat arrayToMat(double[][] array,int height, int width, int matType)
{
Mat image = new Mat(height,width,matType);
for (int i=0; i<height; i++)
{
for (int j=0; j<width; j++)
{
image.put(i,j,array[i][j]);
}
}
return image;
}
public static double[][] matToArray(Mat frame)
{
double array[][] = new double[frame.height()][frame.width()];
for (int i=0; i < frame.height(); i++)
{
for (int j=0; j < frame.width(); j++)
{
array[i][j] = frame.get(i,j)[0];
}
}
return array;
}

Comparing 2 Images and marking differences with rectangles

Edit: Updated the code, the code below now correctly draws rectangles around multiple shapes, but still has a minor issue of sometimes creating multiple rectangles on one single shape.
I have 2 Images, that i compare pixel by pixel with each other and i want my programm to create rectangles around the area of difference (multiple rectangles with multiple instances of differences). So far i managed to do this with a single rectangle, so if i had multiple "instances", they'd all be in one big rectangle. Now i'm trying to make the programm create multiple rectangles, but run into an IndexOutOfBoundsException.
The Programm itself overlays the 2 Images being compared with opacity and outputs the resulting overlaid image along with the rectangles into a new File. Both Images being compared have a consistent equal width and height.
I'm calling the rectangles i want to be drawn "regions" within the code.
The Region List is being continiously updated while the comparison is running.
The first question i asked myself was, when does a point of difference (pixel difference) belong to a region?
My attempt was to define a "tolerance", so as long as the pixel being compared is within the tolerance of the last found point of difference, it belongs to the same region. I quickly realized that this doesn't work as soon as i have a shape in form of a giant U on my image, with the top points being far enough apart to be not within the tolerance. And now i'm kind-of stuck, because i feel like i'm on the wrong path.
Below is the code i have so far:
private void compareImages() throws IOException{
BufferedImage img1;
BufferedImage img2;
try {
img1 = ImageIO.read(new File(path_to_img1));
img2 = ImageIO.read(new File(path_to_img2));
} catch (Throwable e) {
System.out.println("Unable to load the Images!");
return;
}
BufferedImage dest = new BufferedImage(img1.getWidth(), img1.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D gfx = dest.createGraphics();
gfx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65f));
//Compare Images pixel by pixel
int sX = 9999; //Start X
int sY = 9999; //Start Y
int eX = 0; //End X
int eY = 0; //End Y
boolean isDrawable = false;
boolean loadedRegion = false;
List<Rectangle> regions = new ArrayList<>();
List<Rectangle> check_regions = new ArrayList<>();
Rectangle tmp_comparison;
int regionID = 0;
int tolerance = 25;
for (int i = 0; i < img1.getHeight(); i++) {
for (int j = 0; j < img1.getWidth(); j++) {
loadedRegion = false;
regionID = 0;
sX = 9999;
sY = 9999;
eX = 0;
eY = 0;
if ( img1.getRGB(j, i) != img2.getRGB(j, i) ){
isDrawable = true;
if (regions.size() != 0){
//Attempting to locate a matching existing Region
tmp_comparison = new Rectangle(j, i, 1, 1);
for (int trID = 0; trID<regions.size(); trID++){
if (tmp_comparison.intersects(check_regions.get(trID).getBounds()) == true) {
// Region found
sX = (int) regions.get(trID).getX();
sY = (int) regions.get(trID).getY();
eX = (int) regions.get(trID).getWidth();
eY = (int) regions.get(trID).getHeight();
regionID = trID;
loadedRegion = true;
break;
}
}
}
//Update Region Dimension
if (j<sX){
sX = j;
}
if (j>eX){
eX = j;
}
if (i<sY){
sY = i;
}
if (i>eY){
eY = i;
}
if (regions.size() == 0 || loadedRegion == false){
regions.add(new Rectangle(sX, sY, eX, eY));
check_regions.add(new Rectangle(sX-tolerance, sY-tolerance, eX-sX+(tolerance*2), eY-sY+(tolerance*2)));
} else {
regions.set(regionID, new Rectangle(sX, sY, eX, eY));
check_regions.set(regionID, new Rectangle(sX-tolerance, sY-tolerance, eX-sX+(tolerance*2), eY-sY+(tolerance*2)));
}
}
}
}
// If there are any differences, draw the Regions
// Regions are 10px bigger in all directions as compared to the actual rectangles of difference
if (isDrawable == true){
gfx.setPaint(Color.red);
for (int i = 0; i<regions.size(); i++) {
int dsX = 0;
int dsY = 0;
int deX = 0;
int deY = 0;
sX = (int) regions.get(i).getX();
sY = (int) regions.get(i).getY();
eX = (int) regions.get(i).getWidth();
eY = (int) regions.get(i).getHeight();
if (sX>=10){dsX = sX-10;}
if (eX<=img1.getWidth()-10){deX = eX-sX+20;}
if (sY>=10){dsY = sY-10;}
if (eY<=img1.getHeight()-10){deY = eY-sY+20;}
gfx.draw(new Rectangle2D.Double(dsX, dsY, deX, deY));
}
}
gfx.drawImage(img1, 0, 0, null);
gfx.drawImage(img2, 0, 0, null);
gfx.dispose();
File out = new File("C:\\output.png");
ImageIO.write(dest, "PNG", out);
}
Below is the code that creates one big rectangle around all the differences found in the images being compared.
private void oneRectangle() throws IOException{
BufferedImage img1;
BufferedImage img2;
try {
img1 = ImageIO.read(new File(path_to_img1));
img2 = ImageIO.read(new File(path_to_img2));
} catch (Throwable e) {
System.out.println("Unable to load the Images!");
return;
}
BufferedImage dest = new BufferedImage(img1.getWidth(), img1.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D gfx = dest.createGraphics();
gfx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65f));
//Compare Images pixel by pixel
boolean isDrawable = false;
int sX = 9999;
int sY = 9999;
int eX = 0;
int eY = 0;
for (int i = 0; i < img1.getHeight(); i++) {
for (int j = 0; j < img1.getWidth(); j++) {
if ( img1.getRGB(j, i) != img2.getRGB(j, i) ){
isDrawable = true;
if (j<sX){
sX = j;
}
if (j>eX){
eX = j;
}
if (i<sY){
sY = i;
}
if (i>eY){
eY = i;
}
}
}
}
// Draw rectangle if there are any differences
if (isDrawable == true){
gfx.setPaint(Color.red);
int dsX = 0;
int dsY = 0;
int deX = 0;
int deY = 0;
if (sX>=10){dsX = sX-10;}
if (eX<=img1.getWidth()-10){deX = eX-sX+20;}
if (sY>=10){dsY = sY-10;}
if (eY<=img1.getHeight()-10){deY = eY-sY+20;}
gfx.fill(new Rectangle2D.Double(dsX, dsY, deX, deY));
}
gfx.drawImage(img1, 0, 0, null);
gfx.drawImage(img2, 0, 0, null);
gfx.dispose();
File out = new File("C:\\output.png");
ImageIO.write(dest, "PNG", out);
}

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

Categories

Resources