-
Notifications
You must be signed in to change notification settings - Fork 21
Parametric Color Types #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm not sure what the original rationale for this decision was. Perhaps @StefanKarpinski or @dcjones would be the best to provide insight here? |
We probably should switch to parametric types. Being able to use color types in OpenGL without conversion would indeed be nice. Honestly, I think original rationale was just that this was the first Julia code I wrote and I didn't entirely understand parametric types. |
To be fair, this is the first (and only) Julia code that I worked on, and I still don't entirely understand parametric types. |
I almost have this done. Here's an important implementation decision: I'd like to implement support for The problem comes in with the following: white is defined as So, does there need to be a separate |
Yes, that's why I thought, you might just want to have floating point types in the beginning.
That's exactly what parametric types and multiple dispatch should be used for, right? |
I actually was just thinking about fixed size arrays and colors. |
@SimonDanisch (post 1): I initially thought that dispatch could be used too, and indeed my current implementation takes that route. But the example I gave shows the danger of this approach. I haven't seen a As an example, Here's a related example: suppose one performs an image transformation, like a rotation. In general, you'll need to do pixel interpolation. Using Julia's rules for arithmetic, the linear interpolation at a location halfway between two pixels with values These are reasons why I suspect the scaling/interpretation of the meaning has to be separated from the raw data type used to represent the value. |
Actually, it occurs to me that fundamentally this is an attribute that should be attached to the number. So perhaps the best approach would be to define
So a value recorded by a 12-bit camera could be represented as Not exactly sure how arithmetic on such types would work out, but it's interesting to consider. |
The range thing is similar to what I was going to suggest, but turned a bit sideways. A way to look at it is that when you use Uint8 like this, you're not really using it the normal way – i.e. to represent the integer values 0 through 255. Rather, you're using it as a kind of fixed point type that can represent the values 0/255, 1/255, ..., 255/255. Perhaps it would be better to always have the values be between 0 and 1 but define different standard ways of representing those values. Thus, instead of the type parameter being Uint8, it would be an 8-bit fixed-point float. |
But that can't be a real solution, as it will break compatibility with a lot of other packages (OpenCV, OpenGL and the like). |
I think I just fully grasped why you would like to have RGBI or RangedNumber and don't feel comfortable with my solution. |
@StefanKarpinski, that's a really interesting suggestion---thanks. I'm going to have to spend some time thinking about it, but indeed this might be the magic answer. @SimonDanisch, correct. In scientific imaging, it's meaningful to say that the image intensity is 743: assuming you know the gain of your camera, this implies a certain number of photons that you collected, which in turn implies a certain signal-to-noise ratio, which in turn influences your confidence in your results. Saying you have to convert to a 0-1 scale to do arithmetic on images emphasizes "display" above "data", and I'm uncomfortable with that. Careful bookkeeping elsewhere can solve this problem, though. |
Okay, so what you're saying is, you don't want to loose your scale, but need floatingpoints for arithmetic. As for intensity values, it makes sense to introduce a new type like Intensity{T <: Real}, as they follow completely different semantics. |
I agree that people who want to work with RGBs are unlikely to be the same people who need photons. Indeed I'm planning an SIUnits-like module for converting between I think I'm just going to start writing a |
Looks like Jeff already has a somewhat related package: https://github.com/JeffBezanson/FixedPoint.jl. |
Ah you found it:) i just started searching for it. |
I'm not immediately interested in And yes, it's a good idea to avoid exotic types that users have to create. I'm currently thinking |
Wait... With that you would achieve exactly the opposite, from what I need for interoperability. |
The idea is Example start of an implementation:
|
I guess fixedpoint types are represented as the underlying integer in
|
The core tension is that the two "sides" have quite different expectations from color values:
Since these new types have the semantics of real values between 0 and 1 and an unsigned 8-bit representation, they give both sides what they want. It's a little early to say anything conclusive, but I kind of suspect that this will end up having a lot less dissonance at either end. You would only need new types if you have a new way of representing colors, which is not especially common. |
I agree, it seems to be a brilliant solution! @timholy |
It's not crazy, but I was going to wait to tackle such things when a serious need arose. |
Close by bb94a80 |
Hi,
is there any reason, not to have the color spaces parametric?
That's the major reason holding me back to use colors for OpenGL.
I guess it can get a little complicated with the ranges, if you introduce uint8 for the color spaces.
But I mainly need Float32 colors, because OpenGL has very limited to non-existent support for Float64 values.
So I would propose to use at least T<:FloatingPoint instead of Float64.
I guess I could just define
convert(Array{Float32,1}, Color)
, but is that really the way to go?Advantage: the user doesn't have to postfix every number with f0.
Disadvantage: large arrays, for example 3D arrays with color values, would be quite slow to convert...Which is definitely bad, if it can be avoided that easily.
Side note:
OpenGL is totally fine with any
Array{Immutable, 1/2/3}
for a texture or buffer, so an array with Float32 colors could get uploaded directly to VRAM)The text was updated successfully, but these errors were encountered: