[Insight-users] Bug with fix Mean Image Filter : Color Spaces are
not Vector Spaces
Bradley Lowekamp
blowekamp at mail.nih.gov
Thu May 19 11:58:34 EDT 2005
Thank you for your quite detail explanation of some of the design
principle of ITK types.
However the current RGBPixel type does not follow your philosophy. It
does have several of the "ill-defined" operators implemented. I tried
compiling with these operator not defined. Building the library, tests,
and examples the only error I encountered was in the RGBPixelTest. So
perhaps they are not needed, but I did not try to build the
Applications.
I do believe that I may share the same philosophy of sticking to strict
but well defined concepts. I agree that the term vector is over used,
but based on it's context I infer on the meaning. For example in this
case I assumes that a vector was a collection of elements with the
expected "operators" defined.
In generic programming, I believe that "concepts" form the axioms and
operators which we are allowed to operator on a given templated type.
For example here are some of the concepts of an early version of STL:
http://www.sgi.com/tech/stl/table_of_contents.html This is usually a
difficult task which rarely produces a flawless set of "concepts".
There are many parallels to this aspect of generic programming and
abstract algebra. Concepts are quite similar to Ring, Fields and
Groups. With such "concepts" many types may fit the concepts all which
have a vastly difference structure. An algorithm can use any type along
as the type matches the required concepts. I have found such
definitions of concepts and stated require concepts missing in ITK.
As ITK grows to support such types as HSV, Tensor, and improved support
for RGB images, it may be quite important to nail down the fundamental
concepts of the pixel types. While there are methods to at compile time
validate if a given templated argument supports the required concepts
that may be further then is needed. The major benefit of nailing down
these concepts would be to enable algorithms to be more easily written
for several of these types of data.
This is my initial reaction to my efforts is tying to uses these
different types with different filters. It may be off. But I have a
feeling that it may benefit ITK in the long run for several reasons.
As I am still looking through some of the information on color, I only
have a brief comment. I am already quite familiar with color spaces and
certain aspect of them partially from my hobby of digital photography.
I think that here are operations that should be able to be perform on
color pixels. What these are and how they are defined I am unsure. This
is one case where they may be a concept, which vector are derived from,
which allows for certain operators but they may not be Euclidian for
example.
Thanks,
Brad
========================================================
Bradley Lowekamp
Management Systems Designers Contractor for
Office of High Performance Computing and Communications
National Library of Medicine
'blowekamp at mail.nih.gov
On May 18, 2005, at 7:31 PM, Luis Ibanez wrote:
>
>
> Hi Brad,
>
>
> This is a common misconception originated by the fact that
> Computer Scientist and Software Engineers misuse the term
>
>
> "Vector"
>
>
> The word "Vector" was coined by William Hamilton in his book
> "Elements of Quaternions" published in 1886 (post-mortem).
>
>
> In the same text Hamilton coined the terms:
>
> "Scalar"
> "Versor"
> "Tensor"
>
>
>
> A "Vector" is by definition mathematical object that embodies
> the concept of "direction in space". Strictly speaking, a Vector
> describes the relationshiop between two points in space, and
> captures both their relative distance and orientation.
>
>
>
> Computer scientists and software engineers missused the term
> vector in order to represent the concept of an "Indexed Set".
> Mechanical Engineers and Civil Engineers, who deal with the
> real world of physical objects will not commit this mistake
> and will keep the word "Vector" attached to a geometrical
> concept. Biologist, on the other hand will associate "Vector"
> to a "vehicle" that allows them to direct something in a
> particular direction.
>
>
>
> Textbooks in programming do not help to clarify those concepts
> and losely use the term "Vector" for the purpose of representing
> an "Enumerated set of common elements".
>
> STL follows this trend and continue using the word "Vector" for
> what it was not supposed to be used.
>
> Linear Algebra devoids the "Vector" from its notion of Geometrical
> reality and makes it an abstract set of numbers with arithmetic
> operations associated.
>
>
>
>
> In ITK we deal with real objects that inhabit the physical space.
>
> We chose to give the appropriate name to the mathematical objects
> that describe geometrical relationships in N-Dimensional space.
>
>
> Is for this reason that we explicitly make clear the distincion
> between:
>
>
> 1) Point
> 2) Vector
> 3) CovariantVector
>
>
>
> ... despite de fact that most people would be happy with a simple
> use of double[3] for the three concepts and then will proceed to
> perform all sort of conceptually flawed operations such as
> "adding two points" or "dividing a point by a scalar", or
> "adding a covariant vector to a point", or "adding a covariant
> vector to a vector".
>
>
>
> In order to enforce the decent use of the Geometrical concepts in ITK
> we organized this classes in a hierarchy that supported reuse of code
> and yet compartamentalize the behavior of the individual classes.
> The use of the "FixedArray" as base class of the "Point", the "Vector"
> and the "CovariantVector" was a design decision based on calling
> things by their correct name.
>
>
>
>
> A "FixedArray" is an enumerated collection with a fixed number
> of elements. You can instantiate a fixed array of letters, or
> a fixed array of images, or a fixed array of transforms, or a
> fixed array of geometrical shapes.
>
> Therefore, the FixedArray should only implement the functionality
> that is necesary to "access" those enumerated elements. No assumptions
> can be made at this point on any other operations required by the
> elements of the FixedArray, except the fact of having a default
> constructor.
>
>
>
> The "itkPoint" is a type that represents the spatial coordinates
> of a spatial location. Based on geometrical concepts we defined
> the valid operations of the Point class. In particular we made
> sure that no operator+() was defined between Points, and that no
> operator*( escalar ) nor operator/() scalar were defined for points.
>
>
> In other words, you could do in ITK operations such as:
>
> Vector = Point - Point
> Point += Vector
> Point -= Vector
> Point = BarycentricCombination( Point, Point )
>
>
>
> and you cannot (because you *should not*) do operation such as
>
> Point = Point * Scalar // INVALID OPERATION
> Point = Point + Point // INVALID OPERATION
> Point = Point / Scalar // INVALID OPERATION
>
>
>
>
> The "itkVector" is, by Hamilton's definition, the subtraction
> between two points. Therefore a "Vector" must satisfy the
> following basic operations:
>
>
> Vector = Point - Point
> Point = Point + Vector
> Point = Point - Vector
> Vector = Vector + Vector
> Vector = Vector - Vector
>
>
> A "Vector" object is intended to be instantiated over elements
> that support matematical operation such as addition, subtraction
> and multiplication by scalars.
>
>
>
>
> The "itkRGBPixel" type, embodies a different concept from the ones
> of Vectors in space. The RGB is a representation a human physiological
> capability to analyze visual light using three sprectral sensors.
> The RGB space *is not* a vector space. For example, negative numbers
> are
> not appropriate in a color space because they will be the equivalent of
> 'negative stimulation' on the human eye. People in colorimetry use
> negative color values as an artificial construct for color comparision
> in the sense that
>
> ColorA = ColorB - ColorC
>
> *just* as a way of saying that they can produce ColorB by combining
> ColorA and ColorB. But they are aware that (at least in emitted light)
> it is not possible to "substracts light". So when they say
>
> ColorA = ColorB - ColorC
>
> they actually mean
>
> ColorB = ColorA + ColorC
>
>
>
>
> On the other hand, when dealing with printed color and with paint
> (as opposed to emmitted light like in computer screens) the physical
> behavior of color allows for subtraction, because strictly speaking
> the objects that you see as red are those that absorb all light
> frequencies *except* those in the red section of the spectrum.
>
>
>
> The concept of addition and subtraction of colors has to be carefully
> interpreted. In fact, RGB has a different definition regarding you
> are talking about the channels associated to the three color sensors
> of the human eye, or to the three phosphors found in most computer
> screeens or to the color inks that are used for printing reproduction.
>
> See for example:
>
> http://www.drycreekphoto.com/Learn/color_spaces.htm
>
> and
>
> http://www.color.org
>
> Color spaces are usually non linear and do not even from a group.
>
>
> When you anticipate to perform the operation of "Mean" on a RGB type
> you are assuming that in the color space provides the action of finding
> a color "in the middle" of two colors, can be found by using a linear
> operation between their numerical representation. This is unfortunately
> not the case in color spaces due to the fact that they are based on
> human perception.
>
>
>
> You can of course, just ignore the "RGB color space" nature of
> the image and manage RGB images as a set of three independent
> channels.
>
> In that case, you could simply "Adapt" or "Convert" your RGB image
> into a image of itk::Vector< float, 3 > and use operations such as
> "Mean" on it.
>
>
>
>
> To summarize:
>
>
>
> 1) Color space is not a Vector space.
>
> This is the reason why the itk::RGBPixel type does not
> provide any arithmetic operations. Only Luminance is
> implemented.
>
>
>
> 2) If you are willing to disregard the physical nature of
> what R,G,B values mean, then you can simply read your
> RGB images using a type such as
>
> typedef itk::Vector< float, 3 > PixelType;
> typedef itk::Image< PixelType, 2 > ImageType;
> typedef itk::ImageFileReader< ImageType > ReaderType;
>
> and use this ImageType for instantiating the MeanImageFilter.
>
>
> Note that the result of the "Mean operation" may not be
> what you expect to be the "color in the middle" in the
> sense of human visual perception.
>
>
>
>
>
> Please let us know if you have further questions,
>
>
>
> Thanks
>
>
>
>
> Luis
>
>
>
>
>
>
>
> =====================================================================
> Bradley Lowekamp wrote:
>
>> /it.Set( static_vast<OutputPixelType>(sum * ( 1.0 /
>> double(neighbothoodSize))) );/
>> That should work too. But I think that it is an oversite that
>> NumericTraits<RGBPixel> does not have ScalarRealType.
>> With regards to the added operator to RGBPixel (and likely for
>> RGBAPixel too), I am still confused about the differences between
>> FixedArray and Vector classes. I think I read in the Software Guide
>> instances where each were used, though I can't seemed to find an
>> example of FixedArray at the moment. The Vector class provides many
>> math operators so I also don't understand why they specific pixel
>> types were not derived from the Vector class.
>> Thanks.
>> ========================================================
>> Bradley Lowekamp
>> Management Systems Designers Contractor for
>> Office of High Performance Computing and Communications
>> National Library of Medicine
>> 'blowekamp at mail.nih.gov
>> On May 18, 2005, at 9:22 AM, Miller, James V ((Research)) wrote:
>> Can you use:
>> /A better option is probably to add scalar division (by
>> a floating
>> point type) to the RGBPixel type./
>> /Jim/
>> -----Original Message-----
>> *From:* insight-users-bounces+millerjv=crd.ge.com at itk.org
>> [mailto:insight-users-bounces+millerjv=crd.ge.com at itk.org]*On
>> Behalf Of *Bradley Lowekamp
>> *Sent:* Tuesday, May 17, 2005 4:58 PM
>> *To:* insight-users at itk.org
>> *Subject:* [Insight-users] Bug with fix Mean Image Filter
>> I was trying to use mean Image Filter with RGBPixel Type. This
>> failed because this pixel type did not supported the needed
>> operator. This was the line
>> /// get the mean value/
>> /it.Set( static_vast<OutputPixelType>(sum /
>> double(neighbothoodSize)) );/
>> RGBPixels do not support the divide by scalars operator.
>> Perhaps
>> because this type may have only been designed to used with
>> unsigned chars? Any way the fix I coded up was:
>> // get the mean value/ /
>> /it.Set( static_vast<OutputPixelType>(sum *
>>
>> (1.0/NumericTraits<OutputPixelType>::
>> ScalarRealType(neighbothoodSize)))
>> );/
>> However, that didn't work because
>> NumericTraits<RGBPixel<unsigned char>> does not have a
>> ScalarRealType member, like every other numeric traits. I
>> actually am using RGBPixelType<double> but I implemented the
>> numeric traits my self.
>> Thanks.
>> ========================================================
>> Bradley Lowekamp
>> Management Systems Designers Contractor for
>> Office of High Performance Computing and Communications
>> National Library of Medicine
>> 'blowekamp at mail.nih.gov
>> ----------------------------------------------------------------------
>> --
>> _______________________________________________
>> Insight-users mailing list
>> Insight-users at itk.org
>> http://www.itk.org/mailman/listinfo/insight-users
>
>
>
>
>
More information about the Insight-users
mailing list