c++ - 如何在图像上应用自定义过滤器?
问题描述
我在 WSL + XServer 上的 Ubuntu 20.04 LTS 上为 GUI 使用 OpenCV4。
我想创建自定义卷积过滤器内核并将它们应用于我的图像。这是我为它编写的代码:
cv::Mat filter2D(cv::Mat input, cv::Mat filter)
{
using namespace cv;
Mat dst = input.clone();
//cout << " filter data successfully found. Rows:" << filter.rows << " cols:" << filter.cols << " channels:" << filter.channels() << "\n";
//cout << " input data successfully found. Rows:" << input.rows << " cols:" << input.cols << " channels:" << input.channels() << "\n";
for (int i = 0-(filter.rows/2);i<input.rows-(filter.rows/2);i++)
{
for (int j = 0-(filter.cols/2);j<input.cols-(filter.cols/2);j++)
{ //adding k and l to i and j will make up the difference and allow us to process the whole image
float filtertotal = 0;
for (int k = 0; k < filter.rows;k++)
{
for (int l = 0; l < filter.rows;l++)
{
if(i+k >= 0 && i+k < input.rows && j+l >= 0 && j+l < input.cols)
{ //don't try to process pixels off the edge of the map
float a = input.at<uchar>(i+k,j+l);
float b = filter.at<float>(k,l);
float product = a * b;
filtertotal += product;
}
}
}
//filter all proccessed for this pixel, write it to dst
dst.at<uchar>(i+(filter.rows/2),j+(filter.cols/2)) = filtertotal;
}
}
return dst;
}
int main(int argc, char** argv)
{
// Declare variables
cv::Mat_<float> src;
const char* window_name = "filter2D Demo";
// Loads an image
src = cv::imread("fapan.png", cv::IMREAD_GRAYSCALE ); // Load an image
if( src.empty() )
{
printf(" Error opening image\n");
return EXIT_FAILURE;
}
static float x[3][3] = {
{-1, -1, -1},
{-1, 8, -1},
{-1, -1, -1}
};
cv::Mat kernel(3,3, CV_16FC1, x);
// Apply filter
filter2D(src, kernel);
cv::imshow( window_name, src );
cv::waitKey(0);
return EXIT_SUCCESS;
}
如您所见,不仅边缘是白色的,而且内部也是白色的。
解决方案
您为输入代码发布的输出是正确的,因为您在图像上应用了普通过滤器。
它可能会导致它有点模糊或锐化,但它永远不会导致它完全检测到边缘。
为了只检测图像的边缘,您必须沿某个方向应用拉普拉斯算子。 https://www.l3harrisgeospatial.com/docs/LaplacianFilters.html#:~:text=A%20Laplacian%20filter%20is%20an,an%20edge%20or%20continuous%20progression。(带有一些信息的链接)这是图像的衍生物,它只会检测到变化。
我建议您在 matlab 图像处理工具箱上执行此操作。
推荐阅读
- cocoa - 以编程方式更改 macOS Mojave 强调色
- python - 如何找到使用 ssh 和 rsync 的方法
- c++ - 不知何故告诉编译器“不要处理代码行”
- java - 使用 SharedPreferences 创建多个用户
- r - 从嵌套循环返回完整列表
- mongodb - MongoDB 对大型多更新操作的可扩展性问题
- python - 将 python WeakSet 提供给列表构造函数是否安全?
- c - 如何打印出每个目录但作为路径名?(在身体描述中解释)
- spring - spring boot rest webservice,如何改进干净的代码?
- haskell - 我正在尝试在 haskell 中重新定义产品定义。我收到一条错误消息,提示“功能中的非详尽模式”