How to save data as binary Image in MATLAB

Hello Everyone,I hope you are doing well. I want to save the following data as Binary Image in MATLAB
Each has shape 1x1000
Can anybody help me with this?
I have tried the following Code but it does not work.
[numImages, lenImage] = size(Dataset1000);
imSz = 1000; % assuming images are 1000x1000
imbg = false(imSz); % background "color"
imfg = ~imbg(1,1); % forground "color"
imSizeOut=[1000 1000]; % ImageSize
for imNum = 1:numImages
imData = Dataset1000(imNum,:); % get pattern
[~,Y] = meshgrid(1:imSz); % make a grid
% black and white image
BW = imbg;
BW(Y==imData)=imfg;
% resize (from 1000x1000)
BW=imbinarize(imresize(uint8(BW),imSizeOut));
% convert to uint8 (0 255)
im = im2uint8(BW);
SE=strel('disk',2);
BW=imdilate(im,SE);
end

3 Comments

@KSSV I have write the image but it save as blank Image.
@KSSV The code is not working on this. can you please look whats wrong in it?

Sign in to comment.

 Accepted Answer

There's nothing to save but a black image, since the binarized image is always empty. I'm not sure what you're trying to do with the binarization comparison, but I crammed a placeholder operation in there to show that the rest can work with a bit of cleanup.
load dataset2.mat
[numImages, lenImage, ~] = size(Dataset1000);
imSizeOut=[1000 lenImage]; % i'm assuming the width is inherited
% create this outside the loop
SE = strel('disk',2);
for imNum = 1:numImages % these datasets only have one row
imData = Dataset1000(imNum,:); % get pattern
Y = 1:lenImage; % make a grid
% binarize image
% this does the same thing as before
% Y is a vector of integers from [0 1000]
% imData is a vector of FP values from approx [0 1]
% there will be no matches, and i can't guess at what you're trying to match
%BW = Y==imData; % this needs to be fixed
BW = imData > 0.99; % THIS IS JUST A PLACEHOLDER OPERATION
% resize (from 1x1000 to 1000x1000)
% this would work if you need to change both dimensions
%BW = imresize(BW,imSizeOut); % i don't think the recasting is necessary here
% but this would be much cheaper if only one dimension needs to be changed
BW = repmat(BW,[imSizeOut(1) 1]);
% since the image is binarized, the results are the same in logical and uint8
% but processing this in logical should be faster
BW = imdilate(BW,SE);
% convert to uint8 (0 255)
BW = im2uint8(BW);
end
imshow(BW)
Considering that all the information is in the vector, it'd probably be faster to do the dilation before replication/resizing. In that case, ones(1,5) would be equivalent to a r = 2 disk strel.
Saving the image with imwrite should be simple enough
imwrite(BW,sprintf('myimage_%04d.png',imNum)) % or something similar
Note that like most formats, PNG supports uint8, but it also supports logical images. If you use PNG, you wouldn't necessarily have to recast the output to uint8 if you didn't want to. Besides any convenience factor, using logical can result in a significantly smaller file size.

13 Comments

