图像平滑之中值滤波(c++实现opencv medianBlur()函数)


一、概念

中值滤波中值滤波的实现原理是把数字图像中一点的值用该点的一个区域的各个点的值的中值代替。我们将一个点的特定长度或形状的邻域称为窗口,那么对于二维图像的中值滤波,一般采用33或55的窗口进行滤波,中值滤波和均值滤波有所区别,是一种非线性滤波。

二、opencv medianBlur()函数

函数原型:

CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );

参数说明:

src : 输入1、3、4通道图像;当ksize为3或5时,图像深度应为
CV_8U, CV_16U,或CV_32F,对于较大的滤波核,它只能是CV_8U。
dst : 输出图像,大小和类型与src相同。
ksize : l滤波核大小,它必须是奇数且大于1,例如:3,5,7…

三、c++实现中值滤波

//中值滤波
 void myMedianBlur(cv::Mat &src, cv::Mat &dst, int kSize)
 {
     //图像边界扩充
     int hh = (kSize - 1) / 2;
     int hw = (kSize - 1) / 2;
     cv::Mat Newsrc;
     cv::copyMakeBorder(src, Newsrc, hh, hh, hw, hw, cv::BORDER_REFLECT_101);//以边缘为轴,对称
     dst = cv::Mat::zeros(src.rows, src.cols, src.type());
     
     //遍历图像
     for (int i = 0; i < src.rows; i++)
     {
         for (int j = 0; j < src.cols; j++)
         {
             double valueSum = 0.0;
             #define SIZE 256
             int iVec[SIZE];
             for (int k = 0; k < hh*2+1; k++)
             {
                 for (int z = 0; z < hw*2+1; z++)
                 {
                     int srcValue = (int)Newsrc.at<uchar>(i + k, j + z);
                     valueSum += srcValue;
                     iVec[z+k] = srcValue;
                 }
             }
             //排序
             int iSize = hh*2+1 + hw*2+1;
             for(int h = 0; h < iSize;h++)
             {
                 for(int w = 1; w < iSize - h; w++)
                 {
                     int temp =  iVec[w-1];
                     if(iVec[w-1]>iVec[w])
                     {
                         iVec[w-1] = iVec[w];
                         iVec[w] = temp;
                     }
                 }
             }

             int iValue = iSize % 2 == 0 ? (iVec[iSize/2]+iVec[iSize/2-1])/2 : iVec[iSize/2];
            dst.at<uchar>(i, j) = (uchar)iValue;
         }
     }

 }

四、自己实现中值滤波和opencv中值滤波对比

    cv::Mat src;
    src = cv::imread("D:\\QtProject\\Opencv_Example\\median\\mreut.png", cv::IMREAD_GRAYSCALE);
    if (src.empty()) {
        cout << "Cannot load image" << endl;
        return;
    }
    cv::imshow("src", src);
    cv::Mat medianDst;
    cv::medianBlur(src, medianDst,7);
    cv::imshow("medianDst", medianDst);
    cv::Mat myMedianDst;
    myMedianBlur(src, myMedianDst,7);
    cv::imshow("myMedianDst", myMedianDst);

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值