7

Voglio creare un elemento di strutturazione del disco su OpenCv. Ho bisogno del mio SE per essere simile conElemento di strutturazione del disco opencv vs Matlab

sel = strel('disk',5); 

voglio farlo usando

cvstructuringElementEx(cols,rows,anchor_x,anchor_y,shape,*values); 

Che cosa devo fare per raggiungere questo obiettivo e quali valori di anchor_x e anchor_y dare lo stesso punto centrale SE con MATLAB?

risposta

5

Secondo the docs, si potrebbe provare:

cv::Mat sel = cv::getStructuringElement(MORPH_ELLIPSE, cv::Size(9,9)); 

questo mi ha dato il seguente elemento strutturante:

0 0 0 0 1 0 0 0 0 
0 1 1 1 1 1 1 1 0 
0 1 1 1 1 1 1 1 0 
1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 
0 1 1 1 1 1 1 1 0 
0 1 1 1 1 1 1 1 0 
0 0 0 0 1 0 0 0 0 

Mentre in MATLAB ho ottenuto:

>> getnhood(strel('disk',5)) 
ans = 
    0  0  1  1  1  1  1  0  0 
    0  1  1  1  1  1  1  1  0 
    1  1  1  1  1  1  1  1  1 
    1  1  1  1  1  1  1  1  1 
    1  1  1  1  1  1  1  1  1 
    1  1  1  1  1  1  1  1  1 
    1  1  1  1  1  1  1  1  1 
    0  1  1  1  1  1  1  1  0 
    0  0  1  1  1  1  1  0  0 

Quindi non esattamente lo stesso ma abbastanza vicino :)

1

Avevo bisogno dell'elemento di strutturazione esatto come in matlab, quindi ho scritto questa funzione (non molto elegante) per il mio bisogno. Funziona per le forme con un numero dispari di righe/colonne tra 3 e 21 (è possibile aggiungere manualmente gli altri valori (controllare # zeri in Matlab)

La funzione viene richiamata in questo modo:.

int Radius = 1; 
// following call equivalent to Matlab's sel = getnhood(strel('disk',Radius)) 
cv::Mat sel = strelDisk(Radius); 

E la funzione attuale è

cv::Mat strelDisk(int Radius){ 
// THIS RETURNS STREL('DISK',RADIUS) LIKE IN MATLAB FOR RADIUS = ODD NUMBER BETWEEN 3-->21 
cv::Mat sel((2*Radius-1),(2*Radius-1),CV_8U,cv::Scalar(255)); 
int borderWidth; 
switch (Radius){ 
case 1: borderWidth = 0; break; 
case 3: borderWidth = 0; break; 
case 5: borderWidth = 2; break; 
case 7: borderWidth = 2; break; 
case 9: borderWidth = 4; break; 
case 11: borderWidth = 6; break; 
case 13: borderWidth = 6; break; 
case 15: borderWidth = 8; break; 
case 17: borderWidth = 8; break; 
case 19: borderWidth = 10; break; 
case 21: borderWidth = 10; break; 
} 
for (int i=0; i<borderWidth; i++){ 
    for (int j=0; j<borderWidth; j++){ 
     if (i+j<8){ 
      sel.at<uchar>(i,j)=0; 
      sel.at<uchar>(i,sel.cols-1-j)=0; 
      sel.at<uchar>(sel.rows-1-i,j)=0; 
      sel.at<uchar>(sel.rows-1-i,sel.cols-1-j)=0; 
     } 
    } 
} 
return sel;