How to create a Binary image from two columns of raw data

Hello, I have the following dataset, which consists of two columns. I have also attached a scatter plot of the dataset, where first column is on x axis and 2nd column is on y axis.
I want to create a Binary image for the dataset.
How can i do it in MATLAB

답변 (3개)

DGM
DGM 2022년 11월 2일
This is similar to the prior answer, but in this case, we need to deal with scaling both x and y data.
load matlab.mat
outsize = [500 500];
% rescale data to fit width, generate indices
dlen = size(pdw,1);
x0 = pdw(:,1);
y0 = pdw(:,2);
x0 = (outsize(2)-1)*normalize(x0,'range') + 1;
xidx = 1:outsize(2);
yidx = interp1(x0,y0,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)
Note that strokes are drawn across any periods where there are no samples being taken.
The same configuration of xidx,yidx would work with the rudimentary non-aa polyline example given in that same thread.

댓글 수: 12

@DGM But in this case the shape of the data is change and strokes is not suitable for the dataset
If you just want to ignore the x-spacing of the data, then:
load matlab.mat
blocksize = [500 1000];
% rescale data to fit width, generate indices
dlen = size(pdw,1);
outwidth = ceil(dlen/blocksize(2))*blocksize(2);
outsize = [blocksize(1) outwidth];
y0 = pdw(:,2);
xidx = (1:dlen)';
yidx = round(outsize(1) - (rescale(y0,1,outsize(1))-1));
% create image
lidx = sub2ind(outsize,yidx,xidx);
outpict = false(outsize);
outpict(lidx) = true;
% reshape image into a multipage array
outpict = reshape(outpict,blocksize(1),blocksize(2),[]);
% just show the first frame
imshow(outpict(:,:,1))
% save the output frames
for f = 1:size(outpict,3)
fname = sprintf('mypicture_%04d.png',f);
imwrite(outpict(:,:,f),fname)
end
Since the full image is being split into blocks, its width is 14000px, but the data trace only extends 13215px.
@DGM some shape are changes like the signal half in one image and half in other image.
is there is any solution for this problem?
Yes, some of the features are split across images. That's because each image is 1000px wide. The data segments representing captured features aren't a fixed width. They won't align with the images, nor will they generally fit within the images if the data is represented as 1px per sample.
load matlab.mat
plot(pdw(:,1))
% the locations of large jumps in the data
x = find(diff(pdw(:,1))>100E3)
x = 6×1
2556 4029 6482 12525 12939 13022
% the segment lengths are typically wider than the images
[x(1); diff(x)]
ans = 6×1
2556 1473 2453 6043 414 83
@DGM if we dont implement image of 1000 samples. just save the image which have larger jumps and some shape?
You mean like this? This attempts to segment the data into blocks and plot each segment in its own image at 1px/sample. All the images are the same height, but different widths.
load matlab.mat
% the locations of large jumps in the data
xjumps = [1; find(diff(pdw(:,1))>100E3); size(pdw,1)];
nblocks = numel(xjumps)-1;
for k = 1:nblocks
% get this block
blockx = pdw(xjumps(k)+1:xjumps(k+1),1);
blocky = pdw(xjumps(k)+1:xjumps(k+1),2);
% output image width depends on segment size
outsize = [500 numel(blockx)];
% rescale data to fit width, generate indices
xidx = round(rescale(blockx,1,outsize(2)));
yidx = round(rescale(blocky,1,outsize(1)));
yidx = outsize(1) - yidx + 1;
% create image
lidx = sub2ind(outsize,yidx,xidx);
outpict = false(outsize);
outpict(lidx) = true;
fname = sprintf('signalfeature_%04d.png',k);
imwrite(outpict,fname)
end
@DGM Forget about dividing it into smaller image.
I want to create image in which x axis equal to length of the vector. in this dataset i have length of 13215
Okies.
load matlab.mat
% rescale data to fit width, generate indices
dlen = size(pdw,1);
blocksize = [500 dlen];
outwidth = ceil(dlen/blocksize(2))*blocksize(2);
outsize = [blocksize(1) outwidth];
y0 = pdw(:,2);
xidx = (1:dlen)';
yidx = round(outsize(1) - (rescale(y0,1,outsize(1))-1));
% create image
lidx = sub2ind(outsize,yidx,xidx);
outpict = false(outsize);
outpict(lidx) = true;
imwrite(outpict,'superwidepict.png')
| want to create image in which x axis equal to length of the vector. in this dataset i have length of 13215
Do you want to ignore the fact that the x spacing in your vector is irregular, and just put each y value one pixel to the right of the previous one, as if the x were all consecutive?
Do you want to use the length of your data as the number of pixels wide for the image, but to scale the image column coordinates according to the actual x values, so some columns end up representing multiple x values and some columns end up representing no x values?
@Walter Roberson How x spacing of vector is irregular?
the first column should be on x axis and 2nd column on y axis.
@DGM Did we able to find values from image as on original dataset?
If you knew what the original range of y had been, you might recover the y-data with a resolution determined by the height of the image. All the actual x-data will be lost. It's merely one dot per sample. Any jumps in x are not represented by the image.
Of course, I don't know why you would be wanting to recover the data from the image. Even if the issue with the nonuniform x-data weren't the case, you'd still be losing information in converting it to a raster image.
% you have an output image
inpict = imread('superwidepict.png');
% and a limited-precision stored reference to the original data range
y0range = [1.41351e-05 0.00327854];
% you can recover the y-position of each dot
[yidx,~] = find(inpict);
% you can rescale to data units
yrec = y0range(2) - rescale(yidx,0,range(y0range));
% compare to the original data
load matlab.mat
y0 = pdw(:,2);
% compare original and recovered data
xl = [1830 3196]; % look at a closeup
yl = [0.0061 0.2693]*1E-3;
subplot(2,1,1)
plot(y0); xlim(xl); ylim(yl)
subplot(2,1,2)
plot(yrec); xlim(xl); ylim(yl)
% plot the error
plot(y0-yrec)

