2013-07-04 22 views
5

sto elaborando una tale immagine come mostrato in Fig.1, che si compone di una serie di punti e necessario per convertire la Fig 2.opencv - termoretraibile oggetti pixel

Fig.1 immagine originale.

Fig.1 original image
Fig.2 volevano immagine

Fig.2 wanted image

Per terminare la conversione, in primo luogo rilevo il edge di ogni punto e quindi utilizzo dilation. Il risultato è soddisfacente dopo aver scelto i parametri corretti, visto in Fig. 3.

immagine Fig.3 dopo la dilatazione

Fig.3 image after dilation

ho elaborato la stessa immagine prima in MATLAB. Quando si tratta di ridurre gli oggetti (in Fig.3) in pixel, la funzione bwmorph(Img,'shrink',Inf) funziona e il risultato è esattamente da dove proviene la Fig. 2. Quindi, come ottenere la stessa immagine desiderata in opencv? Sembra che non ci sia una simile funzione shrink.

Ecco il mio codice di trovare funzionamento bordo e la dilatazione:

#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include <stdlib.h> 
#include <stdio.h> 
#include <cv.h> 
#include <highgui.h> 
using namespace cv; 

// Global variables 
Mat src, dilation_dst; 
int dilation_size = 2; 

int main(int argc, char *argv[]) 
{ 
    IplImage* img = cvLoadImage("c:\\001a.bmp", 0);     // 001a.bmp is Fig.1        

    // Perform canny edge detection 
    cvCanny(img, img, 33, 100, 3); 

    // IplImage to Mat 
    Mat imgMat(img); 
    src = img; 

    // Create windows 
    namedWindow("Dilation Demo", CV_WINDOW_AUTOSIZE); 

    Mat element = getStructuringElement(2,       // dilation_type = MORPH_ELLIPSE 
        Size(2*dilation_size + 1, 2*dilation_size + 1), 
        Point(dilation_size, dilation_size)); 

    // Apply the dilation operation 
    dilate(src, dilation_dst, element); 
    imwrite("c:\\001a_dilate.bmp", dilation_dst); 
    imshow("Dilation Demo", dilation_dst); 

    waitKey(0); 
    return 0; 
} 

risposta

4

1- Find all the contours nella vostra immagine.

2- Utilizzo di moments trovare il proprio centro di massa. Esempio:

/// Get moments 
vector<Moments> mu(contours.size()); 
for(int i = 0; i < contours.size(); i++) 
{ mu[i] = moments(contours[i], false); } 

/// Get the mass centers: 
vector<Point2f> mc(contours.size()); 
for(int i = 0; i < contours.size(); i++) 
{ mc[i] = Point2f(mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00); } 

3- Creare un'immagine zero (nero) e scrivere tutti i punti centrali su di esso.

4- Nota che avrete uno o due punti in più provenienti dai contorni del bordo. Forse puoi applicare un pre-filtro in base allo contour areas, poiché il bordo è un grande contorno collegato con un'area estesa.

+0

Ho trovato il codice [qui] (http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/moments/moments.html) ma non capisco cosa significa 'mc [i]' . Potresti mostrare un esempio del tuo passo 3, cioè come scrivere i punti in base a 'mc [i]' – WangYudong

+0

mc è un vettore di punti. dovresti creare un'immagine della stessa dimensione con quella originale, quindi cambiare i pixel con image.at (i, j) = 255; dove i, j sono i punti presi da mc. Fare riferimento a questo [collegamento] (http://stackoverflow.com/questions/9104869/how-can-i-change-a-pixel-value-from-a-grayscaled-image-using-opencv-2-3). Cerca "cambiando i pixel in opencv" se non risolve il tuo problema. – baci

0

Non è molto veloce, ma ho implementato l'algoritmo di filtraggio morfologico da Digital Image Processing, 4a edizione di William K. Pratt. Questo dovrebbe essere esattamente quello che stai cercando.

Il codice è concesso in licenza MIT e disponibile su GitHub allo cgmb/shrink.

In particolare, ho definito cv::Mat cgmb::shrink_max(cv::Mat in) per ridurre un dato cv::Mat di CV_8UC1 tipo fino a quando non è possibile eseguire ulteriori riduzioni.

Quindi, se si compila Shrink.cxx con il vostro programma e cambiare il codice in questo modo:

#include "Shrink.h" // add this line 
... 
dilate(src, dilation_dst, element); 
dilation_dst = cgmb::shrink_max(dilation_dst); // and this line 
imwrite("c:\\001a_dilate.bmp", dilation_dst); 

Otteniamo questo:

image after binary shrink

Tra l'altro, l'immagine ha rivelato a bug in Octave Image s' attuazione bwmorph ridursi. La Figura 2 non dovrebbe essere il risultato di un'operazione di restringimento su Figura 3, in quanto l'anello non dovrebbe essere rotto da un'operazione di restringimento. Se quell'anello è scomparso in MATLAB, presumibilmente soffre anche di una specie di bug simile.

Attualmente, Octave e I hanno risultati leggermente diversi da MATLAB, ma sono molto vicini.

Problemi correlati