2015-04-23 3 views
5

Questa è la mia immagine originale: Weld Nut"Ritagliare" un'immagine sulla base di rilevamento dei bordi

Ho chiesto all'utente di ritagliarla, convertito in scala di grigi e corse questa riga di codice su di esso:

edgeImg = edge(grayImg,'canny',0.23); 

questo è il risultato:

Edges

voglio "tagliare fuori" tutto il cerchio centrale e il bordo esterno, in sostanza. Sto attraversando un periodo difficile per capire come farlo e onestamente sono in perdita.

Ho pensato di riempire l'area che voglio mantenere nell'immagine binaria, e quindi potrei usarla come timbro, ma non ho potuto trovare un modo che non riempisse il centro cerchio pure.

Qualche idea?

Grazie.

EDIT: Questa area bianca è ciò che voglio mantenere:

Highlighted

+0

Provare a dilatare l'immagine e a ridurla. Questo è un approccio molto comune, dai un'occhiata a –

+1

Puoi evidenziare quali parti vuoi effettivamente conservare? Non è chiaro per me. grazie –

+1

@ Benoit_11 Aggiornato. – TechnoSam

risposta

2

vorrei suggerire di non fare il rilevamento dei bordi, in primo luogo, si stanno perdendo preziose informazioni relative al colore. Puoi provare un algoritmo di clustering, come K-Means (including source code) o qualsiasi altra cosa.

Al termine del cluster, è possibile mantenere i pixel correlati ai cluster con l'oggetto. I cluster desiderati possono essere selezionati in base alla posizione dell'oggetto nell'immagine (incluso il ritaglio dell'immagine) e il colore.

Codice esempio di K-Means di clustering per 2 cluster è qui sotto:

he = imread('D:\1.jpg'); 
imshow(he); 

cform = makecform('srgb2lab'); 
lab_he = applycform(he,cform); 

ab = double(lab_he(:,:,2:3)); 
nrows = size(ab,1); 
ncols = size(ab,2); 
ab = reshape(ab,nrows*ncols,2); 

%One cluster for your object and one for background 
nColors = 2; 
[cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ... 
             'Replicates',2); 


pixel_labels = reshape(cluster_idx,nrows,ncols); 

segmented_images = cell(1,3); 
rgb_label = repmat(pixel_labels,[1 1 3]); 

for k = 1:nColors 
    color = he; 
    color(rgb_label ~= k) = 0; 
    segmented_images{k} = color; 
end 

%Show both clusters: object and non-object 
imshow(segmented_images{1}); 
figure; 
imshow(segmented_images{2}); 

La segmentazione risultante è abbastanza buono:

enter image description hereenter image description here

+0

La risposta dovrebbe includere del codice per esemplificare – krisdestruction

+1

Il codice è stato effettivamente fornito nella mia risposta: http://www.mathworks.com/help/images/examples/color-based-segmentation-using-k-means-clustering.html – Konstantin

+0

@krisdestruction, puoi controllare i risultati. Nessun lavoro manuale oltre a ritagliare l'immagine – Konstantin

1

Invece di usare K- Significa che puoi semplicemente usare color thresholder dato che hai così tante informazioni sul colore. Quindi puoi chiamare la funzione di maschera generata automaticamente chiamata createMask e successivamente elaborare la tua immagine lì. Il codice è sotto La migliore parte di questo metodo è che createMask è riutilizzabile per qualsiasi immagine, non solo la tua!

% Read Image 
I = imread('r8ATB.jpg'); 
figure; imshow(I); 

% Crop Image 
C = I(75:490,40:460,:); 
figure; imshow(C); 

% Plot Noisy Mask 
[BW,MK] = createMask(C); 
figure; imshow(BW); 
figure; imshow(BW); 

% Fix Holes 
imopen(...); 

Questa è l'immagine originale.

Original Image

Immagine potata

enter image description here

finestra soglia Start.

enter image description here

Soglia Parametri

enter image description here

maschera creata

enter image description here

Immagine finale

enter image description here

La funzione createMask.m generata automaticamente utilizzando il mio parametro è la seguente.

function [BW,maskedRGBImage] = createMask(RGB) 
%createMask Threshold RGB image using auto-generated code from colorThresholder app. 
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using 
% auto-generated code from the colorThresholder App. The colorspace and 
% minimum/maximum values for each channel of the colorspace were set in the 
% App and result in a binary mask BW and a composite image maskedRGBImage, 
% which shows the original RGB image values under the mask BW. 

% Auto-generated by colorThresholder app on 23-Apr-2015 
%------------------------------------------------------ 


% Convert RGB image to chosen color space 
I = rgb2hsv(RGB); 

% Define thresholds for channel 1 based on histogram settings 
channel1Min = 0.983; 
channel1Max = 0.167; 

% Define thresholds for channel 2 based on histogram settings 
channel2Min = 0.205; 
channel2Max = 1.000; 

% Define thresholds for channel 3 based on histogram settings 
channel3Min = 0.341; 
channel3Max = 1.000; 

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

% Invert mask 
BW = ~BW; 

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

Si può quindi procedere ad utilizzare imopen e imclose per ripulire la maschera. Quindi applicalo all'immagine. Il mio metodo richiede la messa a punto per renderlo perfetto secondo qualsiasi metodo, ma ti darà risultati coerenti.

Per ottenere il complemento della tua immagine, tutto ciò che devi fare è invertire la maschera e applicarla.

+1

la tua soluzione è anche abbastanza buona, tuttavia richiede un po 'di lavoro manuale. Ad ogni modo, l'ho svalutato. – Konstantin

+1

Hai svettato anche il tuo per una soluzione automatica. Anche se richiede un input manuale, generalmente lo si vuole se si crea il timbro più accurato dell'OP specificato nella domanda. Sono consapevole di k-means e della suggestione che può fare e che userei totalmente se fossero immagini distinte con soggetti diversi. – krisdestruction