均值滤波 中值滤波 高斯平滑滤波

          均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标象素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。


          图像平滑用于去除图像中的噪声。高斯平滑,就是将每个像素的灰度值用其领域的加权平均值代替。该算法简单,能够有效去除高斯噪声。

       高斯平滑模板: 
          图像高斯平滑 - illidan - illidan的博客
//高斯平滑  中值滤波  均值滤波    
#include    
#include  

// 高斯平滑  
// 1. pImageData   图像数据  
// 2. nWidth       图像宽度  
// 3. nHeight      图像高度  
// 4. nWidthStep   图像行大小 
bool SmoothGauss(unsigned char *pImageData, int nWidth, int nHeight, int nWidthStep)
{
    int i = 0;
    int j = 0;
    int nValue = 0;
    unsigned char *pLine[3] = { NULL, NULL, NULL };
    int nTemplate[9] =
    {
        1, 2, 1,
        2, 4, 2,
        1, 2, 1
    };
    for (j = 1; j < nHeight - 1; j++)
    {
        pLine[0] = pImageData + nWidthStep * (j - 1);  //对应3行3列高斯模板矩阵中的 3行列。
        pLine[1] = pImageData + nWidthStep * j;
        pLine[2] = pImageData + nWidthStep * (j + 1);
        for (i = 1; i < nWidth - 1; i++)
        {
            nValue =
                (pLine[0][i - 1] * nTemplate[0] +    //对应3行3列矩阵中的各个点。
                pLine[0][i] * nTemplate[1] +
                pLine[0][i + 1] * nTemplate[2] +
                pLine[1][i - 1] * nTemplate[3] +
                pLine[1][i] * nTemplate[4] +
                pLine[1][i + 1] * nTemplate[5] +
                pLine[2][i - 1] * nTemplate[6] +
                pLine[2][i] * nTemplate[7] +
                pLine[2][i + 1] * nTemplate[8]) / 16;
            pLine[0][i - 1] = (unsigned char)nValue;
        }
    }
    return true;
}

int main()
{
    IplImage * image, *image2, *image3,*image4;
    image = cvLoadImage("C:\\Users\\lyb\\Documents\\Visual Studio 2013\\Projects\\ConsoleApplication 14_11_4\\11.bmp", 0);//以灰度图像的形式读入图片    
    cvNamedWindow("image_first-hand", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("image_jun_zhi", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("image_zhong_zhi", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("image_gauss", CV_WINDOW_AUTOSIZE);
    //cvSaveImage("E:\\image\\moon.jpg",image,0);    
    cvShowImage("image_first-hand", image);
    //cvWaitKey(0);    
    unsigned char * ptr, *dst;
    int i, j, m, n, sum, temp, r, s;
    image2 = cvCreateImage(cvGetSize(image), image->depth, 1);
    image3 = cvCreateImage(cvGetSize(image), image->depth, 1);
    image4 = cvLoadImage("C:\\Users\\lyb\\Documents\\Visual Studio 2013\\Projects\\ConsoleApplication 14_11_4\\11.bmp", 0);//以灰度图像的形式读入图片  
    //image4 = cvCreateImage(cvGetSize(image), image->depth, 1);
    //模板1 均值     
    int tem[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
    //也可以使用改进的高斯模板,但是效果相近     
    int tem2[9] = { 0 };//获取中值时用于排序   

    //高斯滤波
    unsigned char *pImageData1 = (unsigned char *)image4->imageData;
    int nWidth1 = image4->width;
    int nHeight1 = image4->height;
    int nWidthStep1 = image4->widthStep;
    if (SmoothGauss( pImageData1,nWidth1,nHeight1,nWidthStep1)==true)
        printf("%15s", "return"); //运行结果:return;

    //均值滤波3*3模板的均值    
    for (i = 0; i < image->height; i++){
        for (j = 0; j< image->width; j++){

            //边界处理    
            if (i == 0 || i == image->height || j == 0 || j == image->width){
                ptr = (unsigned char *)image->imageData + i*image->widthStep + j;
                dst = (unsigned char *)image2->imageData + i*image2->widthStep + j;
                *dst = *ptr; //边界值赋予源图像的值    
            }
            else {
                sum = 0;
                for (m = -1; m <= 1; m++){
                    for (n = -1; n <= 1; n++){
                        ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;

                        sum += (*ptr) * tem[3 * (m + 1) + n + 1];
                    }
                }
                dst = (unsigned char *)image2->imageData + i *image2->widthStep + j;
                *dst = (unsigned char)((sum + 4) / 9);//赋新值,四舍五入    
            }

        }
    }
    //中值滤波 在去除噪声的同时,图像的模糊程度比较小,比均值滤波更加适合    
    //冲击噪声或者称为椒盐噪声    
    for (i = 0; i < image->height; i++){
        for (j = 0; j< image->width; j++){

            //边界处理    
            if (i == 0 || i == image->height || j == 0 || j == image->width){
                ptr = (unsigned char *)image->imageData + i*image->widthStep + j;
                dst = (unsigned char *)image3->imageData + i*image3->widthStep + j;
                *dst = *ptr; //边界值赋予源图像的值    
            }
            else {
                temp = 0;
                //将3*3模板覆盖的值拷贝进数组,一边查找中值    
                for (m = -1; m <= 1; m++){
                    for (n = -1; n <= 1; n++){
                        ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;
                        tem2[3 * (m + 1) + n + 1] = *ptr;
                        //printf("%d",*ptr);    

                    }
                }
                //对数组进行冒泡排序    
                for (r = 0; r <8; r++){
                    for (s = 0; s< r - 1; s++){
                        if (tem2[s] > tem2[s + 1]){
                            temp = tem2[s];
                            tem2[s] = tem2[s + 1];
                            tem2[s + 1] = temp;
                        }
                    }
                }
                //printf("%d",tem2[4]);    
                //对新图赋予新值    
                dst = (unsigned char *)image3->imageData + i *image3->widthStep + j;
                *dst = (unsigned char)(tem2[4]);//赋新值    
            }

        }
    }



    cvShowImage("image_jun_zhi", image2);
    cvShowImage("image_zhong_zhi", image3);
    cvShowImage("image_gauss", image4);
    cvWaitKey(0);
    //cvSaveImage("E:\\image\\Dart2.bmp", image2, 0);
    //cvSaveImage("E:\\image\\Dart3.bmp", image3, 0);
    return 0;
}
原图:
均值滤波 中值滤波 高斯平滑滤波_第1张图片


高斯:
均值滤波 中值滤波 高斯平滑滤波_第2张图片

均值:
均值滤波 中值滤波 高斯平滑滤波_第3张图片

中值:
均值滤波 中值滤波 高斯平滑滤波_第4张图片



你可能感兴趣的:(均值滤波 中值滤波 高斯平滑滤波)