Sign in to follow this  
Shai

is it wrong to use floats to store images?

Recommended Posts

currently I'm writing a bunch of classes to easily load and filter images... each class starts by allocating a bunch of memory to store the floats of the image. Is it worth the hassle to rewrite these classes into using chars? will the increase in speed be noticeable?

Share this post


Link to post
Share on other sites
Depend on what you want to do with the images...

use floats if you want to "edit" the images, either by making effects and stuff. Floats makes much sure that you don't loose information in the process.
like bluring, lightning etc etc...

If your idea is to do "photoshop" on the images ... then floats
If your idea is just displaying or simple editing ... then char (or int, byte+byte+byte+byte = int )

Share this post


Link to post
Share on other sites
It's not really a speed issue, more a size issue. A char (rather, 24 bit RGB) takes up one quarter the memory of a float based version. Speedwise, on modern processors it will be slower due to the increased amount of memory access being done.

Skizz

Share this post


Link to post
Share on other sites
agree - but then again, back to what you want to use it for

lets take a simple example - brightness /contrast
Think this is lua or something...

float brightness = 0.2
float contrast = 1.5

for y=0, height-1 do
for x=0, width-1 do
r,g,b,a=pget(x,y) //function return r,g,b,a from pixel
r=(r-0.5)*contrast+0.5+brightness
g=(g-0.5)*contrast+0.5+brightness
b=(b-0.5)*contrast+0.5+brightness
pset(x,y,r,g,b,a) // function sets r,g,b,a on pixel
end
progress(y/height) // don't remember
end

Just think it works on a x by y image...

This code is slow, but create a good adjusting on the image. +you can adjust with small amounts. This creates a good image.
Doing this on an image based on char is not a smart idea if your goal is good images.
If speed is important, then you might sacrifice speed for quality, and do it with char... but then you adjust the brightness /contrast differently

Share this post


Link to post
Share on other sites
Quote:
Original post by Skizz
It's not really a speed issue, more a size issue. A char (rather, 24 bit RGB) takes up one quarter the memory of a float based version. Speedwise, on modern processors it will be slower due to the increased amount of memory access being done.

Skizz

but a float is 32-bit and so are most modern day processors... won't this minimize the difference in speed of floats and chars?

(unless ofc 1 32-bit instruction can reserve 4 chars)

Share this post


Link to post
Share on other sites
Quote:
Original post by DarkSlayer
Depend on what you want to do with the images...

use floats if you want to "edit" the images, either by making effects and stuff.

that's the idea :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Shai
Quote:
Original post by Skizz
It's not really a speed issue, more a size issue. A char (rather, 24 bit RGB) takes up one quarter the memory of a float based version. Speedwise, on modern processors it will be slower due to the increased amount of memory access being done.

Skizz

but a float is 32-bit and so are most modern day processors... won't this minimize the difference in speed of floats and chars?

(unless ofc 1 32-bit instruction can reserve 4 chars)

The bit width of a processor is a very misleading metric. It's usually the width of the native integer type. The floating point size has nothing to do with this. In fact, the 16 bit versions of the x86 processors (8086, 80186, 80286) could still handle 32 bit floats. You can also specify 64 bit floats as the 'double' type. Floats will be slower than using chars because FPU operations are slower and you're using much bigger data sets, but they will be more accurate. Also, if you want to you can use the MMX (for char based) or the SSE (for float based) extensions to manipulate the RGB values in parallel.

Skizz

Share this post


Link to post
Share on other sites
If you want a 3.40282367+e38 colour bitmap then be my guest, but I imagine it's a little overkill.

If you only want to manipulate a bitmap then that's different, you usually aren't doing that sort of thing in realtime, so IMHO the extra accuracy would be worth it.

Then again, if it was accuracy you were worried about, you might be better off using an 8.8 or 8.24 fixed point representation for each component, but that's a lot more work.

Share this post


Link to post
Share on other sites
why don't you just normalize them when you load them.

r = (float)red/256.0f;
g = (float)green/256.0f;
b = (float)blue/256.0f;
(alpha, if necessary)

and then store them as chars? Why waste disk space? You just do the conversion somewhere before putting them into your class.

Share this post


Link to post
Share on other sites
thnx guys I'll store them as chars and convert 'em to fixed point notation

*goes searching for a good fixed point tutorial*

Share this post


