2013-06-22 19 views
7

Chcę utworzyć element strukturyzujący w kształcie dysku na OpenCv. Muszę mój SE być podobnaDisk Structuring Element opencv vs Matlab

sel = strel('disk',5); 

chcę to zrobić za pomocą

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

Co muszę zrobić, aby to osiągnąć i jakie wartości od anchor_x i anchor_y dają ten sam punkt środkowy SE z MATLAB?

Odpowiedz

5

Według the docs, można spróbować:

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

To dało mi następujący element strukturę:

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 

Chociaż w programie MATLAB Mam:

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

Więc nie do końca to samo, ale wystarczająco blisko :)

1

Potrzebowałem dokładnego elementu strukturyzującego, jak w matlab, więc napisałem tę (niezbyt elegancką) funkcję do mojej potrzeby. To działa dla kształtów z nieparzystej liczby wierszy/kolumn między 3 a 21 (można ręcznie dodać inne wartości (sprawdź # zer w Matlab)

Funkcja wywoływana jest tak:.

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

Rzeczywista funkcja to

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;