2017-05-25 231 views
0

如何使用matlab从视网膜图像检测视杯和光盘?我想找出视神经边缘matlab中的图像处理(分割)

Click here to See the Sample Image that need to be processed

我曾尝试下面的代码

RGB = imread('img/A(4).jpg'); 
G = DialateBloodVessel(RGB); 
[BW,H] = RGBThresh(G,220,60); 
H = H(:,:,3); 
I = edge(H,'Roberts',0.1); 
imshowpair(I,G); 

%%%%%%%%%% DialateBloodVessel(RGB) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
function [ RemovedBV ] = DialateBloodVessel(RGB) 
%UNTITLED3 Summary of this function goes here 
% Detailed explanation goes here 
IM = RGB; 
SE = strel('disk',10); 
IM2 = imdilate(IM,SE); 
%SE2 = strel('disk',10); 
RemovedBV = imerode(IM2,SE); 
end 

%%%%%%%%%% RGBThresh(RGB,Ch1,Ch3) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

function [BW,maskedRGBImage] = RGBThresh(RGB,Ch1,Ch3) 
I = RGB; 

% Define thresholds for channel 1 based on histogram settings 
channel1Min = Ch1; 
channel1Max = 255.000; 

% Define thresholds for channel 2 based on histogram settings 
channel2Min = 0.000; 
channel2Max = 185.000; 

% Define thresholds for channel 3 based on histogram settings 
channel3Min = Ch3; 
channel3Max = 255.000; 

% Create mask based on chosen histogram thresholds 
sliderBW = (I(:,:,1) >= channel1Min) & (I(:,:,1) <= channel1Max) & ... 
    (I(:,:,2) >= channel2Min) & (I(:,:,2) <= channel2Max) & ... 
    (I(:,:,3) >= channel3Min) & (I(:,:,3) <= channel3Max); 
BW = sliderBW; 

% Initialize output masked image based on input image. 
maskedRGBImage = RGB; 

% Set background pixels where BW is false to zero. 
maskedRGBImage(repmat(~BW,[1 1 3])) = 0; 

end 

我得到下面的输出(视杯和视盘之间的距离)的测量,但我需要完美的圆在任何图像:

enter image description here

+0

我试图霍夫变换获取了圈,也试过颜色阈值,但两者时间我得到不想要的输出。 –

+0

我已更新代码,只需看一下 –

+0

如何在此处上传文件? –

回答

0

当我看着你的形象,我发现有两个小鬼ortant东西:

  • 颜色没有那么有用(通常是这样),因为一切都很红。所以,转变为灰度是一个好主意。

  • 您要选择的圆圈是以大强度变化为特征,而不是高强度。因此,计算梯度可能会有用。

  • 小血管也有很高的梯度。所以,你的DialateBloodVessel可能会有用。


RGB = imread('0PBEL.jpg'); % load the image 
% I crop the image to remove the black background (which gives high gradients too) 
RGB = imcrop(RGB, floor([.2*size(RGB, 2) .2*size(RGB, 1) .6*size(RGB, 2) .6*size(RGB, 1)])); 
G = rgb2gray(RGB); % convert to grayscale 
G = DialateBloodVessel(G); % remove blood vessels 

grad = imgradient(G); % calculate the gradient magnitude (direction is not important) 

%display the (transformed) images: useful to validate method and tune parameters 
figure 
subplot(2, 2, 1); 
imshow(RGB) 
subplot(2, 2, 2); 
imshow(G) 
subplot(2, 2, 3); 
imshow(grad, []) 
subplot(2, 2, 4); 
imshow(grad >= 20, []) 

% calculate the centroid and radius of all the regions 
stats = regionprops('table',grad >= 20,'Centroid', 'MajorAxisLength','MinorAxisLength');  
centers = stats.Centroid; 
diameters = mean([stats.MajorAxisLength stats.MinorAxisLength],2); 
radii = diameters/2; 
[maxRadii, iMax] = max(radii); % select the largest circle 

subplot(2, 2, 1); 
viscircles(centers(iMax, :),maxRadii); % visualise the selected circle 

enter image description here


作为替代方案,可以使用内置imfindcircles功能如下:

[centers, radii, metric] = imfindcircles(G,[50 100]); 
figure 
imshow(RGB) 
hold on 
viscircles(centers, radii,'EdgeColor','b'); 

注意,此方法可以工作,但有缺点是一个黑匣子。

enter image description here

+0

正如你可以看到我的图片我需要分开2个圆圈,里面的白色区域也应该分割,另一件事,我希望这个算法适用于任何图像。不仅在这个特殊的图像..我是非常新的图像处理,所以我不知道如何做到这一点..如果你可以帮助请... –

+0

我告诉你如何可能做到这一点的例子。您可以根据自己的需要调整此方法。用不同的图像测试该方法,并尝试调整参数以获得令人满意的结果。 – m7913d

+1

Ohk谢谢你的宝贵答案,这真的非常有用。我在多张图片上测试了这段代码,并且通过改变了很少的参数,它正在工作..现在我需要自动调整这个... –