Link to post
Share on other sites
I'm glad someone finally suggestd the obvious answer of fixed-point. However just to make things clear, you store the image on disk with 1 char per color channel (3 bytes for RGB), but in memory I'd suggest storing them as shorts in 8.8 (unsugned) fixed point format. This makes operations such as multiplication easy such that you don't lose accuracy, as you really need 32-bit ints to perform 8.8 multiplication and division with no accuracy loss.
Plus and Minus is simple - no change.

Just be sure to stay away from floats altogether so that it will not be unnecessarily slow. use /2, or >>1, not *0.5 for example.

Share this post


Link to post
Share on other sites
just a note ...

you could also save the image as float ...

let say you load an image, or start drawing an image - make it float

if you want to save your work (but not as final result) - save it with floats, so you don't loose image data.
every pixel is usually represented between 0.00 to 1.00 (0,0,0 to 255,255,255).
But what if you are working on an image, and some of your pixles is 1,1 or -0.5 ... if you convert this data to standard bmp image, these result would be saved as 255,255,255 and 0,0,0 ... you will loose image data ... Even loose image data

so a work-file, temp-file or whatever (something in progress), should be saved with floats ... not char.

the final result should however be converted to char and then to an imageformat of choice ...

anyway ... just to get you started ... focus on floats .. then move on.

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
I'm glad someone finally suggestd the obvious answer of fixed-point. However just to make things clear, you store the image on disk with 1 char per color channel (3 bytes for RGB), but in memory I'd suggest storing them as shorts in 8.8 (unsugned) fixed point format. This makes operations such as multiplication easy such that you don't lose accuracy, as you really need 32-bit ints to perform 8.8 multiplication and division with no accuracy loss.
Plus and Minus is simple - no change.

Just be sure to stay away from floats altogether so that it will not be unnecessarily slow. use /2, or >>1, not *0.5 for example.


I'd stay away from fixed point it will byte you in the ass down the road. But it's up to you.



Share this post


Link to post
Share on other sites
Many image processing algorithms can be vectorized. They can also take advantage of multiple processors. All future processors will have multiple cores. Already exist compilers that can vectorize and split problem into multiple threads (Intel C++). In the future they will do it even better.

If you go fix point you will not take advantage of this or not take advantage of it as easily. That might not be a problem for you and than fix-point will be sufficient for your app. It depends on what you need right now compared to what you plan to do today and tommorow. If you want to use this library with OpenGL, you will have to convert anyways from fixed point. What does the fixed point really save you in the long time? Just a bit faster ops in the short term. But two years later you will have new compiler and CPU and you will have to throw away your code. If that's not a problem than don't worry about it and use fixed point ;-)


Share this post


Link to post
Share on other sites
There is one alternative. Use generics (templates). Then you can design you class independent of the numeircal type. So for now you can use a fixed-point and tommorow you can plug in floats or doubles.

Share this post


Link to post
Share on other sites
I feel the earge to push www.pixeltoaster.com , it's a new library from gaffer (the man who gave you PTC, OpenPTC and TinyPTC) which handles float display, so you can display your float-stored-images directly, and he has some really fast convertion routine too, until hardware support arrives.

Could be fun just to try, I can't yet, I'm waiting for the linux one (coming).

Albert

Share this post


Link to post
Share on other sites
Quote:
Original post by qesbit
Many image processing algorithms can be vectorized. They can also take advantage of multiple processors. All future processors will have multiple cores. Already exist compilers that can vectorize and split problem into multiple threads (Intel C++). In the future they will do it even better.

If you go fix point you will not take advantage of this or not take advantage of it as easily. That might not be a problem for you and than fix-point will be sufficient for your app. It depends on what you need right now compared to what you plan to do today and tommorow. If you want to use this library with OpenGL, you will have to convert anyways from fixed point. What does the fixed point really save you in the long time? Just a bit faster ops in the short term. But two years later you will have new compiler and CPU and you will have to throw away your code. If that's not a problem than don't worry about it and use fixed point ;-)

What has the use of fixed point / floating point got to do with vectorisation? MMX can do integer SIMD and SSE can do floating point SIMD so operations on RGB triplets (or ARGB for that matter) can be vectorised, i.e. operations can be applied to R, G and B (and A) at the same time regardless of the format.

