[vtkusers] bit wise operations for vtkImageData
David Gobbi
david.gobbi at gmail.com
Mon Mar 28 17:33:05 EDT 2011
Hi Jonathan,
You should write a small, stand-alone program that tests
SetJavaArray(). If it clearly demonstrates that this method
is not working, submit a bug report.
- David
On Mon, Mar 28, 2011 at 3:23 PM, Jonathan Morra <jonmorra at gmail.com> wrote:
> So after some more work, I figured out that's it definitely the setCharArray
> method that's not working.
> After testing I have realized that this works but is very slow (too slow to
> be usable)
> private void setCharArray(vtkImageData image, char[] array) {
> vtkCharArray ca = new vtkCharArray();
> ca.Initialize();
> ca.SetNumberOfValues(array.length);
> //ca.SetJavaArray(array);
> int i=0;
> for (char data : array) {
> ca.SetValue(i, data);
> ++i;
> }
> ca.Modified();
> ca.SetName("ImageScalars");
> image.GetPointData().SetScalars(ca);
> image.Update();
> }
> and this does not work (but it is fast about it's not working)
> private void setCharArray(vtkImageData image, char[] array) {
> vtkCharArray ca = new vtkCharArray();
> ca.Initialize();
> ca.SetNumberOfValues(array.length);
> ca.SetJavaArray(array);
> /*int i=0;
> for (char data : array) {
> ca.SetValue(i, data);
> ++i;
> }*/
> ca.Modified();
> ca.SetName("ImageScalars");
> image.GetPointData().SetScalars(ca);
> image.Update();
> }
> Why isn't SetJavaArray() working?
> On Mon, Mar 28, 2011 at 2:17 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>>
>> I can't see anything that is obviously wrong, but my experience
>> with Java is limited.
>>
>> - David
>>
>>
>> On Mon, Mar 28, 2011 at 2:42 PM, Jonathan Morra <jonmorra at gmail.com>
>> wrote:
>> > After playing around a little bit, I have come up with the following
>> > that's
>> > not currently working. Could you please advise me why this isn't
>> > working.
>> > Thanks
>> > put() {
>> > // Organ data contains a list of char[]
>> > final char[] storedCharArray = organData.get(imageNumber);
>> > final char[] binaryCharArray = getCharArray(binaryOrgan);
>> > int i=0;
>> > for (char binaryData : binaryCharArray) {
>> > char storedData = storedCharArray[i];
>> > if (binaryData == 0)
>> > storedData &= ~(1 << bitNumber);
>> > else
>> > storedData |= (1 << bitNumber);
>> > storedCharArray[i] = storedData;
>> > ++i;
>> > }
>> > get() {
>> > vtkImageData binaryImage = // Get blank image of correct
>> > dimensions,
>> > orientation, spacing, etc.
>> > final char[] storedCharArray = organData.get(imageNumber);
>> > final char[] binaryCharArray = getCharArray(binaryImage);
>> > int i=0;
>> > for (char storedData : storedCharArray) {
>> > binaryCharArray[i] = (char)((storedData >> bitNumber) & 1);
>> > ++i;
>> > }
>> > setCharArray(binaryImage, binaryCharArray);
>> > private void setCharArray(vtkImageData image, char[] array) {
>> >
>> > ((vtkCharArray)image.GetPointData().GetScalars()).SetJavaArray(array);
>> > }
>> > private char[] getCharArray(vtkImageData image) {
>> > vtkPointData points = image.GetPointData();
>> > vtkCharArray ca = (vtkCharArray)points.GetScalars();
>> > char[] chars = ca.GetJavaArray();
>> > return chars;
>> > }
>> >
>> > On Fri, Mar 25, 2011 at 12:48 PM, David Gobbi <david.gobbi at gmail.com>
>> > wrote:
>> >>
>> >> In python it is possible to access the VTK data arrays directly via
>> >> python's buffer interface, so that's what I use when I want to quickly
>> >> move pixel data back and forth from python to VTK. It allows me to
>> >> use a VTK array (including the one that the image uses to store its
>> >> pixels) as if it was a native python array.
>> >>
>> >> I have a feeling that the only way you will be able to rapidly do VTK
>> >> pixel operations of any kind from Java, is if someone adds a similar
>> >> feature to the Java wrappers.
>> >>
>> >> - David
>> >>
>> >>
>> >> On Fri, Mar 25, 2011 at 1:31 PM, Jonathan Morra <jonmorra at gmail.com>
>> >> wrote:
>> >> > Your understanding is correct, however I cannot
>> >> > use GetScalarComponentAsDouble and SetScalarComponentAsDouble because
>> >> > they
>> >> > are way too slow in Java. Do you have any other suggestions for how
>> >> > to
>> >> > do
>> >> > this or will I have to write it myself in C++?
>> >> >
>> >> > On Fri, Mar 25, 2011 at 12:29 PM, David Gobbi <david.gobbi at gmail.com>
>> >> > wrote:
>> >> >>
>> >> >> Hi Jonathan,
>> >> >>
>> >> >> If I understand correctly, you have several binary images with
>> >> >> exactly
>> >> >> the same dimensions. And you want to collapse them into a single
>> >> >> image, by storing a bitfield in the pixels of that image. So:
>> >> >>
>> >> >> To set bit "i" in pixel "xyz" (C++ code):
>> >> >> int a = int(image.GetScalarComponentAsDouble(x, y, z, 0));
>> >> >> a |= (1 << i);
>> >> >> image.SetScalarComponentAsDouble(x, y, z, a);
>> >> >>
>> >> >> To clear bit "i" in pixel "xyz":
>> >> >> int a = int(image.GetScalarComponentAsDouble(x, y, z, 0));
>> >> >> a &= ~(1 << i);
>> >> >> image.SetScalarComponentAsDouble(x, y, z, a);
>> >> >>
>> >> >> To test bit "i" in pixel "xyz":
>> >> >> int a = int(image.GetScalarComponentAsDouble(x, y, z, 0));
>> >> >> return ((a >> i) & 1);
>> >> >>
>> >> >> But I'm not sure if this is what you are trying to do. I didn't
>> >> >> fully
>> >> >> understand your pseudocode.
>> >> >>
>> >> >> - David
>> >> >>
>> >> >>
>> >> >>
>> >> >> On Fri, Mar 25, 2011 at 1:08 PM, Jonathan Morra <jonmorra at gmail.com>
>> >> >> wrote:
>> >> >> > I'm in Java and storing a large number of binary vtkImageData's.
>> >> >> > I
>> >> >> > know
>> >> >> > this is inefficient, and am searching for a better way to store
>> >> >> > them.
>> >> >> > Right
>> >> >> > now I have a hash of the vtkImageData's and a get/put function.
>> >> >> > Basically I
>> >> >> > want to mimic this get/put but with better storage. I was
>> >> >> > thinking
>> >> >> > one
>> >> >> > way
>> >> >> > to do this is to use bitwise logical operations to store the
>> >> >> > information
>> >> >> > in
>> >> >> > the binary masks. For instance, if we have 2 binary images, then
>> >> >> > we
>> >> >> > could
>> >> >> > store that information in 1 vtkImageData using the following
>> >> >> > pseudo
>> >> >> > code.
>> >> >> > private static final int IMAGE1_BIT_CHANNEL = 0;
>> >> >> > private static final int IMAGE2_BIT_CHANNEL = 1;
>> >> >> > private vtkImageData storedImage;
>> >> >> > vtkImageData get(String image) {
>> >> >> > int channel = image eq "image1" ? IMAGE1_BIT_CHANNEL :
>> >> >> > IMAGE2_BIT_CHANNEL;
>> >> >> > vtkImageData return = new vtkImageData();
>> >> >> > foreach (pixel in storedImage)
>> >> >> > if (pixel at bit channel)
>> >> >> > return[pixel] = 1;
>> >> >> > else
>> >> >> > return[pixel] = 0;
>> >> >> > return return;
>> >> >> > }
>> >> >> > void put(String image, vtkImageData binaryImage) {
>> >> >> > int channel = image eq "image1" ? IMAGE1_BIT_CHANNEL :
>> >> >> > IMAGE2_BIT_CHANNEL;
>> >> >> > foreach (pixel in binaryImage)
>> >> >> > if (pixel)
>> >> >> > storedImage at bit in channel = 1;
>> >> >> > else
>> >> >> > storedImage at bit in channel = 0;
>> >> >> > }
>> >> >> > This could be extended easily for 8 channels for a char image for
>> >> >> > instance.
>> >> >> > This operation would have to be very fast though cause it is done
>> >> >> > often
>> >> >> > on
>> >> >> > the UI thread.
>> >> >> > 1. Is there a way to do this in VTK with Java?
>> >> >> > 2. Is this the best scheme for accomplishing my goal?
>> >> >> > 3. Is there a better scheme for doing this?
>> >> >> > Thanks.
>> >> >> > _______________________________________________
>> >> >> > Powered by www.kitware.com
>> >> >> >
>> >> >> > Visit other Kitware open-source projects at
>> >> >> > http://www.kitware.com/opensource/opensource.html
>> >> >> >
>> >> >> > Please keep messages on-topic and check the VTK FAQ at:
>> >> >> > http://www.vtk.org/Wiki/VTK_FAQ
>> >> >> >
>> >> >> > Follow this link to subscribe/unsubscribe:
>> >> >> > http://www.vtk.org/mailman/listinfo/vtkusers
>> >> >> >
>> >> >> >
>> >> >
>> >> >
>> >
>> >
>
>
More information about the vtkusers
mailing list