opencv过滤器对多维Mat [英] opencv filter on multi-dimension Mat

查看:173
本文介绍了opencv过滤器对多维Mat的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将以下代码传输到c ++中:

  gaussFilter = fspecial('gaussian',2 * neighSize + 1 ,0.5 * neighSize); 
pointFeature = imfilter(pointFeature,gaussFilter,'symmetric');

其中 pointFeature width,24] array。



我尝试使用 filter2D ,但它只支持二维数组。 p>

所以我想知道opencv中是否有可以过滤多维数组的函数?

方案

如果你正在使用OpenCV,你可以尝试这个3维MatND:

  void Smooth3DHist (cv :: MatND& hist,const int& kernDimension)
{

assert(hist.dims == 3);
int x_size = hist.size [0];
int y_size = hist.size [1];
int z_size = hist.size [2];
int xy_size = x_size * y_size;

cv :: Mat kernal = cv :: getGaussianKernel(kernDimension,-1,CV_32F);

//(int z = 0; z 的XY维度
{
float * ind =(float * )hist_data + z * xy_size; //子矩阵指针
cv :: Mat subMatrix(2,hist.size,CV_32F,ind);
cv :: sepFilter2D(subMatrix,subMatrix,CV_32F,kernal.t(),kernal,Point(-1,-1),0.0,cv :: BORDER_REPLICATE);
}

//过滤Z维
float * kernGauss =(float *)kernal.data;
unsigned kernSize = kernal.total();
int kernMargin =(kernSize-1)/ 2;
float * lineBuffer = new float [z_size + 2 * kernMargin];
for(int y = 0; y< y_size; y ++)
{
for(int x = 0; x< x_size; x ++)
{
//沿着Z维复制到行缓冲区
float * z_ptr =(float *)hist.data + y * x_size + x; //与hist.ptr相同(0,y,x)
for(int z = 0; z {
lineBuffer [z + kernMargin] = * z_ptr;
}

//复制边框
for(int m = 0; m< kernMargin; m ++)
{
lineBuffer [m] = lineBuffer [kernMargin]; //复制左侧
lineBuffer [z_size + 2 * kernMargin - 1 - m] = lineBuffer [kernMargin + z_size - 1]; //复制右侧
}

//过滤行缓冲区1D - 卷积
z_ptr =(float *)hist.data + y * x_size + x;
for(int z = 0; z< z_size; z ++,z_ptr + = xy_size)
{
* z_ptr = 0.0f;
for(unsigned k = 0; k {
* z_ptr + = lineBuffer [z + k] * kernGauss [k]
}
}
}
}
delete [] lineBuffer;

}


i want to transport the follow codes into c++:

gaussFilter = fspecial('gaussian', 2*neighSize+1, 0.5*neighSize);
pointFeature = imfilter(pointFeature, gaussFilter, 'symmetric');

where the pointFeature is a [height, width, 24] array.

i try to use filter2D, but it only support the 2D array.

so i want to know if there are functions in opencv that can filtering the multi-dimensional array?

解决方案

If you are using OpenCV, you could try this for a 3 Dimensional MatND:

void Smooth3DHist(cv::MatND &hist, const int& kernDimension)
{

    assert(hist.dims == 3);
    int x_size  = hist.size[0];
    int y_size  = hist.size[1];
    int z_size  = hist.size[2];
    int xy_size = x_size*y_size;

    cv::Mat kernal = cv::getGaussianKernel(kernDimension, -1, CV_32F);

    // Filter XY dimensions for every Z
    for (int z = 0; z < z_size; z++)
    {
        float *ind = (float*)hist.data + z * xy_size; // sub-matrix pointer
        cv::Mat subMatrix(2, hist.size, CV_32F, ind);
        cv::sepFilter2D(subMatrix, subMatrix, CV_32F, kernal.t(), kernal, Point(-1,-1), 0.0, cv::BORDER_REPLICATE);
    }

    // Filter Z dimension
    float* kernGauss = (float *)kernal.data;
    unsigned kernSize = kernal.total();
    int kernMargin = (kernSize - 1)/2;
    float* lineBuffer = new float[z_size + 2*kernMargin];
    for (int y = 0; y < y_size; y++)
    {
        for (int x = 0; x < x_size; x++)
        {
            // Copy along Z dimension into a line buffer
            float* z_ptr = (float*)hist.data + y * x_size + x;//same as hist.ptr<float>(0, y, x)
            for (int z = 0; z < z_size; z++, z_ptr += xy_size)
            {
                lineBuffer[z + kernMargin] = *z_ptr;
            }

            // Replicate borders
            for (int m = 0; m < kernMargin; m++)
            {
                lineBuffer[m] = lineBuffer[kernMargin];// replicate left side
                lineBuffer[z_size + 2*kernMargin - 1 - m] = lineBuffer[kernMargin + z_size - 1];//replicate right side
            }

            // Filter line buffer 1D - convolution
            z_ptr = (float*)hist.data + y * x_size + x;
            for (int z = 0; z < z_size; z++, z_ptr += xy_size)
            {
                *z_ptr = 0.0f;
                for (unsigned k = 0; k < kernSize; k++)
                {
                    *z_ptr += lineBuffer[z+k]*kernGauss[k];
                }
            }
        }
    }
    delete [] lineBuffer;

}

这篇关于opencv过滤器对多维Mat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