3 grayscale images to 1 colour image in Java - java

Im looking to create a Java application that will take 3 grayscale images (each representing red, green and blue) and then merging them/flattening them/etc. to create one colour image, I was wondering if anyone knew if there are any existing algorithms or methods which I might be able to use?
I understand there is a program called ImageJ which I have used before and it does exactly what im looking to; you choose 3 images and an RGB image can be created from them. I know this is done in Java by using a lookup table, this is something ive never encountered before so wouldnt even know where to begin.
If anyone has any ideas of the best way to approach it, existing algorithms, how I might be able to make my own, etc. that would be great. Im not looking for anyone to code for me, just to guide me in the right direction; my theory of iterating every pixel for each R, G and B grayscale image might not work?
Thanks for the help in advance

Working in the sRGB colourspace, it is easy to implement a method that does this.
Consider the following method:
private static BufferedImage createColorFromGrayscale(BufferedImage red, BufferedImage green, BufferedImage blue){
BufferedImage base = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_INT_ARGB);
for(int x = 0;x < red.getWidth();x++){
for(int y = 0; y < red.getHeight(); y++){
int rgb = (red.getRGB(x, y) & 0x00FF0000) | (green.getRGB(x, y) & 0x0000FF00) | (blue.getRGB(x, y) & 0x000000FF);
base.setRGB(x, y, (rgb | 0xFF000000));
}
}
return base;
}
Creating a new base image, we create a colour component by using bitwise ANDs and ORs to create a 4 byte integer color in format ARGB which is assigned to the base image. Iterating through the whole image by the means of the for loops we are able to set each pixel of the resultant base image to the colours of each channel respectively.
This method assumes that all three images are equal in size. If images are not equal in size, you must handle that separately (e.g by means of stretching images before input or by modifying the method to accept images of different size.)
P.S: It might be more efficient to directly use one of the bufferedimage instances as the base image to save memory when dealing with large images...

Related

NDK - process RGB value without Alpha from an ARGB_8888 bitmap

I have a processing algo which performs well if I process each color channel seperately. but when I tried to process the whole pixel value, things missed up. the results are not good. now I want to isolate the 3 color channel from the pixel value( exclude alpha) then work on the new value (the 3 channels).
How can I do that in C++? knowing that I tried the RGB_565 bitmap format which is not a good solution. and knowing that I want to merge the RGB into a 24bits variable.
You can access each channel separately. The exact way depends on actual pixel format.
ANDROID_BITMAP_FORMAT_RGBA_8888: each pixel is 4-byte long, layout pattern is RGBARGBA..., i.e. the 1-st pixel byte is red component, the 2-d is green, the 3-d is blue and the 4-th is alpha component.
ANDROID_BITMAP_FORMAT_RGB_565: each pixel is 2-byte long, stored in native endianness, so color components may be extracted in next way:
red = (u16_pix >> 11) & 0x1f;
green = (u16_pix >> 5) & 0x3f;
blue = (u16_pix >> 0) & 0x1f;
ANDROID_BITMAP_FORMAT_RGBA_4444:
is deprecated because of poor quality, you shouldn't even think about this one
ANDROID_BITMAP_FORMAT_A_8:
is 1 byte per pixel and designed for alpha-only or grayscale images. It is probably not what you are looking for.
Note that Android has no 24bpp format, and you must choose 32bpp or 16bpp one. About your algo: there are two alternatives - code may access individual components right inside packed pixel value, or you may deinterleave packed pixels into few planes, i.e. arrays, each of them will hold only one channel. Then after processing you may interleave them again to one of the supported formats or transform to some other format you are interested in.

Filling spots in am image java where data is equal to 0

Right now I have a composite code that produces and image from recorded data. I am trying to figure out a way that I can fill the spots in the image where no data was recorded (aka where it reads 0.0) with a new color. I have been experimenting a little with Graphics, but am not finding a way that I can just will these empty spots. I would post an image if I had enough points...
But I hope you understand what I am trying to say.
Like the comment suggests we really need more info.
If you use a BufferedImage then you can simply set a single pixel color using this method setRGB(int x, int y, int rgb)

How to determine bufferedimage color type in java

I need a way to determine the type of this BufferedImage in java (Binary, Gray, 24 bit color, 8 bit color) ?
It is something like BufferedImage.getType() method ,that returns an integer that determines that ,but I need a way to handle that. And if there is an Algorithm that detects it like the color is grey if red=green=blue and so on. I will be thankful if you tell me about it
All regards
Either, as you suggest, use BufferedImage.getType() (you can find what the int return values mean, in the API doc).
Or, use BufferedImage.getColorModel() to get more information, like ColorSpace (ColorModel.getColorSpace()) to determine color space type, like RGB, CMYK or Gray, or special color spaces, like sRGB, AdobeRGB, PhotoYCC, IEXYZ, Lab etc.
If you need to figure out if your image in 24/32 bit depth with RGB color model really is all gray, you are out of luck, and instead have to loop though all the pixel values and see if R == G == B (perhaps with a small threshold).

