creating image from double[][]

H

harryos

hi
i have a double[][] that contains data of an image.I would like to
know how i can create a BufferedImage from this.I also want to convert
the data to greyscale values .I couldn't figure out how to use
javax.imageio methods to do this

thanks
harry
 
H

harryos

Without more specifics about the format of your original "double" data, it's impossible to suggest how a conversion to greyscale might work.

hi Pete,

i am reading an image
BufferedImage img=ImageIO.read(new File("someimage.png"));
int wd=img.getWidth();
int ht=img.getHeight();
int[] rgbArray=new int[wd*ht];
img.getRGB(0, 0,wd,ht,rgbArray,0,wd);

then i am converting the int[] rgbArray into a double[] sothat my
application can process the pixel values.For this i do something like

for each pixel at index i,
int pixel=rgbArray;
int alpha=(pix >> 24) & 0x0ff;(i found these in one of your prev
posts ,thanks!)
int r=(pix>>16)& 0x0ff;
int g=(pix>>8)& 0x0ff;
int b=pix & 0x0ff;

then i take average of r,g,b so that i may get a greyscale value
double grey=(r+g+b)/3.0

using these i create a double[][] since i know the width & height of
image
Now i would like to create an image from this double[][] (or after
some processing is done on these double values).That is where i would
like some help
I couldn't figure out how to create the image from such an array
thanks
harry
 
S

Stefan Ram

Jack Marsh said:
RGB Luminance value = 0.3 R + 0.59 G + 0.11 B
Consider for example what (r+g+b)/3.0 would do if the image
were composed entirely of red, green and blue bars. The result
would be gray = 1/3 everywhere.

If the image would be composed of red bars with
luminance 1/3/0.3. green bars with luminance 1/3/0.59
and blue bars with luminance 1/3/0.11, the result
would be gray = 1/3 everywhere, according to /your/
formula.

If the image would be composed of chocolate bars,
the result would be edible.
 
L

Lord Zoltar

That would be a big mistake. Rather than treating red, green and blue as
equals, they must be weighted... one common scheme is

RGB Luminance value   =   0.3 R + 0.59 G + 0.11 B

Consider for example what (r+g+b)/3.0 would do if the image were
composed entirely of red, green and blue bars.  The result would be gray
= 1/3 everywhere. Leaving you with a totally uniform gray image with no
details. The Luminance formula takes into account the reaction of the
eye to different parts of the visible spectrum.  Human eyes are more
sensitive to green than to red or green for example. Note that the
coefficients in the Luminance formula add to 1.0, so White is properly
replicated.

I'm curious as to how the weights are determined. Was it through
experimentation and trial and error, or was there some theory behind
why THOSE numbers are better than others?
 
N

Neil Coffey

Lord said:
RGB Luminance value = 0.3 R + 0.59 G + 0.11 B
[...]
I'm curious as to how the weights are determined. Was it through
experimentation and trial and error, or was there some theory behind
why THOSE numbers are better than others?

It's probably from experiments conducted by the CIE
(Commission Internationale de l'Éclairage) -- many colour-related
techniques used in computing are.

Neil
 
N

Neil Coffey

harryos said:
then i am converting the int[] rgbArray into a double[] sothat my
application can process the pixel values.For this i do something like [...]
then i take average of r,g,b so that i may get a greyscale value
double grey=(r+g+b)/3.0

So ignoring double arrays, the basic underlying thing you want to do
is convert an image to greyscale, right? In which case, why not:

- create a new greyscale BufferedImage
- get a graphics context to the greyscale image
(with createGraphics());
- render your original image to the greyscale image's graphics
context?
- use your shiny new greyscale image for whatever purpose.

You probably want to set the 'colour accuracy' rendering hint on
the graphics context. As someone has pointed out, just averaging
the RGB values isn't a great conversion (although it's commonly used).

Neil
 
J

jimgardener

hi i have a double[][] that contains data of an image.I would >like to know how i can create a BufferedImage from this.I also >want to convert the data to greyscale values .


I am not the owner of this code ,but i found this by googling.Also i
have some doubt as to the casting to short from double.But this gives
a 'toned down' greyscale image when i run this with a truecolor or
greyscale input image.The image is not as dark as the original one.I
don't know how to remedy that.Can some experts comment on this code.

public static BufferedImage CreateImageFromMatrix(double[] img, int
width) {
int[] grayImage = new int[img.length];
double[] scales = (double[])img.clone();
Arrays.sort(scales);
double min = scales[0];
double max = scales[scales.length - 1];
for(int i = 0; i < grayImage.length; i++) {
double v = img;
v -= min;
v /= (max - min);
short val = (short)(v * 255);
grayImage = (val << 16) | (val << 8) | (val);
}
BufferedImage bi = new BufferedImage(width, img.length / width,
BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, width, img.length / width, grayImage, 0, width);
return bi;
}

regards
Jim
 
K

Knute Johnson

Neil said:
harryos said:
then i am converting the int[] rgbArray into a double[] sothat my
application can process the pixel values.For this i do something like [...]
then i take average of r,g,b so that i may get a greyscale value
double grey=(r+g+b)/3.0

So ignoring double arrays, the basic underlying thing you want to do
is convert an image to greyscale, right? In which case, why not:

- create a new greyscale BufferedImage
- get a graphics context to the greyscale image
(with createGraphics());
- render your original image to the greyscale image's graphics
context?
- use your shiny new greyscale image for whatever purpose.

You probably want to set the 'colour accuracy' rendering hint on
the graphics context. As someone has pointed out, just averaging
the RGB values isn't a great conversion (although it's commonly used).

Neil

Or for that matter use a ColorConvertOp which is even faster.
 