Here is the plot of the dataset tge row vector consists of shape like this, How can i save this as binary image
binary means two levels. That is not two levels so you'd need to pick a threshold, for example 0.99. Then you could do
binaryData = tge > 0.99;
which is what @DGM already told you to do, so why aren't you doing it?
Are you just trying to get a binarized image of the plot/waveform itself?
@Image Analyst i am trying but still not get a result for that
@DGM This is second option to save the plot as binary image. How can we do that? But first we need to create binary image from the dataset which has shape of 1x1000.
If you want a binary image of the figure window, then save it as a PNG image with exportgraphics. Then read it back in and convert to grayscale with rgb2gray and then to binary by thresholding or using imbinarize.
The seems like it would not give anything desireable. However despite many posts no one here seems to know what you reall want. Can you create your binary image, like in Photoshop or somewhere, and save it as a PNG file and attach it here so we can see what you want as the final output?
Do you want to include the decorations (labels, ticks, box), or do you just want the curve?
You could use exportgraphics(), but I don't have that, so I'm not going to build around it. You could use export_fig() from the File Exchange, but I'll leave that for later. In either case, you're going to have to deal with the frustrating translation between pixels and "resolution", and the apparent impossibility of reliably predicting exactly how the figure contents are going to be padded. Similar applies when trying to use saveas() or print(). Everything becomes a function of the figure geometry, your screen size, and whether the figure is in a docked state.
... or you could just use existing tools to try to beat the figure into a fixed output geometry. Given that you're trying to binarize an antialiased line that's been scaled, it should be no surprise that it won't look pretty.
load dataset3.mat
outsize = [1000 1000]; % [height width]
basepad = 20; % minimum padding around image content
% plot the thing
plot(Dataset1000,'k') % use black
% roughly fit the plot box to the image aspect ratio
% this won't be perfect, since labels are independent
ar = outsize(2)/outsize(1);
set(gca,'plotboxaspectratio',[ar 1 1]);
% capture the figure, reduce to grayscale, invert
set(gcf,'color',[1 1 1]); % this helps with binarization
outpict = frame2im(getframe(gcf));
outpict = max(outpict,[],3);
outpict = 255-outpict;
% trim off all the excess padding
outpict = outpict(any(outpict,2),any(outpict,1));
% rescale to fit within specified geometry
[h,w,~] = size(outpict);
if (w+basepad)/(h+basepad) > ar
outpict = imresize(outpict,[NaN outsize(2)-2*basepad]);
else
outpict = imresize(outpict,[outsize(1)-2*basepad NaN]);
end
% apply fixed padding as specified
outpict = padarray(outpict,[1 1]*basepad,0,'both');
% compensate for the labels by padding to enforce aspect ratio
[h,w,~] = size(outpict);
padw = (outsize - [h w])/2;
outpict = padarray(outpict,floor(padw),0,'pre');
outpict = padarray(outpict,ceil(padw),0,'post');
% binarize the output
outpict = imbinarize(outpict);
imshow(outpict)
% PNG supports logical images
imwrite(outpict,'binarizedplot.png')
Is this more what you want?
Alternatively, maybe you just want to draw the curve in a raster array without any plot decorations or hassle.
The naive approach might be something like this. This is basically nothing more than interpolation, rounding, and assignment.
load dataset3.mat
outsize = [500 500];
% rescale data to fit width, generate indices
dlen = numel(Dataset1000);
xidx = 1:outsize(2);
yidx = interp1(linspace(1,outsize(2),dlen),Dataset1000,xidx);
yidx = round(outsize(1) - (outsize(1)-1)*normalize(yidx,'range'));
idx = sub2ind(outsize,yidx,xidx);
% preallocate
outpict = false(outsize);
% assign output pixels
outpict(idx) = true;
imshow(outpict)
% PNG supports logical images
imwrite(outpict,'generatedplot.png')
That definitely plots a pixel for each x-position, but note that the points aren't connected. If you want a stroke between the points, you can do that by drawing a polyline.
load dataset3.mat
outsize = [500 500];
% rescale data to fit width, generate indices
dlen = numel(Dataset1000);
xidx = 1:outsize(2);
yidx = interp1(linspace(1,outsize(2),dlen),Dataset1000,xidx);
yidx = outsize(1) - (outsize(1)-1)*normalize(yidx,'range');
% preallocate
outpict = false(outsize);
% draw a non-aa polyline
for seg = 1:outsize(2)-1
% get coordinates
x0 = xidx(seg);
x1 = xidx(seg+1);
y0 = yidx(seg);
y1 = yidx(seg+1);
% draw this line segment
for n = 0:(1/round(sqrt((x1-x0)^2 + (y1-y0)^2))):1
xn = round(x0 +(x1 - x0)*n);
yn = round(y0 +(y1 - y0)*n);
outpict(yn,xn) = true;
end
end
imshow(outpict)
% PNG supports logical images
imwrite(outpict,'polylineplot.png')
Alternatively, the same can be done using ROI tools from IPT.
load dataset3.mat
outsize = [500 500];
% rescale data to fit width, generate indices
dlen = numel(Dataset1000);
xidx = 1:outsize(2);
yidx = interp1(linspace(1,outsize(2),dlen),Dataset1000,xidx);
yidx = outsize(1) - (outsize(1)-1)*normalize(yidx,'range');
% display a dummy image to fix geometry
imshow(false(outsize))
% create ROI object and configure
ROI = images.roi.Polyline(gca);
ROI.Position = [xidx(:) yidx(:)];
% convert to logical mask
outpict = createMask(ROI);
imshow(outpict)
% PNG supports logical images
imwrite(outpict,'polylineplot2.png')
@DGM Thanks, The last Three solutions works on dataset3.mat but when i run this on dataset1.mat it gives blank image. or the when run on the following data it does not gives any shape
dataset1 and dataset4 are constant-valued. The curve is simply a straight line at the bottom of the image.
@DGM Yes they are constant value, Is there is any modification in above code to get this line in middle or little bit above the bottom.
For cases where there's zero variance, you can do something to conditionally position the line. In reality, there's really no point preserving the line, since it contains no more information than any other horizontal line. You can literally just create a new line in the middle of the image.
load dataset4.mat
outsize = [500 500];
% rescale data to fit width, generate indices
dlen = numel(Dataset1000);
xidx = 1:outsize(2);
yidx = interp1(linspace(1,outsize(2),dlen),Dataset1000,xidx);
if range(yidx) == 0
yidx(:) = round(outsize(1)/2);
else
yidx = outsize(1) - (outsize(1)-1)*normalize(yidx,'range');
end
% display a dummy image to fix geometry
imshow(false(outsize))
% create ROI object and configure
ROI = images.roi.Polyline(gca);
ROI.Position = [xidx(:) yidx(:)];
% convert to logical mask
outpict = createMask(ROI);
imshow(outpict)

Sign in to comment.

More Answers (0)

Categories

Find more on Deep Learning Toolbox in Help Center and File Exchange

Products

Release

R2022b

Asked:

on 18 Oct 2022

Commented:

DGM
on 21 Oct 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!