7

我想在 OpenCv 上创建一个圆盘形结构元素。我需要我的 SE 与

sel = strel('disk',5);

我想使用

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

我需要做什么来实现这一点,以及使用 MATLAB 的 SE 的哪些值anchor_xanchor_y相同的中心点?

4

2 回答 2

6

根据文档,您可以尝试:

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

这给了我以下结构元素:

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

在 MATLAB 中我得到:

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

所以不完全相同但足够接近:)

于 2013-06-22T20:45:40.460 回答
1

我需要 matlab 中的精确结构元素,所以我根据需要编写了这个(不是很优雅的)函数。它适用于具有 3 到 21 之间奇数行/列的形状(您可以手动添加其他值(在 Matlab 中检查 # zeros)。

函数调用如下:

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

实际功能是

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;
于 2014-05-07T10:28:35.923 回答