Error on using movmean function -> shifted coordinates

1 view (last 30 days)
I tried using movmean and it seems to work correctly, but I get two dots almost in the middle of the screen. How come? Did I do something wrong when using movmean?
matrix = importdata('matrix.txt');
theta = 90*3;
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
c=mean(matrix,1);
Rmatrix = (matrix-c)*R'+c;
M = movmean(Rmatrix,3);
figure
plot(M(:,1), M(:,2), 'b.', 'MarkerSize', 10);
hold on
plot(Rmatrix(:,1), Rmatrix(:,2), 'r.');
hold off
axis equal
xlim([0 512]);
ylim([0 512]);
From the figure below it would appear that each coordinate belongs to a curve.
Is it possible to fix those coordinates (2 blue dots)? Or, in case it is not possible to fix them, is it possible to remove them?

Accepted Answer

DGM
DGM on 17 Dec 2022
matrix = importdata('matrix.txt');
theta = 90*3;
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
c=mean(matrix,1);
Rmatrix = (matrix-c)*R'+c;
% find jump between objects
D = diff(hypot(Rmatrix(:,1),Rmatrix(:,2)));
[~,idx] = max(D);
% insert NaN points between segments
Rmatrix = [Rmatrix(1:idx,:); [NaN NaN]; Rmatrix(idx+1:end,:)];
M = movmean(Rmatrix,3);
plot(M(:,1), M(:,2), 'b.', 'MarkerSize', 10);
hold on
plot(Rmatrix(:,1), Rmatrix(:,2), 'r.');
hold off
axis equal
xlim([0 512]);
ylim([0 512]);
  2 Comments
Alberto Acri
Alberto Acri on 17 Dec 2022
Edited: Alberto Acri on 17 Dec 2022
Okay, that's exactly what I wanted to achieve. Can you tell me how to do that for the attached matrix_1.txt as well?
I tried changing this line but did not get the desired result.
Rmatrix = [Rmatrix(1:idx,:); [NaN NaN]; Rmatrix(idx+1:idx+2,:); [NaN NaN]; Rmatrix(idx+2:end,:)];
DGM
DGM on 17 Dec 2022
matrix = importdata('matrix_1.txt');
theta = 90*3;
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
c=mean(matrix,1,'omitnan'); % <-- there are NaNs, so ignore them
Rmatrix = (matrix-c)*R'+c;
% find jump between objects
D = diff(hypot(Rmatrix(:,1),Rmatrix(:,2)));
[~,idx] = max(D);
% insert NaN points between segments
Rmatrix = [Rmatrix(1:idx,:); [NaN NaN]; Rmatrix(idx+1:end,:)];
M = movmean(Rmatrix,3);
plot(M(:,1), M(:,2), 'b.', 'MarkerSize', 10);
hold on
plot(Rmatrix(:,1), Rmatrix(:,2), 'r.');
hold off
axis equal
xlim([0 512]);
ylim([0 512]);
Of course, this only inserts NaNs at the largest jump. If there are more than two objects, you'll have to deal with that.

Sign in to comment.

More Answers (2)

the cyclist
the cyclist on 17 Dec 2022
If you look at data matrix you import, it has a discontinuity between elements 245 and 246:
matrix = readmatrix('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1234242/matrix.txt');
matrix(244:247,:)
ans = 4×2
339 97 338 97 281 347 280 348
You get those outlier points when you do the moving average across that discontinuity.
Without knowing why that discontinuity is there, I am hesitant to suggest a solution. But, you could split the data into two separate parts.

Image Analyst
Image Analyst on 17 Dec 2022
Edited: Image Analyst on 17 Dec 2022
I think here again the problem is yyour mixing up x and y with row and column. I explained this to you in your other question. If you realize that bwboundaries returns (row, column), which is (y, x) then there would be no need to do that rotation.
Here is the relevant snippet showing you the way it should be done:
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
imshow(originalImage); % Optional : show the original image again. Or you can leave the binary image showing if you want.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(binaryImage);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k}; % Get boundary for this specific blob. Data is in (row, column format), not (x, y)
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
hold off;
caption = sprintf('%d Outlines, from bwboundaries()', numberOfBoundaries);
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.

Categories

Find more on Graphics Object Properties in Help Center and File Exchange

Tags

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!