Trying to write a program that processes images based on skin in Java

The process is pretty simple -- I want to take an image as input, and compare every pixel in the image against a specified color. Then return the percentage of pixels that match the color.
I'm sure this is very simple to implement, I just need some kind of guidance as to which library to use, whether there are any tutorials on image processing by pixels. I haven't really found anything and would love any help.
Also, if this is easier in another language, I wouldn't mind using that either. I'm just most proficient with Java
This is doable with the standard Java BufferedImage class.
File file= new File("tardis.jpg");
BufferedImage image = ImageIO.read(file);
int rgb = image.getRGB(42, 42);
int red = (rgb & 0x00ff0000) >> 16;
int green = (rgb & 0x0000ff00) >> 8;
int blue = rgb & 0x000000ff;
getHeight() and getWidth() do what you'd expect allowing full scanning. ImageIO is a convenience class for using ImageReaders (and writers).

Use Java to identify lines in a graph

I am working on an idea wherein I have to identify lines in a JPG or PNG file. The PNG file contains one graph of a single value - one x,y combination. For example, the graph looks like Y = mx+c.
I would like to identify the line in the graph - if I can indentify the position of the pixel in the frame, I believe I can get back the values (x,y) which were used to plot the graph. The assumptions here is - I know the scale i.e 1 pixel = what unit of Y ?
Can somebody please help me to write a code which will identify the pixels of a specific color in one PNG file?
EDIT
Lets take an example to make it clear. Lets say I have a set of data values X and Y like this -
X = 1, Y = 10
X = 2, Y = 20
X = 3, Y = 30
X = 4, Y = 40
X = 5, Y = 50
X = 6, Y = 60
In this case, if I use jfreechart type of charting tool and make a chart, it tools like a straight line.
So the input is the dataset and output is the .PNG file (using jchart or jfreechart) containing this line graph for Y values.
Question is - if we reverse the flow, can we develop one program which will take the PNG file (that contains the graph) and give me back the dataset.
The context of the problem is -- I want to store the PNG files in my application and not the raw dataset. But given a PNG file, I should be able to get back my dataset.
I'm a bit confused as to whether your problem is simply determining the colour of pixels in an image, or if the problem is the mathematics of what you're trying to do.
For the former, do something such as the following:
BufferedImage bimg = ImageIO.read(new File("whatever.png"));
// get the colour of the pixel at position (x, y)
int col = bimg.getRGB(x, y);
// decode red, green and blue components of colour if necessary
int r = (col >> 16) & 0xff;
int g = (col >> 8) & 0xff;
int b = col & 0xff;
If from the graph you just want to get back the dataset (i.e. not derive an equation from that data), then you essentially loop through each X position and find the Y position where there's a pixel of the colour that the graph plotting program uses. If the graph has axes, antialiasing etc, then the task will be more complex.
The task of deriving an equation from the data is potentially much more complex, but you can start by checking for certain suspected formulae such as y = mx + c as you mention. For example, you can loop through checking the difference between each Y position for the last; if that difference is always the same, then you've got a straight line graph (and at that point, deriving the formula should be trivial).
For testing for other equations, it helps to know a bit of calculus. Then, a starting point is to see if the differences in the differences match the derivative for the equation in question. (Just as an example, if the equation is y = ax^2 + c, then for every increase in X, the increase in Y will itself increase by 2a.)
Do I read that correctly: you have an image of a single line on an otherwise blank canvas? If so, you can just look down the leftmost pixel column and find the pixel that is different, then take a column a bit to the right and find the pixel there. Now you have two points, and generating a linear function from that is trivial. As unit, why not use pixels?
Generally, on a computer monitor you don't have a central (0,0) point, as that point is defined to be the top left corner of the screen. So if we are looking at a function f(x)=ax+b then b parameter is defined to be the y value of the function at x=0, meaning the left border of the screen. So it's important to define exactly what you are offsetting from.
To find the slope, just take some central point on the screen you know you have a point of the function there, go x pixels to the left or the right, find the y height delta, and y/x is the function slope, or parameter a in the function aforementioned.
i am not sure where you reached with your project, but i needed to detect lines in an image as well. Here is what helped me.
http://www.music.mcgill.ca/~cmckay/software/musictech/ScoreReader/HorizontalLineDetection.html

Categories