Hi, I'm new to D and having a go at writing some image processing
stuff using Vladimir's ae.graphics library.
To filter (i.e. perform correlations/convolutions) on a view with
colour type C, I'd like to perform intermediate calculations
using a colour with the same number of channels as C, but all of
type double, and then to convert back to something of type C at
the end.
e.g. for a horizontal blur I'd like to keep a running total per
channel, packaged in an all-doubles colour type, and then write
(total / kernel width) for each channel back into a value of type
C.
How do I perform the necessary type magic here? Thanks

I've done this by declaring a static array of the same length as
ViewColor!V.channels, and foreach-ing over the channels in a
colour, but this seem uglier than it need to - it would be nice
if I could just define + and = appropriately on double[] and
colours to do the right thing.
On Sunday, 18 January 2015 at 21:10:05 UTC, Phil wrote:

Hi, I'm new to D and having a go at writing some image
processing stuff using Vladimir's ae.graphics library.
To filter (i.e. perform correlations/convolutions) on a view
with colour type C, I'd like to perform intermediate
calculations using a colour with the same number of channels as
C, but all of type double, and then to convert back to
something of type C at the end.
e.g. for a horizontal blur I'd like to keep a running total per
channel, packaged in an all-doubles colour type, and then write
(total / kernel width) for each channel back into a value of
type C.
How do I perform the necessary type magic here? Thanks

Hi, I'm new to D and having a go at writing some image
processing stuff using Vladimir's ae.graphics library.
To filter (i.e. perform correlations/convolutions) on a view
with colour type C, I'd like to perform intermediate
calculations using a colour with the same number of channels as
C, but all of type double, and then to convert back to
something of type C at the end.
e.g. for a horizontal blur I'd like to keep a running total per
channel, packaged in an all-doubles colour type, and then write
(total / kernel width) for each channel back into a value of
type C.
How do I perform the necessary type magic here? Thanks

Hi Phil,
The Color template implements opCast for types with the same set
of fields, so you should be able to just cast a struct with ubyte
fields to one with double fields (or use std.conv.to). The only
restriction is that the fields must have the same order.
You can use the ChangeChannelType template to create a Color type
from an existing one but a different type for the channel fields,
for example this assert will hold:
static assert(is(ChangeChannelType!(RGB, ushort) == RGB16));
To create a view with double-typed channels from an RGB view, you
can use colorMap:
alias doubleTypedView = colorMap!(c =>
cast(ChangeChannelType!(typeof(c), double))c);
You can use this as with any other view transform:
auto i = onePixel(L8(1));
auto d = i.doubleTypedView();
assert(d[0, 0].l == 1.0);
By the way, as I've never tried using floating-point types, the
code didn't quite work with them as it is, as some templates
expected integral types in a few places. I guess you've fixed
things on your side? Anyhow, I've now pushed a commit which fixes
and adds tests for FP types.

Brilliant, thanks a lot.
That works a treat, allowing me to use c1 + c2 when c1 :: RGB and
c2 :: ChangeChannelType!(RGB, int), say.
It's not happy with doubles atm, but presumably this is sorted in
your push. Thanks again :-)
On Monday, 19 January 2015 at 21:11:34 UTC, Vladimir Panteleev
wrote:

Hi Phil,
The Color template implements opCast for types with the same
set of fields, so you should be able to just cast a struct with
ubyte fields to one with double fields (or use std.conv.to).
The only restriction is that the fields must have the same
order.
You can use the ChangeChannelType template to create a Color
type from an existing one but a different type for the channel
fields, for example this assert will hold:
static assert(is(ChangeChannelType!(RGB, ushort) == RGB16));
To create a view with double-typed channels from an RGB view,
you can use colorMap:
alias doubleTypedView = colorMap!(c =>
cast(ChangeChannelType!(typeof(c), double))c);
You can use this as with any other view transform:
auto i = onePixel(L8(1));
auto d = i.doubleTypedView();
assert(d[0, 0].l == 1.0);
By the way, as I've never tried using floating-point types, the
code didn't quite work with them as it is, as some templates
expected integral types in a few places. I guess you've fixed
things on your side? Anyhow, I've now pushed a commit which
fixes and adds tests for FP types.