댓글을 달려면 로그인하십시오.

Image Analyst
Image Analyst 2022년 11월 2일
What do you want the size of this image to be in pixels? How many rows and columns?
s = load('matlab1.mat')
xy = s.pdw;
x = xy(:, 1);
y = xy(:, 2);
subplot(2, 1, 1);
plot(x, y, 'b.', 'MarkerSize', 10);
grid on;
% Define the size of the image you want
rows = 512;
columns = 1500;
% Rescale data
x = rescale(x, 1, columns);
y = rescale(y, 1, rows);
binaryImage = false(rows, columns);
for k = 1 : length(x)
row = rows - round(y(k)) + 1;
col = round(x(k));
binaryImage(row, col) = true;
end
subplot(2, 1, 2);
imshow(binaryImage);

댓글 수: 6

@Image Analyst The size should be equal to the length of the vector.
Can we create multiple image from dataset? for example my dataset has shape 13215x2.
We can create of image for every 1000 values.
so there will be 14 images as output?
You realize that creating an image that's 1px per sample is essentially asking to discard all the xdata in a set where xdata is not uniformly-spaced, right?
The size should be equal to the length of the vector.
We can create of image for every 1000 values.
Do I understand correctly that you want to break up the data into sections of 1000 values, and you want the image produced for that segment to be 1000 pixels wide, even though the x data is not regularly spaced? So some x coordinates will have no data at them, and other x coordinates will have several datapoints at them, and the x span of each of the 14 plots will be different from each other, depending on how much x range the 1000 values just happened to cover ??
@Walter Roberson @DGM Yes i want to break up data into 1000 values and create image from dataset.
But is there is any method to save the image which only consists of shapes(white pixels) that will be better apporach.
The comment I posted on my answer above generates 14 images, each 1000px wide, rendering 1px per datapoint (i.e. not a polyline)
Let's step back and ask WHY you want 1000 binary images, or even one binary image from your data? I see no need for it, and you haven't given any reason - you just said that you want that but with no justification. What do the original coordinates represent in reality?

댓글을 달려면 로그인하십시오.

Walter Roberson
Walter Roberson 2022년 11월 2일
filename = 'matlab.mat';
datastruct = load(filename, 'pdw');
pdw = datastruct.pdw;
targetsize = [930 1860]; %rows, columns
margin = 5;
scaled_x = rescale(pdw(:,1), margin+1, targetsize(2)-margin);
scaled_y = rescale(pdw(:,2), margin+1, targetsize(1)-margin);
canvas = zeros(targetsize(1), targetsize(2), 3, 'uint8');
r = 3;
xyr = [scaled_x, scaled_y, r * ones(size(scaled_x))];
canvas = insertShape(canvas, 'circle', xyr, 'Color','white');
binary = canvas(:,:,1) > 0;
%verify
imshow(flipud(binary))
Except for the imshow() at the end, none of this requires the graphics system or creating any files.

댓글 수: 2

DGM
DGM 2022년 11월 2일
편집: DGM 2022년 11월 2일
FWIW, it does require CVT.
Not that I'm in any position to object, since I got lazy and used IPT ROI tools. Still, the linked comment has a polyline implementation that does not. I suppose even imshow() is an IPT dependency depending on version.
I suppose I could've simplified the rescaling though.
(CVT means Computer Vision Toolbox in this context, and IPT means Image Processing Toolbox)

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Convert Image Type에 대해 자세히 알아보기

제품

릴리스

R2022b

질문:

2022년 11월 2일

댓글:

2022년 11월 9일

Community Treasure Hunt

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

Start Hunting!

Translated by