1
$\begingroup$

I have binary images with an fixed sized header. These can be converted into PGM images, provided cutting the header, and putting the appropriate information using linux/OSX tools as "head -c", "tail -c", and "cat". I can later import these images in Mathematica for further treatment.

I would like to create an importer in Mathematica as treated in the documentation which could do all this so the import can be done on a Windows station without using the linux/OSX tools.

I have not been able to manage this problem.

The only Idea I had is to use the functions BinaryReadList or BinaryRead. But since the information I get with them is not the same as what I get with ImageData[Import[file, "PGM"]]. I am stuck.

The difference can be directly verified with binread-module based an answer of Sjoerd C. de Vries. And also with a little code I wrote to show the difference on readable files

    (* PGM : filename for output *)

    PGM= "/Users/thomas/Documents/Mathematica/LM.pgm";
    Dim = {25,25};
    f[x_,y_]:=2^16*E^(-(2/3) (x^2-0.5` x y+0.25` y^2));

    (* Creating now an small Image *)

    LittleMat=IntegerPart[Array[f,Dim,{{-6,6},{-6,6}}]+1];
    (*LittleMat= RandomInteger[{1,2^16},Dim];*)
    ArrayPlot[LittleMat, ImageSize->{300,300},AspectRatio->Full]

    (* Exporting and re-importing the small Image *)

    Export[PGM,Image[LittleMat,"UnsignedInteger16"],"PGM"];
    ReImp = Import[PGM,"PGM"];
    RI = IntegerPart[2^16*ImageData[ReImp]];

    ArrayPlot[RI, ImageSize->{300,300},AspectRatio->Full]

    (* Information is luckily still the same *)
    (*LittleMat-RI*)

    (* Now reading the file binary, bitwise *)

    Bytestest = FileByteCount[PGM]
    N[Bytestest /(25*25)]

    (* Why is the ImageSize in bits twice the pixel-number? *)

    HeaderL = Bytestest -2*25*25

    stream=OpenRead[PGM,BinaryFormat -> True];
    SetStreamPosition[stream,HeaderL];
    MyPGM = BinaryReadList[stream,"UnsignedInteger16",ByteOrdering->-1];
    SetStreamPosition[stream,0];
    Close[stream];

    (* MyPGM list of the same size as pixel-number *)

    PGMmat = Partition[MyPGM,25];
    ArrayPlot[PGMmat, ImageSize->{300,300},AspectRatio->Full]

    (* Information not the same aby more *)

    ArrayPlot[PGMmat-RI, ImageSize->{300,300},AspectRatio->Full]
$\endgroup$
1
  • $\begingroup$ just to answer the easy one "ImageSize in bits twice the pixel - number": the image size in bytes is twice the pixel size because you are using 16 bit / 2 byte integers. $\endgroup$
    – george2079
    Commented Sep 12, 2016 at 17:53

1 Answer 1

1
$\begingroup$

you are one byte off when you set stream position, and have the wrong byte ordering. This makes it work:

SetStreamPosition[stream, HeaderL - 1];
MyPGM = BinaryReadList[stream, "UnsignedInteger16", 
   ByteOrdering -> 1];

The combined errors happen to make every value < 256 correct, which makes the image look sort-of right. I think 16 bit PGM is always big endian regardless of your file system.

just by the way you can directly request the integer data from ImageData as:

RI = ImageData[ReImp, "Bit16"];
$\endgroup$
4
  • $\begingroup$ Thank you. Even if it looks fine, there is the center pixel which is different, and PGMmat == RI gives False. Still I would be happy with the result, if the "real life" PGM-Image would work as well, ... I should find a way to send you that small image. $\endgroup$
    – thomasS
    Commented Sep 13, 2016 at 14:28
  • $\begingroup$ For the given example : RI = ImageData[ReImp, "Bit16"]; is much better, since PGMmat == RI answers with True, but still not for the "real life" PGM-Image. For this image : Even the maximum/minimum are different ... $\endgroup$
    – thomasS
    Commented Sep 13, 2016 at 14:52
  • $\begingroup$ the 16 bit range is actually 0-(2^16-1), so you should have had IntegerPart[(2^16-1)*ImageData[ReImp]] You should have (2^16-1) in your f definition and don't add the 1 after IntegerPart and then it all works out. RI == PGMmat == LittleMat (*True*) $\endgroup$
    – george2079
    Commented Sep 13, 2016 at 15:14
  • $\begingroup$ I will put this question as answered. Maybe the "real life" sample is of different format. I put a Drop-Box Link to the sample-image. @george2079 Can you check that? Thnx $\endgroup$
    – thomasS
    Commented Sep 14, 2016 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.