Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Write Binary Image from Matrix

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 02:59:04

Message: 1 of 13

Hi -- I have a 2D array of ones and zeros and would like to write it as a binary bitmap. Seems simple, but I can't figure out how. What am I missing? Thanks.

Subject: Write Binary Image from Matrix

From: ImageAnalyst

Date: 29 Jan, 2010 03:11:56

Message: 2 of 13

On Jan 28, 9:59 pm, "Matt " <m...@email.com> wrote:
> Hi -- I have a 2D array of ones and zeros and would like to write it as a binary bitmap. Seems simple, but I can't figure out how. What am I missing? Thanks.
---------------------------------------------------------------------------------------------------
Matt:
You're missing the Image Processing Toolbox. In that toolbox is the
imwrite() function, which can write BMP format images in a variety of
bit depths.

BMP — Windows Bitmap
Supported Bitdepths No Compression RLE Compression Output Class Notes
1-bit x – logical
4-bit x x uint8
8-bit x x uint8
16-bit x – uint8 1 sample/pixel
24-bit x – uint8 3 samples/pixel
32-bit x – uint8 3 samples/pixel
                               (1 byte padding)

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 03:25:20

Message: 3 of 13

ImageAnalyst <imageanalyst@mailinator.com> wrote in message <0e5b2491-45b2-45d6-a684-5ec8771179ad@k19g2000yqc.googlegroups.com>...
> On Jan 28, 9:59 pm, "Matt " <m...@email.com> wrote:
> > Hi -- I have a 2D array of ones and zeros and would like to write it as a binary bitmap. Seems simple, but I can't figure out how. What am I missing? Thanks.
> ---------------------------------------------------------------------------------------------------
> Matt:
> You're missing the Image Processing Toolbox. In that toolbox is the
> imwrite() function, which can write BMP format images in a variety of
> bit depths.

Thanks for the reply -- I have the IPT, but when I just imwrite(M), where M is my matrix, the operation takes a very long time (~1 min for a 2000x1600 image). I suspect there is a better option?

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 03:37:05

Message: 4 of 13

ImageAnalyst <imageanalyst@mailinator.com> wrote in message <0e5b2491-45b2-45d6-a684-5ec8771179ad@k19g2000yqc.googlegroups.com>...
> ---------------------------------------------------------------------------------------------------
> Matt:
> You're missing the Image Processing Toolbox. In that toolbox is the
> imwrite() function, which can write BMP format images in a variety of
> bit depths.

Another thing -- when I use this method and open the resulting BMP in IrfanView, I just get a black image.

Subject: Write Binary Image from Matrix

From: ImageAnalyst

Date: 29 Jan, 2010 03:57:02

Message: 5 of 13

What is the data type? What does it say when you use the "whos"
command? It needs to be an integer not a floating point array. A
small image like that should write out in just a few seconds, not a
minute, if it were uint8. Probably your array is a double. Scale it
to 0-255 and cast it to uint8 and see if that works.

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 05:12:06

Message: 6 of 13

ImageAnalyst <imageanalyst@mailinator.com> wrote in message <160bab78-0cd4-485c-a2f3-84a1b6cb61de@h12g2000vbd.googlegroups.com>...
> What is the data type? What does it say when you use the "whos"
> command? It needs to be an integer not a floating point array. A
> small image like that should write out in just a few seconds, not a
> minute, if it were uint8. Probably your array is a double. Scale it
> to 0-255 and cast it to uint8 and see if that works.

Thanks -- good catch. My "image" was an array of doubles. That said, the command

imwrite(uint8(I),fname,'bmp');

is still generating a very large 8-bit file -- which is very slow. Can I force to write a binary image? I need to perform this operation ~100,000 times, so every second counts.

Subject: Write Binary Image from Matrix

From: ImageAnalyst

Date: 29 Jan, 2010 11:47:55

Message: 7 of 13

I don't know if it can be sped up. Writing 300 gigabytes of data will
take a long time! I doubt imwrite can be sped up any. Maybe try to
see if you can start with uint8 data earlier in the process so you
don't have to cast it, but that won't be possible if you're doing
processes that require floating point precision. Are you sure you
really need to write out 100,000 3 MB images? 3 MB for an image is
not "very large" by the way, in fact a 3 MB digital camera resolution
would be considered "small." But 100,000 of them is a LOT of images.

