您在答案中寻找的内容令人困惑。如果我们假设您的过滤器存储在std::vector<double>
被调用filter
并且您的图像实际上是 2D 并且具有类型std::vector< std::vector<double> >
称为image
,那么我们可以执行以下操作来应用 1-D 过滤器[-1,0,1]
:
std::vector< std::vector<double> > new_image;
std::vector<double> filter;
filter.push_back(-1.0); filter.push_back(0.0); filter.push_back(1.0);
for(int i = 0; i < image.size(); i++){
for(int j = 0; j < image.at(i).size(); j++){
new_image.at(i).push_back( filter.at(0)*image.at(i).at(j-1)
+ filter.at(1)*image.at(i).at(j)
+ filter.at(2)*image.at(i).at(j+1) );
}
}
例如,如果您想要一个像这样的二维过滤器
[0 1 0]
[1 0 1]
[0 1 0]
然后我们假设它也被存储为向量的向量,并且基本上也是如此。
std::vector< std::vector<double> > new_image;
for(int i = 0; i < image.size(); i++){
for(int j = 0; j < image.at(i).size(); j++){
top_filter_term = filter.at(0).at(0)*image.at(i-1).at(j-1)
+ filter.at(0).at(1)*image.at(i-1).at(j)
+ filter.at(0).at(2)*image.at(i-1).at(j+1);
mid_filter_term = filter.at(1).at(0)*image.at(i).at(j-1)
+ filter.at(1).at(1)*image.at(i).at(j)
+ filter.at(1).at(2)*image.at(i).at(j+1);
bot_filter_term = filter.at(2).at(0)*image.at(i+1).at(j-1)
+ filter.at(2).at(1)*image.at(i+1).at(j)
+ filter.at(2).at(2)*image.at(i+1).at(j+1);
new_image.at(i).push_back(top_filter_term + mid_filter_term + bot_filter_term);
}
}
请注意——我没有对过滤器数组进行边界检查,你真的应该只在远离图像边缘的地方应用它,或者添加代码来应用你想要的过滤器的任何类型的边界条件. 我也没有对此进行优化发表任何声明。对于大多数用途,使用矢量是一种很好的方法,因为它们可以动态调整大小并提供足够的内置支持来执行许多有用的图像操作。但是对于真正大规模的处理,您需要优化过滤操作等内容。
至于您关于过滤 3D 数组的问题,有几件事需要考虑。一,确保您确实想要过滤整个数组。对于许多图像处理任务,将所有颜色通道拆分为它们自己的 2D 数组,进行处理,然后将它们重新组合在一起会更好、更有效。如果您确实想要一个真正的 3D 过滤器,那么请确保您的过滤器实际上是 3D 的,也就是说,它将是一个由向量组成的向量。然后,您将使用与上述完全相同的逻辑,但您将为应用于图像的每个颜色通道或“切片”的过滤器部分添加一层额外的术语。