OpenCv 实现高斯模糊
OpenCv Implementing Gaussian Blur
我想在 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];
}
}
}
}
我对解决方案一无所知。任何帮助将不胜感激。
改变
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 循环以便不必检查是否您将触摸图像边框,如果您将不同的 cv::Mat
大小存储在某个本地 const 变量中,并在循环中使用它们。最后,sum(kernel)
是常量,因此您也可以预先计算该值。
我想在 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];
}
}
}
}
我对解决方案一无所知。任何帮助将不胜感激。
改变
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 循环以便不必检查是否您将触摸图像边框,如果您将不同的 cv::Mat
大小存储在某个本地 const 变量中,并在循环中使用它们。最后,sum(kernel)
是常量,因此您也可以预先计算该值。