6

tôi đang gặp khó khăn để đạt được các phân khúc đúng đắn về một hình ảnh màu xám:Phân đoạn hình ảnh màu xám

Image to be segmented

Sự thật mặt đất, tức là những gì tôi muốn các phân khúc để trông giống như, là thế này:

Ground truth

Tôi quan tâm nhất đến ba thành phần trong vòng kết nối. Vì vậy, như bạn có thể thấy, tôi muốn phân đoạn hình ảnh hàng đầu thành ba thành phần: hai hình bán nguyệt và hình chữ nhật giữa chúng.

Tôi đã thử các kết hợp khác nhau về giãn nở, xói mòn và tái tạo, cũng như các thuật toán phân cụm khác nhau, bao gồm k-means, isodata và hỗn hợp gaussians - tất cả đều có mức độ thành công khác nhau.

Mọi đề xuất sẽ được đánh giá cao.

Chỉnh sửa: đây là kết quả tốt nhất mà tôi có thể nhận được. Điều này đã được thu được sử dụng một đường viền tích cực vào phân khúc thu nhập từ đầu tròn, và sau đó áp dụng phân nhóm ISODATA:

Clusters

Có hai vấn đề với điều này:

  • Quầng sáng trắng xung quanh cụm phía dưới bên phải , thuộc cụm trên cùng bên trái
  • Quầng xám xung quanh cụm trên cùng bên phải và dưới cùng bên trái, thuộc cụm trung tâm.
+0

Dường như bạn có một histogram tri-modal. Hãy xem câu trả lời của tôi trên dsp.stackexchange.com -> http://dsp.stackexchange.com/questions/3643/image-segmentation-issue-of-different-materials/3650#3650. Trong mọi trường hợp, câu hỏi của bạn sẽ được chuyển đến trang web đó. –

+0

Tôi đã thử phân đoạn dựa trên biểu đồ. Vấn đề với cách tiếp cận này là các giá trị của các điểm ảnh xung quanh cụm phải nhất tương tự nhất với các điểm ảnh của cụm trái nhất, dẫn đến một "quầng" xung quanh cụm phải nhất. – Richard

+0

Bạn đã thử bwboundaries, hoặc bwlabel? Họ có thể làm việc cho bạn. Nhưng nếu hiệu ứng hào quang quá nhiều, bạn có thể không nhận được kết quả mong muốn. Tuy nhiên, với một số thao tác và làm sạch trước và sau, bạn có thể có được những gì bạn muốn. Nó cũng có thể giúp sử dụng một cái gì đó như [vòng tròn hough] (http://www.mathworks.com/matlabcentral/fileexchange/26978-hough-transform-for-circles/content/html/circle_houghdemo.html), hoặc các phương pháp khác như [cái này] (http: //blogs.mathworks.com/pick/2008/05/23/phát hiện vòng tròn-trong-một-hình ảnh /), để bạn biết giới hạn của vòng kết nối của bạn. – Bill

Trả lời

7

Đây là bộ khởi động ... sử dụng circular Hough transform để tìm phần hình tròn. Đối với điều đó tôi ban đầu threshold the image locally.

im=rgb2gray(imread('Ly7C8.png')); 
imbw = thresholdLocally(im,[2 2]); % thresold localy with a 2x2 window 
% preparing to find the circle 
props = regionprops(imbw,'Area','PixelIdxList','MajorAxisLength','MinorAxisLength'); 
[~,indexOfMax] = max([props.Area]); 
approximateRadius = props(indexOfMax).MajorAxisLength/2; 
radius=round(approximateRadius);%-1:approximateRadius+1); 
%find the circle using Hough trans. 
h = circle_hough(edge(imbw), radius,'same'); 
[~,maxIndex] = max(h(:)); 
[i,j,k] = ind2sub(size(h), maxIndex); 
center.x = j;  center.y = i; 

figure;imagesc(im);imellipse(gca,[center.x-radius center.y-radius 2*radius 2*radius]); 
title('Finding the circle using Hough Trans.'); 

enter image description here

chỉ chọn những gì bên trong vòng tròn:

[y,x] = meshgrid(1:size(im,2),1:size(im,1)); 
z = (x-j).^2+(y-i).^2; 
f = (z<=radius^2); 
im=im.*uint8(f); 

EDIT:

nhìn kiếm một nơi để bắt đầu ngưỡng hình ảnh để phân khúc nó bằng cách nhìn vào biểu đồ, tìm kiếm giá trị cực đại địa phương đầu tiên và lặp lại từ đó cho đến khi tìm thấy 2 phân đoạn riêng biệt, sử dụng bwlabel:

p=hist(im(im>0),1:255); 
    p=smooth(p,5); 
    [pks,locs] = findpeaks(p); 

    bw=bwlabel(im>locs(1)); 
    i=0; 
    while numel(unique(bw))<3 
    bw=bwlabel(im>locs(1)+i); 
    i=i+1; 
    end 


imagesc(bw); 

enter image description here

Phần giữa bây giờ có thể thu được bằng cách lấy ra hai phần dán nhãn từ vòng tròn, và những gì còn lại sẽ là phần giữa (+ một số quầng)

bw2=(bw<1.*f); 

nhưng sau khi một số bộ lọc trung bình chúng ta có được một cái gì đó reasonble hơn

bw2= medfilt2(medfilt2(bw2)); 

và cùng nhau chúng ta nhận được:

imagesc(bw+3*bw2); 

enter image description here

Phần cuối cùng là một thực tế "nhanh chóng và dơ bẩn", tôi chắc chắn rằng với các công cụ bạn đã sử dụng bạn sẽ nhận được kết quả tốt hơn ...

+0

Rất đẹp, cảm ơn bạn đã dành thời gian để tìm ra điều này. Tuy nhiên, kết quả phụ thuộc rất nhiều vào giá trị ngưỡng, trong trường hợp này là 186. Ví dụ, giá trị 183 làm sai lệch đáng kể kết quả. Tôi nhận ra tôi đã không xác định điều này trong câu hỏi của tôi, nhưng đây chỉ là một ví dụ điển hình của vấn đề; có nhiều hình ảnh khác yêu cầu phân đoạn tương tự. Vì vậy, tôi đã hy vọng sẽ đưa ra một giải pháp chung, tự động. Có lẽ có một số cách để "đoán" tham số ngưỡng. – Richard

+0

Có một số cách để thực hiện việc này, xem bản chỉnh sửa của tôi để có cách nhanh chóng để tự động đặt ngưỡng không xa những gì tôi đã có trước đây ... – bla

1

Bạn cũng có thể nhận được kết quả gần đúng bằng cách sử dụng watershed transformation. Đây là bước ngoặt vào hình ảnh đảo ngược -> lưu vực sông (255-I) Dưới đây là một kết quả ví dụ:

enter image description here

Một phương pháp đơn giản là để thực hiện một đóng hình thái vào hình ảnh ban đầu với một yếu tố đĩa cơ cấu (người ta có thể thực hiện đóng cửa nhiều lần cho granulometries) và sau đó có được vòng tròn đầy đủ. Sau khi giải nén vòng tròn này và các thành phần withing dễ dàng hơn.

se = strel('disk',3); 
Iclo = imclose(I, se);% This closes open circular cells. 
Ithresh = Iclo>170;% one can locate this threshold automatically by histogram modes (if you know apriori your cell structure.) 
Icircle = bwareaopen(Ithresh, 50); %to remove small noise components in the bg 

enter image description here

Ithresh2 = I>185; % This again needs a simple histogram. 

enter image description here

Các vấn đề liên quan