Subject: Write Binary Image from Matrix

From: Steve Eddins

Date: 29 Jan, 2010 12:35:31

Message: 8 of 13

Matt wrote:
> ImageAnalyst <imageanalyst@mailinator.com> wrote in message
> <0e5b2491-45b2-45d6-a684-5ec8771179ad@k19g2000yqc.googlegroups.com>...
>> On Jan 28, 9:59 pm, "Matt " <m...@email.com> wrote:
>> > Hi -- I have a 2D array of ones and zeros and would like to write it
>> as a binary bitmap. Seems simple, but I can't figure out how. What am
>> I missing? Thanks.
>> ---------------------------------------------------------------------------------------------------
>>
>> Matt:
>> You're missing the Image Processing Toolbox. In that toolbox is the
>> imwrite() function, which can write BMP format images in a variety of
>> bit depths.
>
> Thanks for the reply -- I have the IPT, but when I just imwrite(M),
> where M is my matrix, the operation takes a very long time (~1 min for a
> 2000x1600 image). I suspect there is a better option?

One point of clarification: The functions imwrite, imread, and imfinfo
are in MATLAB. They do not require Image Processing Toolbox.

About performance - on my 3.5-year-old IBM Thinkpad T60 laptop with a
slow-ish hard drive, I can write a 2000-by-1600 binary image,
represented as a logical matrix, to a BMP file in about 0.7 seconds. I
can write a 2000-by-1600 grayscale image, represented as a double
matrix, to a BMP file even faster, in about 0.2 seconds.

So I suspect that maybe something else in your code, rather than the
call to imwrite, is taking a minute. Can you post a specific code
fragment that takes a minute, and can you show us how you timed it?

---
Steve Eddins
http://blogs.mathworks.com/steve/

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 12:37:02

Message: 9 of 13

ImageAnalyst <imageanalyst@mailinator.com> wrote in message <6242984d-dfc1-48cc-a0e2-a602f913d4fa@o9g2000yqa.googlegroups.com>...
> I don't know if it can be sped up. Writing 300 gigabytes of data will
> take a long time! I doubt imwrite can be sped up any. Maybe try to
> see if you can start with uint8 data earlier in the process so you
> don't have to cast it, but that won't be possible if you're doing
> processes that require floating point precision. Are you sure you
> really need to write out 100,000 3 MB images? 3 MB for an image is
> not "very large" by the way, in fact a 3 MB digital camera resolution
> would be considered "small." But 100,000 of them is a LOT of images.

Thanks again. Yes, I agree that 3 MB is not large in relative terms. What I meant to say is that it is very large relative to the amount of information it needs to contain. My array is nominally 1600 x 2000 and contains nothing but 1s and 0s. If I could save it as a binary image, the size would be reduced by a factor of 8 -- and writing the file to disk would be much faster.

Subject: Write Binary Image from Matrix

From: ImageAnalyst

Date: 29 Jan, 2010 12:56:58

Message: 10 of 13

Matt:
Maybe you can save them as .mat files (no pun intended) if no other
program needs to read them in. I haven't used "sparse" matrices but
the capability is there in MATLAB if you want to learn about it.
Maybe that will help reduce the amount of data that actually gets
written out to the .mat file.

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 15:58:05

Message: 11 of 13

Steve Eddins <Steve.Eddins@mathworks.com> wrote in message <hjukmj$cug$1@fred.mathworks.com>...
>
> So I suspect that maybe something else in your code, rather than the
> call to imwrite, is taking a minute. Can you post a specific code
> fragment that takes a minute, and can you show us how you timed it?
>
> ---
> Steve Eddins
> http://blogs.mathworks.com/steve/

