我正在尝试实现2D卷积滤波器。我首先使用copymakeborder来创建图像的边框,然后再遍历图像并适当地过滤。然后,我使用colRange和rowRange删除填充,然后将格式化的图片复制到输出矩阵中。
但是图片显示不正确。我一直陷在这个问题上,我找不到错误。我想我已经忽略了一些东西,但是我不确定在哪里。
有人可以帮我吗?
void algorithms::manual_filter_2d(const Mat & input, Mat & output, const Mat & kernel) {
Mat temp_image(input.rows, input.cols, input.type());
cv::copyMakeBorder(input, temp_image, (kernel.cols) / 2, (kernel.cols) / 2, (kernel.rows) / 2, (kernel.rows) / 2, cv::BORDER_REPLICATE);
Mat temp_output(temp_image.rows, temp_image.cols, input.type());
for (int y = (kernel.rows - 1) / 2; y < temp_image.rows - ((kernel.rows) / 2); y++) {
for (int x = (kernel.cols - 1) / 2; x < temp_image.cols - ((kernel.cols) / 2); x++) {
float sum = 0.0f;
for (int ky = 0; ky < kernel.rows; ky++) {
for (int kx = 0; kx < kernel.cols; kx++) {
sum += temp_image.at < float > (y + ky - ((kernel.rows - 1) / 2), x + kx - ((kernel.cols - 1) / 2)) * kernel.at < float > (ky, kx);
}
}
temp_output.at < float > (y - kernel.rows / 2, x - kernel.cols / 2) = sum;
}
}
temp_output.rowRange((kernel.rows - 1) / 2, temp_image.rows - ((kernel.rows) / 2)).colRange((kernel.cols - 1) / 2, temp_image.cols - ((kernel.cols) / 2)).copyTo(output);
}
设置卷积结果的坐标是错误的
// copy input image using a tmp one
Mat temp_image(input.rows, input.cols, input.type());
// pad image using border duplication
cv::copyMakeBorder(input, temp_image, (kernel.cols)/2, (kernel.cols)/2, (kernel.rows)/2, (kernel.rows)/2, cv::BORDER_REPLICATE);
// output image
Mat temp_output(temp_image.rows, temp_image.cols, input.type());
// move over the image
for(int y=(kernel.rows-1)/2; y<temp_image.rows-((kernel.rows)/2); y++) {
for(int x=(kernel.cols-1)/2; x<temp_image.cols-((kernel.cols)/2); x++) {
float sum = 0.0f;
// loop inside the kernel
for (int ky=0; ky<kernel.rows; ky++) {
for (int kx=0; kx<kernel.cols; kx++) {
sum += temp_image.at<float>(y + ky - ((kernel.rows - 1) / 2), x + kx - ((kernel.cols - 1) / 2)) *kernel.at<float>(ky, kx);
}
}
// center inside the image respect to the kernel
temp_output.at<float>(y,x) = sum;
}
}
// copy convolution result into output image
temp_output.rowRange((kernel.rows-1)/2, temp_image.rows-((kernel.rows)/2)).colRange((kernel.cols-1)/2, temp_image.cols-((kernel.cols)/2)).copyTo(output);
}