Рисование большой и малой оси эллиптического объекта в MATLAB - PullRequest
2 голосов
/ 03 апреля 2012

Эта программа в настоящее время вводит изображение монеты, порождает его, преобразует в двоичную форму и находит длину главной и вспомогательной осей сегментированного эллиптика, используя функцию regionprops . Как вывести подзаговор, где я рисую оси, используемые для вычисления 'MajorAxisLength' и 'MinorAxisLength' по исходному изображению?

Я добавил свой код для вашего прочтения.

% Read in the image.
folder = 'C:\Documents and Settings\user\My Documents\MATLAB\Work';
baseFileName = 'coin2.jpg';
fullFileName = fullfile(folder, baseFileName);
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
    fullFileName = baseFileName; % No path this time.
    if ~exist(fullFileName, 'file')
        %Alert user.
        errorMessage = sprintf('Error: %s does not exist.', fullFileName);
        uiwait(warndlg(errorMessage));
        return;
    end
end

rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 3, 1);
imshow(rgbImage, []);
title('Original color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Position', get(0,'Screensize'));

% Extract the individual red color channel.
redChannel = rgbImage(:, :, 1);
% Display the red channel image.
subplot(2, 3, 2);
imshow(redChannel, []);
title('Red Channel Image', 'FontSize', fontSize);
% Binarize it
binaryImage = redChannel < 100;
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage, []);
title('Thresholded Image', 'FontSize', fontSize);

binaryImage = imfill(binaryImage, 'holes');
labeledImage = bwlabel(binaryImage);

area_measurements = regionprops(labeledImage,'Area');
allAreas = [area_measurements.Area];
biggestBlobIndex = find(allAreas == max(allAreas));
keeperBlobsImage = ismember(labeledImage, biggestBlobIndex);
measurements = regionprops(keeperBlobsImage,'MajorAxisLength','MinorAxisLength')

% Display the original color image with outline.
subplot(2, 3, 4);
imshow(rgbImage);
hold on;
title('Original Color Image with Outline', 'FontSize',fontSize);
boundaries = bwboundaries(keeperBlobsImage);
blobBoundary = boundaries{1};
plot(blobBoundary(:,2), blobBoundary(:,1), 'g-', 'LineWidth', 1);
hold off;

Ответы [ 3 ]

5 голосов
/ 03 апреля 2012

У меня была та же задача, что и у вас, в каком-то проекте, который я делал 2 года назад. Я изменил код, который использовал для вас ниже. Он включал вычисление ковариационной матрицы для точек данных и нахождение их собственных значений / собственных векторов. Обратите внимание, что из-за круговой симметрии малая и большая оси будут несколько «случайными». Также обратите внимание, что я сделал бинарный образ очень наивным способом, чтобы сделать код простым.

% Load data and make bw
clear all;close all; clc; 
set(0,'Defaultfigurewindowstyle','docked')

I = imread('american_eagle_gold_coin.jpg');
Ibw = im2bw(I,0.95);
Ibw = not(Ibw);

figure(1);clf
imagesc(Ibw);colormap(gray)

%% Calculate axis and draw

[M N] = size(Ibw);
[X Y] = meshgrid(1:N,1:M);

%Mass and mass center
m = sum(sum(Ibw));
x0 = sum(sum(Ibw.*X))/m;
y0 = sum(sum(Ibw.*Y))/m;

%Covariance matrix elements
Mxx = sum(sum((X-x0).^2.*Ibw))/m;
Myy = sum(sum((Y-y0).^2.*Ibw))/m;
Mxy = sum(sum((Y-y0).*(X-x0).*Ibw))/m;

MM = [Mxx Mxy; Mxy Myy];

[U S V] = svd(MM);

W = V(:,1)/sign(V(1,1)); %Extremal directions (normalized to have first coordinate positive)
H = V(:,2);
W = 2*sqrt(S(1,1))*W; %Scaling of extremal directions to give ellipsis half axis
H = 2*sqrt(S(2,2))*H;

figure(1)
hold on
    plot(x0,y0,'r*');
    quiver(x0,y0,W(1),H(1),'r')
    quiver(x0,y0,W(2),H(2),'r')
hold off

Original image Axis found from binary image enter image description here

3 голосов
/ 03 апреля 2012

Посмотрите документацию для атрибута Ориентация , который regionprops() может вам вернуть.

Это дает угол между положительной осью X и главной осью эллипса.Вы должны быть в состоянии вывести уравнение для линии большой оси в терминах этого угла, а затем просто создать сетку из точек оси X и вычислить значение линии главной оси для всех точек в вашей сетке, а затем просто построить егокак вы бы построили любую другую кривую в MATLAB .

Чтобы сделать то же самое для малой оси, просто обратите внимание, что она будет на 90 градусов дальше против часовой стрелки от большой оси, затем повторитешаг выше.

0 голосов
/ 03 апреля 2012

Обычно это делается с помощью вычисления собственных векторов, как описано в статье в Википедии Момент изображения в разделе «Примеры».Это был бы правильный путь.

Но мне интересно, если вы знаете центроид и ограничивающую рамку из MATLAB, то конечная точка большой оси должна находиться в верхнем левом или верхнем правом углу.Поэтому проверка (кроме шума) этих двух углов, если есть пиксель, даст вам большую ось.В этом случае вспомогательная ось является ортогональной к ней относительно центроида.

Извините за то, что код MATLAB не готов.

Рассуждения не так уж и неправильны, но и не так хороши, используяориентация, как написано выше, лучше;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...