Steve -- thanks for the response. The code is shown below. Basically, I read in a text file containing the centers and radii of a bunch of circles. I populate an array with the circles, and then attempt to write it to disk. If I comment out the imwrite command, the code executes in less than a second. With the imwrite command, it takes maybe 30 seconds.

    fid = fopen([specimen,num2str(fnum(ii)),intype]);
    C = textscan(fid,'%f %f %f %f');
    fclose(fid);
    M(:,1) = C{1};
    M(:,2) = C{2};
    M(:,3) = C{3};
    C = 0;
    M = sortrows(M,2);
    [r c] = size(M);
    if (M(2,2)-M(1,2))>2*M(1,3)
        M = M(2:r,1:c);
    end
    [r c] = size(M);
    xmin = round(min(M(:,1)-M(:,3))*sf);
    xmax = round(max(M(:,1)+M(:,3))*sf);
    ymin = round(min(M(:,2)-M(:,3))*sf);
    ymax = round(max(M(:,2)+M(:,3))*sf);
    M(:,1) = round(M(:,1)*sf - xmin);
    M(:,2) = round(M(:,2)*sf - ymin);
    Rows = ymax-ymin;
    Cols = xmax-xmin;
    I = zeros(Rows,Cols);
    for jj = 1:r
        rad = M(jj,3);
        bot = ceil(Rows - M(jj,2) + rad);
        top = floor(Rows - M(jj,2) - rad)+1;
        left = floor(M(jj,1) - rad)+1;
        right = ceil(M(jj,1) + rad);
        for nn = top:bot
            for kk = left:right
                if ((kk - M(jj,1))^2+(nn-(Rows-M(jj,2)))^2)<=rad^2
                    I(nn,kk) = 1;
                end
            end
        end
        imwrite(I,[specimen,num2str(fnum(ii)),outtype],'png','bitdepth',1);
    end

NOTE: in the above code, 'sf' is a scale factor to control image size. It is currently set to 1.

Subject: Write Binary Image from Matrix

From: Matt

Date: 29 Jan, 2010 16:09:25

Message: 12 of 13

> for jj = 1:r
> rad = M(jj,3);
> bot = ceil(Rows - M(jj,2) + rad);
> top = floor(Rows - M(jj,2) - rad)+1;
> left = floor(M(jj,1) - rad)+1;
> right = ceil(M(jj,1) + rad);
> for nn = top:bot
> for kk = left:right
> if ((kk - M(jj,1))^2+(nn-(Rows-M(jj,2)))^2)<=rad^2
> I(nn,kk) = 1;
> end
> end
> end
> imwrite(I,[specimen,num2str(fnum(ii)),outtype],'png','bitdepth',1);
> end

OK, so I am an idiot. Look at the location of the imwrite command -- it's inside a loop. Thus, I am writing the image 'r' times (1633 in this case). That will teach me to code while drinking bourbon.

Thanks to all for the help.

Matt

Subject: Write Binary Image from Matrix

From: Steve Eddins

Date: 29 Jan, 2010 16:29:30

Message: 13 of 13

Matt wrote:
>> for jj = 1:r
>> rad = M(jj,3);
>> bot = ceil(Rows - M(jj,2) + rad);
>> top = floor(Rows - M(jj,2) - rad)+1;
>> left = floor(M(jj,1) - rad)+1;
>> right = ceil(M(jj,1) + rad);
>> for nn = top:bot
>> for kk = left:right
>> if ((kk - M(jj,1))^2+(nn-(Rows-M(jj,2)))^2)<=rad^2
>> I(nn,kk) = 1;
>> end
>> end
>> end
>>
>> imwrite(I,[specimen,num2str(fnum(ii)),outtype],'png','bitdepth',1);
>> end
>
> OK, so I am an idiot. Look at the location of the imwrite command --
> it's inside a loop. Thus, I am writing the image 'r' times (1633 in this
> case). That will teach me to code while drinking bourbon.

Don't worry, Matt. We've all been there! Many times.

One of the most important steps in debugging or problem-solving in
general is questioning and testing assumptions. That's what was behind
my earlier post. You posted that imwrite was slow (it took a minute).
In the spirit of questioning assumptions I said to myself, "Well, maybe
imwrite is slow, but are we sure? How do we know? Maybe it's something
else"?

The other part of what happened to you is the "cardboard cut-out"
phenomenon. It's very common that a programmer will find a bug simply
by showing the code to someone else, even if that person never says a
word. In a code review, for example, a programmer will be explaining
their code and stop in mid-sentence, scratch their head for a minute,
exclaim, "Oops! That line is wrong!" The code reviewer, who never said
a word during the whole process, might as well have been a cardboard
cut-out.

In this case, you found your own bug simply by posting it and then
reading your own post! Very common, even if there is no bourbon involved.

---
Steve Eddins
http://blogs.mathworks.com/steve/

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us