Help with Hdf5Dotnet and grayscale pictures

Hi,

I'm trying to use HDF5DotNet to write some grayscale pictures provided by
special camera and saved in TIFF format. Each color component is 16 bits (
2Bytes for R, 2Bytes for G, 2Bytes for B).
I have no problem to store some INDEXED or TRUECOLOR pictures but I
have not managed
to write properly these pictures.

I created a dataset that contain the picture matrix with values between 0
and 65535. (so datatype is H5T.H5Type.NATIVE_USHORT).

i wrote attributes like:

   1. CLASS = IMAGE
   2. IMAGE_SUBCLASS = IMAGE_GRAYSCALE
   3. IMAGE_VERSION = 1.2

I need to keep the precision of the 16-bit encoding for further work but
how to view these images in HDFView with a default palette with min and max
set to [0,255].

   - A value of 0 for black color.
   - A value of 65535 for white color.

If I set all pixel values to 30 000 the picture becomes black.

If I set all pixel values to 0 the picture becomes black.

So, how can I process to make link between the 16-bit coded value and the
256-color palette ?

Here a piece of code for generating a test picture:

                ushort[,] dset_data48bit = new ushort[500, 500];
                for (int i = 0; i < 500; i++)
                {
                    for (int j = 0; j < 500; j++)
                    {

                              dset_data48bit[i, j] = 0;
                    }
                }

The "dset_data48bit" array is passed as an argument of the method make_image

//Creation of the picture

public int make_image(H5FileOrGroupId a_oFileId, string a_strImageName, int
a_width, int a_height, ushort[,] a_valeurImage)
        {
            H5DataSetId oDataSetId = null;
            int resRetour = -1;
            long[] dims = new long[IMAGE8_RANK];

            /* On initialise les dimensions de l'image */
            dims[0] = a_height;
            dims[1] = a_width;
            try
            {
                /* Make the dataset */
                oDataSetId = make_dataset_image(a_oFileId, a_strImageName,
IMAGE8_RANK, dims, H5T.H5Type.NATIVE_USHORT, a_valeurImage);

                /* Attach the CLASS attribute */
                WriteAttribute_String(oDataSetId, "CLASS", "IMAGE");

                /* Attach the VERSION attribute */
                WriteAttribute_String(oDataSetId, "IMAGE_VERSION", "1.2");

                /* Attach the IMAGE_SUBCLASS attribute */
                WriteAttribute_String(oDataSetId, "IMAGE_SUBCLASS",
"IMAGE_GRAYSCALE");

                H5DataSpaceId oDataSpaceId = null;
                H5AttributeId oAttributeId = null;
                H5DataTypeId oDataTypeId = null;

                ushort[] tBuffer = {0,65535}; // ushort limit
                long[] dimension = { 2 };

                oDataSpaceId = H5S.create_simple(1, dimension);
                oDataTypeId = H5T.copy(H5T.H5Type.NATIVE_USHORT);
                oAttributeId = H5A.create(oDataSetId, "IMAGE_MINMAXRANGE",
oDataTypeId, oDataSpaceId);
                H5A.write(oAttributeId, oDataTypeId, new
H5Array<ushort>(tBuffer));

                if (oDataSpaceId != null) H5S.close(oDataSpaceId);
                if (oAttributeId != null) H5A.close(oAttributeId);
            }
            catch { }
            finally
            {
                if (oDataSetId != null) H5D.close(oDataSetId);
            }

            return resRetour;
        }

//Creation of the DataSet for the picture
public H5DataSetId make_dataset_image(
H5FileOrGroupId a_oLocId, string a_strDataSetName, int rank, long[] dims,
H5T.H5Type a_H5Type, ushort[,] data)
        {
            H5DataSpaceId oDataSpaceId = null;
            H5DataSetId oDataSetId = null;
            H5DataTypeId oDataTypeId = null;
            try
            {
                //// Open an HDF5 file.
                //oFileId = H5F.open(strHdf5FilePath,
H5F.OpenMode.ACC_RDWR);

                // Create dataspace. Setting maximum size to NULL sets the
maximum
                // size to be the current size.
                oDataSpaceId = H5S.create_simple(rank, dims);

                if (oDataSpaceId != null)
                    oDataSetId = H5D.create(a_oLocId, a_strDataSetName,
a_H5Type, oDataSpaceId);

                oDataTypeId = H5T.copy(a_H5Type);
                // Write the data to the dataset.
                if (oDataSetId != null)
                    H5D.write(oDataSetId, oDataTypeId, new
H5Array<ushort>(data));
            }
            catch
            {

            }
            finally
            {
                if (oDataSpaceId != null) H5S.close(oDataSpaceId);
                if (oDataTypeId != null) H5T.close(oDataTypeId);
            }

            return oDataSetId;
        }

Thank you and don't hesitate to ask for additionnal informations (I'm not
fluent in english) !

This might be more of an HDFView question than an HDF5DotNet question.

The HDFView documentation

http://www.hdfgroup.org/hdf-java-html/hdfview/UsersGuide/ug06imageview.html#
ug06image

is not clear about what kind of grayscale images are supported in HDFView.

I have looked at a few 8-bit examples, but I don't have any 16-bit examples.

This might be an HDFView limitation.

Do the images look right if you divide all values by 256?

I don't see a palette definition in your code sample.