J

John B. Matthews

jimgardener said:
hi i have a double[][] that contains data of an image.I would >like to know
how i can create a BufferedImage from this.I also >want to convert the
data to greyscale values .


I am not the owner of this code ,but i found this by googling.Also i
have some doubt as to the casting to short from double.But this gives
a 'toned down' greyscale image when i run this with a truecolor or
greyscale input image.The image is not as dark as the original one.I
don't know how to remedy that.Can some experts comment on this code.

public static BufferedImage CreateImageFromMatrix(double[] img, int
width) {
int[] grayImage = new int[img.length];
double[] scales = (double[])img.clone();
Arrays.sort(scales);
double min = scales[0];
double max = scales[scales.length - 1];
for(int i = 0; i < grayImage.length; i++) {
double v = img;
v -= min;
v /= (max - min);
short val = (short)(v * 255);
grayImage = (val << 16) | (val << 8) | (val);
}
BufferedImage bi = new BufferedImage(width, img.length / width,
BufferedImage.TYPE_INT_RGB);
bi.setRGB(0, 0, width, img.length / width, grayImage, 0, width);
return bi;
}


Assuming positive elements in img, each v is scaled to the range 0.0 ..
1.0. Multiplication by 255 scales to the range 0 .. 255. The narrowing
to short seems OK. I'd be more worried about division by zero. This
looks like a simple way to spread the given values evenly across the
limited grayscale real estate.

Is Arrays.sort() [O(n*log(n))] a reasonable alternative to a single
min/max pass [O(n)] through array?
 
K

Knute Johnson

harryos said:
Without more specifics about the format of your original "double" data, it's impossible to suggest how a conversion to greyscale might work.

hi Pete,

i am reading an image
BufferedImage img=ImageIO.read(new File("someimage.png"));
int wd=img.getWidth();
int ht=img.getHeight();
int[] rgbArray=new int[wd*ht];
img.getRGB(0, 0,wd,ht,rgbArray,0,wd);

then i am converting the int[] rgbArray into a double[] sothat my
application can process the pixel values.For this i do something like

for each pixel at index i,
int pixel=rgbArray;
int alpha=(pix >> 24) & 0x0ff;(i found these in one of your prev
posts ,thanks!)
int r=(pix>>16)& 0x0ff;
int g=(pix>>8)& 0x0ff;
int b=pix & 0x0ff;

then i take average of r,g,b so that i may get a greyscale value
double grey=(r+g+b)/3.0

using these i create a double[][] since i know the width & height of
image
Now i would like to create an image from this double[][] (or after
some processing is done on these double values).That is where i would
like some help
I couldn't figure out how to create the image from such an array
thanks
harry


If you want to convert a color image to grayscale, use the tools in the
API. It is much simpler and much faster.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;

public class ConvertToGray extends JPanel {
BufferedImage gray;

public ConvertToGray() {
try {
// read an image from the disk
BufferedImage image = ImageIO.read(new File("kittens.jpg"));

setPreferredSize(new Dimension(
image.getWidth(),image.getHeight()));

// create a grayscale image the same size
gray = new BufferedImage(image.getWidth(),image.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);

// convert the original colored image to grayscale
ColorConvertOp op = new ColorConvertOp(
image.getColorModel().getColorSpace(),
gray.getColorModel().getColorSpace(),null);
op.filter(image,gray);

} catch (IOException ioe) {
ioe.printStackTrace();
}
}

public void paintComponent(Graphics g) {
g.drawImage(gray,0,0,null);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

ConvertToGray ctg = new ConvertToGray();
f.add(ctg,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}
}
 
H

harryos

If you want to convert a color image to grayscale, use the tools in the API. It is much simpler and much faster.


thanks sir,that was a good pointer.
however i need to create an image from an incoming double[] .something
like what jim gave above
ie BufferedImage CreateImageFromMatrix(double[] img, int
width)

i tried it..but it gives a slightly faded image when i provide it a
double[] derrived from another greyscale image.I think some scaling is
to be done to make it brighter?

harry
 
J

John B. Matthews

harryos said:
need to create an image from an incoming double[] .something like
what jim gave above ie BufferedImage CreateImageFromMatrix(double[]
img, int width)


Referring to that code, again:
for(int i = 0; i < grayImage.length; i++) {
double v = img;
v -= min;
v /= (max - min);
short val = (short)(v * 255);
grayImage = (val << 16) | (val << 8) | (val);
}


Noting, again: "Assuming positive elements in img, each v is scaled to
the range 0.0 .. 1.0. Multiplication by 255 scales to the range 0 ..
255."
tried it..but it gives a slightly faded image when provide it
a double[] derrived from another greyscale image.


Is this surprising? You have taken some number of values and spread them
across the entire 256-valued gamut from white to black. If the image
appears faded, what can you infer about the distribution of values in
your source image? You can examine its histogram using, for example,
ImageJ:

<http://rsb.info.nih.gov/ij/>

Compare this to the histogram from your converted image.
I think some scaling is to be done to make it brighter?

Yes.
 
K

Knute Johnson

harryos said:
If you want to convert a color image to grayscale, use the tools in the API. It is much simpler and much faster.


thanks sir,that was a good pointer.
however i need to create an image from an incoming double[] .something
like what jim gave above
ie BufferedImage CreateImageFromMatrix(double[] img, int
width)

i tried it..but it gives a slightly faded image when i provide it a
double[] derrived from another greyscale image.I think some scaling is
to be done to make it brighter?

harry

Take a look at WritableRaster, it has methods to take double[] and set
the pixels. You can then get a BufferedImage and use the ColorConverOp
to change it to grayscale.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top