我想在opencv中实现高斯模糊功能,但是当我尝试获得一个噪声图像时。这是我的代码:
int main( int argc, char** argv )
{
src = imread( "fruits.jpg", 0 );
gauss3x3 = Mat(src.cols,src.rows,src.type()); //src.clone();
Mat kernelX = getGaussianKernel(3, 1);
Mat kernelY = getGaussianKernel(3, 1);
Mat kernelXY = kernelX * kernelY.t();
filter(src,gauss3x3,kernelXY);
namedWindow( window_name4, WINDOW_AUTOSIZE );
imshow(window_name4,gauss3x3);
}
void filter(Mat src, Mat dst, Mat kernel) {
cout << "filter" << endl;
for(int i=0; i<src.rows - 0; i++) {
for(int j=0; j<src.cols - 0; j++) {
float p = 0;
for(int k=0; k<kernel.rows; k++) {
for(int l=0; l<kernel.cols; l++) {
if(i+k < src.rows && j+l < src.cols) {
p += (src.at<uchar>(i + k,j + l) * kernel.at<uchar>(k,l));
}
}
}
if(i + kernel.rows/2 < src.rows && j + kernel.cols/2 < src.cols) {
dst.at<uchar>(i + kernel.rows/2,j + kernel.cols/2) = p / sum(kernel)[0];
}
}
}
}
我对解决方案一无所知。任何帮助将不胜感激。
答案 0 :(得分:1)
更改
kernel.at<uchar>(k,l)
为:
kernel.at<double>(k,l)
关键是内核的默认数据类型是CV_64F,它对应于double(documentation)。
另外,请检查输入图像是否严格为灰度。要支持颜色,您必须在开头检测图像类型并区分代码。要创建函数的颜色版本,您必须先使用.at<cv::Vec3b>
代替.at<uchar>
(这当然不是唯一必要的修改)。
我建议您将函数声明更改为:
void filter(const Mat& src, Mat& dst, const Mat& kernel) {
算法的其余部分看起来还不错,除了它可能很慢,如果你避免使用at
方法会更快,并且约束for循环所以不必检查你是否是要触摸图像边框,如果你在一些局部const变量中存储了不同的cv::Mat
尺寸,并在循环中使用它们。最后,sum(kernel)
是常量,因此您也可以预先计算该值。