You'd have to create a palette and attach it to the image dataset

with a PALETTE attribute of type array of object reference. The

first array element refers to the default palette for the image.

G.

···

From: hdf-forum-bounces@hdfgroup.org [mailto:hdf-forum-bounces@hdfgroup.org]
On Behalf Of Rackamm
Sent: Thursday, January 26, 2012 10:34 AM
To: hdf-forum@hdfgroup.org
Subject: [Hdf-forum] Help with Hdf5Dotnet and grayscale pictures

Hi,

I'm trying to use HDF5DotNet to write some grayscale pictures provided by
special camera and saved in TIFF format. Each color component is 16 bits (
2Bytes for R, 2Bytes for G, 2Bytes for B).
I have no problem to store some INDEXED or TRUECOLOR pictures but I have not
managed to write properly these pictures.

I created a dataset that contain the picture matrix with values between 0
and 65535. (so datatype is H5T.H5Type.NATIVE_USHORT).

i wrote attributes like:

1. CLASS = IMAGE
2. IMAGE_SUBCLASS = IMAGE_GRAYSCALE
3. IMAGE_VERSION = 1.2

I need to keep the precision of the 16-bit encoding for further work but how
to view these images in HDFView with a default palette with min and max set
to [0,255].

* A value of 0 for black color.
* A value of 65535 for white color.

If I set all pixel values to 30 000 the picture becomes black.

If I set all pixel values to 0 the picture becomes black.

So, how can I process to make link between the 16-bit coded value and the
256-color palette ?

Here a piece of code for generating a test picture:

                ushort[,] dset_data48bit = new ushort[500, 500];
                for (int i = 0; i < 500; i++)
                {
                    for (int j = 0; j < 500; j++)
                    {

                              dset_data48bit[i, j] = 0;
                    }
                }

The "dset_data48bit" array is passed as an argument of the method make_image

//Creation of the picture

public int make_image(H5FileOrGroupId a_oFileId, string a_strImageName, int
a_width, int a_height, ushort[,] a_valeurImage)
        {
            H5DataSetId oDataSetId = null;
            int resRetour = -1;
            long[] dims = new long[IMAGE8_RANK];

            /* On initialise les dimensions de l'image */
            dims[0] = a_height;
            dims[1] = a_width;
            try
            {
                /* Make the dataset */
                oDataSetId = make_dataset_image(a_oFileId, a_strImageName,
IMAGE8_RANK, dims, H5T.H5Type.NATIVE_USHORT, a_valeurImage);

                /* Attach the CLASS attribute */
                WriteAttribute_String(oDataSetId, "CLASS", "IMAGE");

                /* Attach the VERSION attribute */
                WriteAttribute_String(oDataSetId, "IMAGE_VERSION", "1.2");

                /* Attach the IMAGE_SUBCLASS attribute */
                WriteAttribute_String(oDataSetId, "IMAGE_SUBCLASS",
"IMAGE_GRAYSCALE");

                H5DataSpaceId oDataSpaceId = null;
                H5AttributeId oAttributeId = null;
                H5DataTypeId oDataTypeId = null;

                ushort[] tBuffer = {0,65535}; // ushort limit
                long[] dimension = { 2 };

                oDataSpaceId = H5S.create_simple(1, dimension);
                oDataTypeId = H5T.copy(H5T.H5Type.NATIVE_USHORT);
                oAttributeId = H5A.create(oDataSetId, "IMAGE_MINMAXRANGE",
oDataTypeId, oDataSpaceId);
                H5A.write(oAttributeId, oDataTypeId, new
H5Array<ushort>(tBuffer));

                if (oDataSpaceId != null) H5S.close(oDataSpaceId);
                if (oAttributeId != null) H5A.close(oAttributeId);
            }
            catch { }
            finally
            {
                if (oDataSetId != null) H5D.close(oDataSetId);
            }

            return resRetour;
        }

//Creation of the DataSet for the picture

public H5DataSetId make_dataset_image(

H5FileOrGroupId a_oLocId, string a_strDataSetName, int rank, long[] dims,
H5T.H5Type a_H5Type, ushort[,] data)
        {
            H5DataSpaceId oDataSpaceId = null;
            H5DataSetId oDataSetId = null;
            H5DataTypeId oDataTypeId = null;
            try
            {
                //// Open an HDF5 file.
                //oFileId = H5F.open(strHdf5FilePath,
H5F.OpenMode.ACC_RDWR);

                // Create dataspace. Setting maximum size to NULL sets the
maximum
                // size to be the current size.
                oDataSpaceId = H5S.create_simple(rank, dims);

                if (oDataSpaceId != null)
                    oDataSetId = H5D.create(a_oLocId, a_strDataSetName,
a_H5Type, oDataSpaceId);

                oDataTypeId = H5T.copy(a_H5Type);
                // Write the data to the dataset.
                if (oDataSetId != null)
                    H5D.write(oDataSetId, oDataTypeId, new
H5Array<ushort>(data));
            }
            catch
            {

            }
            finally
            {
                if (oDataSpaceId != null) H5S.close(oDataSpaceId);
                if (oDataTypeId != null) H5T.close(oDataTypeId);
            }

            return oDataSetId;
        }

Thank you and don't hesitate to ask for additionnal informations (I'm not
fluent in english) !