Re: Change Channel names
Peter Hillman <[email protected]> Tue, 15 Dec 2015 20:03:39 +1300
| Newsgroups | gmane.comp.video.openexr.user |
|---|---|
| Message-ID | <[email protected]> |
--===============5671068383254460130==
Content-Type: multipart/alternative;
boundary="------------090705020307060409050401"
--------------090705020307060409050401
Content-Type: text/plain; charset="utf-8"; format=flowed
Content-Transfer-Encoding: 7bit
You could maybe extend the Image class using something like this pseudocode.
The ImageChannel class returns aslice() object that stores the image
layout: you can use that to access the pixels.
And by pseudocode I mean "untested C++":
template <classT>
void
TypedImageChannel<T>::operator+=(const TypedImageChannel<T> &other)
{
assert(image() == other.image());
IMF::Slice outSlice = slice();
IMF::Slice inSlice = other.slice();
assert(outSlice.xSampling == 1);
assert(outSlice.ySampling == 1);
assert(inSlice.xSampling == 1);
assert(inSlice.ySampling == 1);
for ( int y = image().dataWindow().min.y ; y <=
image().dataWindow().max.y ; ++y)
{
for( int x = image().dataWindow().min.x ; x <=
image().dataWindow().max.x; ++x)
{
* (T*) (outSlice.base + y*outSlice.yStride +
x*outSlice.xStride) += * (T*) (inSlice.base + y*inSlice.yStride +
x*inSlice.xStride);
}
}
}
You should then be able to merge channels by doing
image.typedChannel<half>(outChanName)+=image.typedChannel<half>(inChanName);
for each channel inChanName you want to add into outChanName before you
write out the image again, and assuming your channels are stored as half
floats.
I'm not sure if that's exactly what you need, but the nested 'for' loops
should give you an idea how to iterate over the pixels.
If you expect the tool to get more complex than this it may be worth
using a generic image processing library which supports OpenEXR instead.
On 14/12/15 23:47, Aaron Carlisle wrote:
>
> You're awesome! Ill work with this today, and see where I get.
>
> In addition to changing the channel names I also wanted to be able to
> combine the channel data from the rgb channels from each layer into
> one. In python I just created a dictionary, grouped the rgb channels
> and used array to convert them. So (customlayer.red
> <http://customlayer.red>, customlayer.blue <http://customlayer.blue>,
> customlayer.green <http://customlayer.green>) became
> (newlayername.customchannelname(combined pixel data from red, green,
> blue)). In C++ it doesn't seem seem as simple. Do you have any
> suggestions for doing the same in C++?
>
> Thanks again!!
>
> On Dec 13, 2015, at 8:48 PM, Peter Hillman <[email protected]
> <mailto:[email protected]>> wrote:
>
> You cannot modify a channel name because the ChannelList object
> keeps them sorted. If you wish to rename a channel within a list,
> you must delete it and reinsert it with the new name, or else
> assemble a completely new ChannelList containing the channels the
> way you want.
>
> You may find the source of the multiview utility instructive:
> https://github.com/openexr/openexr/blob/master/OpenEXR/exrmultiview/makeMultiView.cpp
>
> That reads in channels from the input(s) and writes them out with
> different names.
> You could drop a channel from the output file by making these two
> lines conditional:
> header. channels (). insert (outChanName, inChannel);
> and
> outFb. insert (outChanName,image. channel (outChanName). slice ());
>
>
>
> On 12/12/15 08:02, Aaron Carlisle wrote:
>> In the ChannelList::Iterator and ChannelList::ConsIterator name()
>> is being defined as a const char * name () const, which means I
>> can't change the name. Is there anyway around this? I just want
>> to be able to change the channel name. I tried converting name
>> into a string then back into a const char * which works, but I
>> have significant data loss and the pixels no longer show up in
>> the image.
>>
>>
>> _______________________________________________
>> Openexr-user mailing list
>> [email protected]
>> https://lists.nongnu.org/mailman/listinfo/openexr-user
>
>
> ------------------------------------------------------------------------
>
> Openexr-user mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/openexr-user
>
--------------090705020307060409050401
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: 8bit
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
You could maybe extend the <tt>Image</tt> class using something
like this pseudocode.<br>
The <tt>ImageChannel</tt> class returns a<tt> slice()</tt> object
that stores the image layout: you can use that to access the pixels.<br>
And by pseudocode I mean "untested C++":<br>
<br>
<tt><span class="pl-k">template </span></tt><tt><</tt><tt><span
class="pl-k">class</span></tt><tt> </tt><tt><span class="pl-en">T</span></tt><tt>></tt><tt><span
class="pl-k"><br>
void<br>
T</span></tt><tt>ypedImageChannel<T>::operator+=(</tt><tt><span
class="pl-k">const T</span></tt><tt>ypedImageChannel<T>
&other)</tt><tt><br>
</tt><tt>{</tt><tt><br>
</tt><tt><br>
</tt><tt> assert(image() == other.image());</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt> IMF::Slice outSlice = slice();</tt><tt><br>
</tt><tt> IMF::Slice inSlice = other.slice();</tt><tt><br>
</tt><tt><br>
</tt><tt> assert(outSlice.xSampling == 1);</tt><tt><br>
</tt><tt> assert(outSlice.ySampling == 1);</tt><tt><br>
</tt><tt> assert(inSlice.xSampling == 1);</tt><tt><br>
</tt><tt> assert(inSlice.ySampling == 1);</tt><tt><br>
</tt><tt><br>
</tt><tt> for ( int y = image().dataWindow().min.y ; y <=
image().dataWindow().max.y ; ++y)</tt><tt><br>
</tt><tt> {</tt><tt><br>
</tt><tt> for( int x = image().dataWindow().min.x ; x <=
image().dataWindow().max.x; ++x)</tt><tt><br>
</tt><tt> {</tt><tt><br>
</tt><tt> * (T*) (outSlice.base + y*outSlice.yStride +
x*outSlice.xStride) += * (T*) (inSlice.base + y*inSlice.yStride +
x*inSlice.xStride);</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt>}</tt><tt><br>
</tt><br>
You should then be able to merge channels by doing<br>
<tt>image.typedChannel<half>(outChanName)+=image</tt><tt><tt>.typedChannel<half></tt>(inChanName);</tt><br>
for each channel inChanName you want to add into outChanName before
you write out the image again, and assuming your channels are stored
as half floats.<br>
I'm not sure if that's exactly what you need, but the nested 'for'
loops should give you an idea how to iterate over the pixels.<br>
<br>
If you expect the tool to get more complex than this it may be worth
using a generic image processing library which supports OpenEXR
instead.<br>
<br>
<br>
<br>
<br>
<div class="moz-cite-prefix">On 14/12/15 23:47, Aaron Carlisle
wrote:<br>
</div>
<blockquote
cite="mid:[email protected]"
type="cite">
<p dir="ltr">You're awesome! Ill work with this today, and see
where I get. </p>
<p dir="ltr">In addition to changing the channel names I also
wanted to be able to combine the channel data from the rgb
channels from each layer into one. In python I just created a
dictionary, grouped the rgb channels and used array to convert
them. So (<a moz-do-not-send="true"
href="http://customlayer.red">customlayer.red</a>, <a
moz-do-not-send="true" href="http://customlayer.blue">customlayer.blue</a>,
<a moz-do-not-send="true" href="http://customlayer.green">customlayer.green</a>)
became (newlayername.customchannelname(combined pixel data from
red, green, blue)). In C++ it doesn't seem seem as simple. Do
you have any suggestions for doing the same in C++?</p>
<p dir="ltr">Thanks again!!<br>
<br>
</p>
<div class="gmail_quote">On Dec 13, 2015, at 8:48 PM, Peter
Hillman <<a moz-do-not-send="true"
href="mailto:[email protected]" target="_blank">[email protected]</a>>
wrote:
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
0.8ex; border-left: 1px solid rgb(204, 204, 204);
padding-left: 1ex;"> You cannot modify a channel name because
the ChannelList object keeps them sorted. If you wish to
rename a channel within a list, you must delete it and
reinsert it with the new name, or else assemble a completely
new ChannelList containing the channels the way you want. <br>
<br>
You may find the source of the multiview utility instructive:
<br>
<tt><a moz-do-not-send="true" class="moz-txt-link-freetext"
href="https://github.com/openexr/openexr/blob/master/OpenEXR/exrmultiview/makeMultiView.cpp">https://github.com/openexr/openexr/blob/master/OpenEXR/exrmultiview/makeMultiView.cpp</a></tt>
<br>
That reads in channels from the input(s) and writes them out
with different names. <br>
You could drop a channel from the output file by making these
two lines conditional: <br>
<tt>header.</tt> <tt><span class="pl-c1">channels</span></tt>
<tt>().</tt> <tt><span class="pl-c1">insert</span></tt> <tt>
(outChanName, inChannel); </tt> <br>
and <br>
<tt>outFb.</tt> <tt><span class="pl-c1">insert</span></tt> <tt>
(outChanName,image.</tt> <tt><span class="pl-c1">channel</span></tt>
<tt>(outChanName).</tt> <tt><span class="pl-c1">slice</span></tt>
<tt>());</tt> <br>
<br>
<br>
<br>
<div class="moz-cite-prefix"> On 12/12/15 08:02, Aaron
Carlisle wrote: <br>
</div>
<blockquote
cite="mid:CADwEHsO24VMfQcUausakqRtO7uQPm-kshDDoFjLe+hwaxXu0xg@mail.gmail.com"
type="cite">
<div dir="ltr"> In the ChannelList::Iterator and
ChannelList::ConsIterator name() is being defined as a
const char * name () const, which means I can't change the
name. Is there anyway around this? I just want to be able
to change the channel name. I tried converting name into a
string then back into a const char * which works, but I
have significant data loss and the pixels no longer show
up in the image. </div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
Openexr-user mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="https://lists.nongnu.org/mailman/listinfo/openexr-user">https://lists.nongnu.org/mailman/listinfo/openexr-user</a>
</pre>
</blockquote>
<br>
<pre class="blue"> <hr>
Openexr-user mailing list
<a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
<a moz-do-not-send="true" href="https://lists.nongnu.org/mailman/listinfo/openexr-user">https://lists.nongnu.org/mailman/listinfo/openexr-user</a>
</pre></blockquote></div>
</blockquote>
</body></html>
--------------090705020307060409050401--
--===============5671068383254460130==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Openexr-user mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/openexr-user
--===============5671068383254460130==--