2014-12-03 2 views
12

Ho problemi con la segmentazione dell'immagine a basso contrasto. Il compito è trovare i difetti di superficie. Sono visibili (i difetti sono sempre aree scure) ma il contrasto dell'immagine è molto basso. Sotto due campioni.Segmentazione dell'immagine a basso contrasto

1 2

Ho provato migliorare il contrasto e quindi tresholding:

Mat tmp1 = imread("C:\\framesRoi\\311.bmp",0); 
stretchContrast(tmp1); 
threshold(tmp1,tmp1,75,255,THRESH_BINARY); 

cui tratto impl contrasto:

int minValue = 255, maxValue = 0; 
const int l = sourceImg.cols * sourceImg.rows * sourceImg.channels(); 
if(sourceImg.isContinuous()) 
{ 
    uchar* ptr = sourceImg.ptr<uchar>(0); 
    for(int i = 0; i < l; ++i) 
    { 
     if(ptr[i] < minValue) 
     { 
      minValue = ptr[i]; 
     } 
     if(ptr[i] > maxValue) 
     { 
      maxValue = ptr[i]; 
     } 
    } 
} 
cout<<"min: "<<minValue<<";"<<"max value: "<<maxValue<<endl; 

const int magicThreshold = 10; 
if(sourceImg.isContinuous()) 
{ 
    uchar* ptr = sourceImg.ptr<uchar>(0); 
    for(int i = 0; i < l; ++i) 
    { 
     ptr[i] = 255 * (ptr[i]-minValue)/(maxValue - minValue); 
    } 
} 

Ma questo approccio non è riuscito. Ci sono molti falsi rilevamenti e non vengono rilevati tutti i difetti: 3

Ecco zip con telai di prova: https://dl.dropboxusercontent.com/u/47015140/testFrames.rar

+1

Quando si esegue un tratto contrasto in base al contenuto dell'immagine, si perde il contesto necessario per prendere una soglia utile. –

+0

@MarkRansom: quindi come dovrei farlo? – krzych

+2

Se si sa che i difetti saranno sempre scuri, è possibile regolare la luminosità senza modificare il contrasto in modo che le aree luminose siano coerenti. Puoi farlo con il massimo, anche se usare un 90 ° percentile o meno sarebbe meno vulnerabile al rumore. –

risposta

8

Prova a raggruppare l'immagine in base al livello di grigio utilizzando un metodo di raggruppamento come i kmea. Qui di seguito ho usato i kmea direttamente sulle immagini senza trasformazioni di livello di grigio (usando 3 cluster mi hanno dato risultati migliori). Dovresti essere in grado di migliorare i risultati raggruppando un'immagine preelaborata usando i metodi descritti nei commenti.

enter image description here enter image description here

Forma dei cluster può variare leggermente a causa della casualità di Kmeans.

Ora se si prendono i componenti collegati dell'immagine in cluster e si calcola il livello medio di grigio di quelle regioni, i difetti dovrebbero avere una media inferiore rispetto alle altre regioni.

Ho eseguito il clustering in Matlab.

im = imread('r2SOV.png');%Uy1Fq r2SOV 
gr = im; 
size = size(gr); 

% perform closing using a 5x5 circular structuring element 
sel = strel('disk', 2, 4); 
mcl = imclose(gr, sel); 
% cluster gray levels using kmeans: using 3 clusters 
x = double(mcl(:)); 
idx = kmeans(x, 3); 
cl = reshape(idx, size); 

figure, imshow(label2rgb(cl)) 
+0

La migliore risposta è così lontana. Aspetterò fino a che la ricompensa scada e accetti la migliore risposta. – krzych

4

come si diceva nel tuo commento, è possibile modificare la luminosità in modo negativo e spingere verso l'alto il contrasto.

Inoltre, il sharpen filter è anche molto utile per il tuo caso. Puoi fare this in OpenCV.

4

Credo che si dovrebbe provare adaptiveThreshold funzione con una grande finestra.

#include "opencv2/opencv.hpp" 
using namespace cv; 
int main(int argc,char** argv) 
{ 

    Mat im = imread("c:/data/img1.png",0); 
    cv::namedWindow("ctrl"); 
    int win=62; 
    int th=2100; 
    cv::createTrackbar("win", "ctrl", &win, 500); 
    cv::createTrackbar("th", "ctrl", &th, 10000); 
    while(true) 
    { 
     Mat thresh; 
     medianBlur(im,thresh,15);//helps smooth out smaller noises, which you could also remove by size instead of this way 
     adaptiveThreshold(thresh,thresh,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,win*2+1,( th/1000.)); 
     imshow("thresh",thresh); 
     if(waitKey(1)==27) 
      exit(0); 
    } 
} 

tutti i risultati qui (http://www.datafilehost.com/d/99e3d86c) Si potrebbe anche voler dare un'occhiata a ImageJ che implementa una serie di algoritmi di auto-soglia. Penso che ciò di cui hai bisogno sia qualcosa che tenga conto delle informazioni sull'immagine locale.

enter image description here enter image description here