I'm currently working on comparing a filtered image to its original (unfiltered) image using the SSIM (Structural similarity) index using Java.
My research brought me to a mathematical formula where the average, variance, covariance and the dynamic range of the two BufferedImages are needed.
Getting to calculate the average and the variance was not a big problem for me, however I can't figure out a way to get the number of bits per pixel needed to calculate the dynamic range, and the covariance value, is this something I can obtain from the BufferedImage.
BufferedImage has a getColorModel() method, and in the returned ColorModel object there is a getPixelSize() method which returns the number of bits per pixel described by that ColorModel.
Related
I try to obtain the spectrum of an grayscale image using FFT Cooley–Tukey algorithm in Java.
I don't know exactly how to form the input for the algorithm and what values from the output to use in order to form the spectrum image.
Currently my input is an array of complex numbers, with Re = value of the pixel in 8bit grayscale domain and Im = 0;
After running the algorithm I obtain another array of complex numbers with the real part having a lot of values out of [0,255] range and imaginary part 0.
I have tried to create an image from the real numbers array modulo 256.
This is how the spectrum should look:
And this is what I've got:
Obviously I'me doing something terrible wrong but I don't know what.
You did not provide your source code ...
your result looks like resolution tree
used for recursive resolution/frequency information scaling and feature extraction not FFT !!! So may be your recursion is wrong or you overlap data (to code in-place FFT is almost insanity) you should start with 1D transform and then use that for 2D and visually check every stage (also the inverse transform to match original data)
your FFT output should have non zero Imaginary part !!!
look here How to compute Discrete Fourier Transform and into all sub-links in that answer of mine
is your image resolution exact power of 2?
if not zero pad it or the FFT would not work properly
your example is wrong
this is how it looks like in real:
left is input image (copied from your question)
middle is real part
right is imaginary part
you can combine them to power spectrum =sqrt(Re*Re+Im*Im) the Re and Im image is amplified to be seen else just few white dots in the corners would be visible. Here some more examples:
your expected result looks like shifted by half of the image resolution (so the center of symmetry is in center of image instead of in corners)
[Edit1] power and wrap
have added power and wrap functions to mine app so here is the result:
first the power is computed so intensity=sqrt(Re^2+Im^2) and then wrap is done by shifting image by half size right and down. What is overlapping that comes from the other side back so just swap all points in all lines swap((x,y),(x+xs/2,y)) and then the same for all columns swap((x,y),(x,y+ys/2)). Now the result matches the one from OP the app is here
I would like to know how to calculate and display a laplacian filtered image for an example Laplacian filter like below..
-1 6 -1
6 -20 6
-1 6 -1
Please help me with this. Thank you. I appreciate any help I can get.
Assuming that you are able to scan image pixel by pixel.
Original_Image(size) = Result_Image (size)
for( int i=1; i<Result_Image.rows-1;i++) // ignore first and last rows to avoid going out of range
{
for( int i=1;i<Result_Image.cols-1;i++)
{
Result_Image(i,j)= -20*Result_Image(i,j)+6*(Result_Image(i-1,j)+Result_Image(i+1,j)+Result_Image(i,j-1)+Result_Image(i,j+1))-1*(Result_Image(i-1,j-1)+Result_Image(i+1,j+1)+Result_Image(i+1,j-1)+Result_Image(i-1,j+1));
}
}
You can achieve this by using OpenCv for Java or similar image prcocessing libraries for Java if Java itself doesnt support scanning images pixel by pixel .
Note = this algorithm can be inefficent,the libraries have some useful functions for filtering images
You asked about Java, but in case you meant something more basic I will try to answer more generally.
Given a Filter Coefficients (You have an approximation of the Laplacian filter) the way to apply it on an image is Convolution (Assuming the Filter is LSI - Linear Spatially Invariant).
The convolution can be computed directly (Loops) of in the frequency domain (Using Convolution Theorem).
There are few things to consider (Real World Problems):
The convolution "Asks" for pixels beyond the image. Hence boundary conditions should be imposed ("Pixels" beyond the image are zero, constant, nearest neighbor, etc...).
The result of the convolution is bigger then the input image due to the "Filter Transient". Again, logical decision should be made.
If you're limited to Fixed Point math, proper scaling should be made after the operation (Rule of Thumb, built to keep the image mean, says the sum of all filter coefficients should be 1, hence you need the scaling).
Good Luck.
I have done my own function plotter with java which works quite well.
All you have to do is to iterate over the with (pixels) of the panel and calculate the y-value. Then plot it with a poly-line onto the screen and that's it.
But here comes my problem: There is a scale factor between the number of pixels and the value which I want to plot.
For example I'm at the 304' iteration (iterating over the with value of the plot panel). Now I calculate the corresponding value for this pixel position (304) by the rule of three. This gives me 1.45436. Then I calculate the sin based on this value. Which is transcendetal number. Then I use again the rule of tree to determine which y-pixel this value corresponds to. Doing so, I have to round because the pixel is an integer. And there is my data loss. This data loss may give me the following result:
This looks not really nice. If I play around with resizing the window I sometimes get a smooth result.
How can I fix this problem? I've actually never seen such plots in any other function plotter.
If you do this in Java, you might consider composing your data points to a Path2D. That would have floating point coordinates, and the drawing engine would take care of smoothing things down. You might have to disable stroke control, though.
I am using a BufferedImage to hold a 10 by 10 sample of an image. With this Image I would like to find an approximate average color (as a Color object) that represents this image. Currently I have two ideas on how to implement this feature:
Make a scaled instance of the image into a 1 by 1 size image and find the color of the newly created image as the average color
Use two for loops. The inner-most is used to average each line, the secondary for-loop is used to average each line pixel by pixel.
I really like the idea of the first solution, however I am not sure how accurate it would be. The second solution would be as accurate as they come, however it seems incredibly tedious. I also believe the getColor command is processor intensive on a large scale such as this (I am performing this averaging roughly at 640 to 1920 times a second), please correct me if I am wrong. Since this method will be very CPU intensive, I would like to use a fairly efficient algorithm.
It depends what you mean by average. If you have half the pixels red and half the pixels blue, would the average be purple? In that case I think you can try adding all the values up and dividing it by how many pixels you have.
However, I suspect that rather than the average, you want the dominant colour?
In that case one alternative could be to discretise the colours into 'buckets' (say at intervals of 100, or even more sparser in the extreme case just 3, one for Red, one for Green and one for Blue), and create a histogram (a simple array with counts). You would then take the bucket which has the most count.
Be careful with idea 1. Remember that scaling often takes place by sampling. Since you have a very small image, you have already lost a lot of information. Scaling down further will probably just sample a few pixels and not really average all of them. Better check what algorithm your scaling process is using.
UPDATE: Formal List of questions:
What do the float values (both input parameters, and the output) of a 2D noise implementation represent? - Partially answered, the inputs are the coordinates. How about the ouput? Also, can I use my integer as a float for the coords? 1.0, 122.0, etc.?
What's a good way to implement a seed in a 2D noise generator? Should I just make it a 3D noise generator using the 3rd param as a seed? Would that imply each seed can generate unique 2D noise?
Going along with the 2d map, generating bitmaps seems to be along the same lines. How could I generate a bitmap from the output? Presumably floats.
My questions are what do the float values (both input parameters, and output) of a cut and paste perlin noise 2D implementation represent? How could I generate a bitmap from them? If I can get a 2d array of some data type, I'm sure I could figure out how to use it to simulate my terrain.
And, I would use a cut and paste implementation, if I could ensure that I could seed the values for them. That's the other part of the question, it is an unanswered one I found here. - what's a good way to implement a seed in a noise generator?
Ok, I understand that this question has been asked many many times, so let me explain what I have researched and found.
First, I found this site here, which seemed to be a winner for explaining it to me. However, I then came up with another question which I found asked but not really answered completely here.
I then tried to get my hands dirty and code some in Java, which is my language of choice. I found this, which had me trying out the hash function given as an answer as my noise function, because I could use a seed there. Then I ran into a problem of it not returning a float to follow the rest of the processes in the tutorial. Back to the drawing board. Along the way, I found many many more sites with questions about perlin noise.
I found an unanswered question here that I hadn't even thought of yet because I haven't gotten my implementation to work. I can't find the link anymore but it said something along the lines of, even if you had a copy and pasted implementation what are the float inputs you put into the function? I was told I needed to pass INTEGERS that are my x and y on the map. I get float outputs from the cut and paste implementations as well. What do THOSE mean? How are those 2D? If I could keep things as integers it would make sense in my brain but in a way, I see that keeping them as integers would not be plausible for interpolating and smoothing the values for a continuous curve.
As I understand the code, these are simply the coordinates for which you want the value.
Using float doesn't seem to make sense here unless you want to support zooming without jitter. Using float values, you can easily zoom into the landscape by calculating intermediate values.
1/the values are a linear or cubic interpolation in between samples random dots forming a 2d grid, so every point is a calculated balance between the 4 predetermined non calculated closest points generated by random function.
2/this is great:
function rndng ( n: float ): float
{//random linear graph -1, 1
var e = ( n *122.459)%1;
return (e*e*143.754)%2-1;
}
function rnd2d ( n: float, m: float ): float
{//random 2d gooed enough for mountains -1, 1
var e = ( n*m *31.178694)%1;
return (e*e*137.21321)%1;
}
if speed is not an issue, you can multiply 5-10 of them for super random function, otherwise it's the fastest on cpu, that function.
3/you have to acces the bitmap read and write library functions, and write pixels, i.e. get pixel, set pixel. to read and write bitmaps, and also create and save bitmap files and filenames.