2012-04-02 312 views
2

該程序當前輸入硬幣的圖像,對其進行閾值處理,對其進行二值化處理,並使用regionprops函數查找分段橢圓的長軸和短軸長度。我如何輸出一個繪製用於計算原始圖像上的'MajorAxisLength'和'MinorAxisLength'軸的子圖?在MATLAB中繪製橢圓對象的主軸和副軸

我附上了我的代碼,供您細讀。

% 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; 

回答

5

我和你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

+1

感謝您撰寫所有這些,這正是我所尋找的幫助。 – mg6011 2012-04-03 20:19:47

0

一般一個做它與計算本徵向量,因爲下「實例」的維基百科文章Image moment中說明。這將是正確的方法。

但我想知道,如果您知道MATLAB的質心和邊界框,那麼主軸的終點必須位於左上角或右上角。因此,檢查(除了噪音)這兩個角落,如果有像素,會給你長軸。次軸相對於質心恰好正交於它。

抱歉沒有準備好MATLAB代碼。

的理由是不是錯,但不是那麼好或者使用取向上面寫得;)

+0

我感謝您抽出寶貴的時間給我一些輸入。 – mg6011 2012-04-03 20:18:36

3

看的Orientation的屬性,regionprops()可以返回到您的文檔。

這給出了正x軸與橢圓長軸之間的角度。您應該能夠根據該角度推導長軸線的方程,然後製作一個x軸點的網格,並計算網格中所有點的長軸線的值,然後將其繪製出來就像你會在MATLAB中繪製任何其他曲線一樣。

要對短軸進行相同操作,只需注意它將從主軸逆時針旋轉90度,然後重複上述步驟。

+0

偉大的職位,感謝您的意見。 – mg6011 2012-04-03 20:20:24

+0

如果我的回答或上面更詳細的答案確實提供了幫助,請考慮對他們進行upvoting(單擊左側的向上箭頭)以表示他們有幫助。 – ely 2012-04-03 20:31:32

+0

不幸的是,我還沒有獲得升級所需的聲望。 – mg6011 2012-04-03 21:10:42