opencv过滤器对多维Mat [英] opencv filter on multi-dimension Mat
本文介绍了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屋!
查看全文