Multiple processors would be utilised by creating threads that worked on large chunks of data, so CPU1 could work on scan lines 0 to height/2 - 1 and CPU2 could work on scan lines height/2 to height - 1. In practice, you'd probably use a tile system and have many concurrent processes running simultaneously.

And are you totally sure there is a compiler that can take serial, single threaded code and create parallel, multithreaded code? I don't think so.

Skizz

Share this post


Link to post
Share on other sites
Quote:
Original post by Skizz
What has the use of fixed point / floating point got to do with vectorisation?
MMX can do integer SIMD and SSE can do floating point SIMD so operations on RGB triplets (or ARGB for that matter) can be vectorised, i.e. operations can be applied to R, G and B (and A) at the same time regardless of the format.


Hence why I said he MAY OR MAY NOT be able to take advantage of it. Please learn to read critically before making assumptions.

Quote:

Multiple processors would be utilised by creating threads that worked on large chunks of data, so CPU1 could work on scan lines 0 to height/2 - 1 and CPU2 could work on scan lines height/2 to height - 1. In practice, you'd probably use a tile system and have many concurrent processes running simultaneously.

And are you totally sure there is a compiler that can take serial, single threaded code and create parallel, multithreaded code? I don't think so.

Skizz


It highly depends on the algorithm and the compiler.

Intel C++ can already do this. There exist compilers on super computers that have done this for a while. SIMD comes from the supercomputer world. Intel C++ can process an algorithm into multiple threads implicitly IF THE ALGORITHM MEETS CERTAIN CRITERIA.

I never discouraged him from using fixed point just to think of the problems he might have if he uses it.

I gave what I felt was the best alternative to design a generic class that can use either fixed point or floats, doubles etc. IMHO that would be the best way to design it.

I will not discuss this further but if later on he discovers he has dug himself a hole by hard coding everything in fix points than you can do rating++ again on me :-)


[EDIT]

But this is moot point to interop with other libs. Later he will discover wonderful world of DSP processing of images and will have troubles using other DSP libs because they do not understand his fixed point. How will he use FFTW with his own fixed point? How can it operate with OpenGL, DirectX or others? He will just have to convert everything again anyways from fixed to floating point.



[Edited by - qesbit on February 8, 2005 9:41:35 AM]

Share this post


Link to post
Share on other sites
here's a question that popped up, how do I get openGL to write fixed point values to the screen?

currently I just call:

glDrawPixels(imageWidth, imageHeight, GL_RGB, GL_FLOAT, result);

with 'result' being a pointer to an array of floats containing the pixel values (values are between 0 - 1).

(yes, I know glDrawPixels is slow, but let's forget about that for a sec)

Share this post


Link to post
Share on other sites
You have to convert them :-)

Silly hobbits, fixed point died eons ago in the age of 8086 machines and Castel Wolfenstein 3D :-)

Good luck shai implement fix point for the learning experience, and than when you know, you will understand what I mean as I have wandered down that path many moons ago :-)

Peace out

Share this post


Link to post
Share on other sites
Quote:
Original post by qesbit
Silly hobbits, fixed point died eons ago in the age of 8086 machines and Castel Wolfenstein 3D :-)

Died out eons ago did it? I've just finished writing a 3D football game for mobile phones in C++ that used fixed point maths and I'm currently doing a physics intensive game in J2ME that also uses fixed point maths. It is certainly not dead.

Skizz

Share this post


Link to post
Share on other sites
What a lot of absolute bull!
Fixed point is far supperrior to float for all of this. Floats is what beginners have used when they simply didn't understand fixed-point, or thought floating point was as fast enough or simpler. This has not changed, floating point addition for example will probably never be as fast as integer addition. Anyone who suggests floats for this is simply less experienced.

Okay, sure depending on how you want to filter these images, you may need to do slightly more work. e.g. generate a fixed point sin/cos table, or other fast tables.

The only thing that'll bite you in the ass would be using floats, when you find it is way too slow. Stop suggesting silly rumours.

Yes I'm sure glDrawPixels is slow (I'm not really a gl person), but with a few simple bit-shifts etc you can convert a fixed-point representation into an actual texture, which as we all know is gonna be drawn way fast!

Share this post


Link to post
Share on other sites
Quote:
Original post by DarkSlayer
the final result should however be converted to char and then to an imageformat of choice ...

I'm getting a *big* loss in quality when converting the 'finished' image from float to char.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this