图像处理 实验一

2017-04-11 20:42:43 BabyGoodMorning 阅读数 1710

计算机图形图像实验

一. 图像处理初步

1. opencv安装,配置

VS配置opencv时,要修改三个地方,如下图

这里写图片描述

这里写图片描述

2.图像读取与显示

//CvArr
//CvMat 是CvArr的子类
//IplImage 是CvMat的子类,这里使用IplImage读取和显示文件
IplImage* img1 = cvLoadImage(imagename1);
cvShowImage("title", img);
cvWaitKey(0);
//释放内存
cvReleaseImage(&img1);
//销毁窗口
cvDestroyWindow("title");

3.图像信息

//宽
img->width
//高
img->height
//大小,这个好像与实际大小不太相符,不是很清楚
img->size

二. 图像基本运算

1.加减乘除

图形相加

void add() {

    cout << "图片加法运算" << endl;
    const char* imagename1 = "1_add.jpg";
    const char* imagename2 = "2_add.jpg";
    IplImage* img1 = cvLoadImage(imagename1);
    IplImage* img2 = cvLoadImage(imagename2);
    //获取两图片的最小宽、最小高
    int min_width = min(img1->width, img2->width);
    int min_height = min(img1->height, img2->height);
    //cvSetImageROI设置感兴趣区域,在此处进行操作
    cvSetImageROI(img1, CvRect(0, 0, min_width, min_height));
    cvSetImageROI(img2, CvRect(0, 0, min_width, min_height));
    //两图片相加
    cvAddWeighted(img1, 0.5, img2, 0.5, 0.0, img1);

    cvShowImage("图片相加", img1);

    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&img1);
    //销毁窗口
    cvDestroyWindow("图片相加");
}

实验结果:

这里写图片描述 这里写图片描述 这里写图片描述
图像一 图像二 结果

图形相减

void sub() {

    cout << "图片减法运算" << endl;
    const char* imagename1 = "1_sub.jpg";
    const char* imagename2 = "2_sub.jpg";
    IplImage* img1 = cvLoadImage(imagename1);
    IplImage* img2 = cvLoadImage(imagename2);

    int min_width = min(img1->width, img2->width);
    int min_height = min(img1->height, img2->height);
    cvSetImageROI(img1, CvRect(0, 0, min_width, min_height));
    cvSetImageROI(img2, CvRect(0, 0, min_width, min_height));

    cout << "图片一:" << img1->width  << " " << img1->height << endl;
    cout << "图片二:" << img2->width << " " << img2->height << endl;

    //cvAddWeighted(img1, 0.5, img2, -0.5, 0.0, img1);
    cvSub(img1, img2, img1);

    cvShowImage("图片相减", img1);

    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&img1);
    //销毁窗口
    cvDestroyWindow("图片相减");

}
这里写图片描述 这里写图片描述 这里写图片描述
图片一 图片二 结果

图像相乘

这里用的是二值蒙板图像与原图像相乘,为了实现一定的效果(去除背景),这里并没有直接使用opencv自带的乘法运算。而是对图像进行了遍历。如果二值蒙版图像在某像素处的值小于10,那么就将与图像在相同位置的值设为0,否则的话不变
void mul() {
    cout << "图片乘法运算" << endl;
    const char* imagename1 = "1_mul.jpg";
    const char* imagename2 = "2_mul.jpg";
    IplImage* img1 = cvLoadImage(imagename1);
    IplImage* img2 = cvLoadImage(imagename2);
    int min_width = min(img1->width, img2->width);
    int min_height = min(img1->height, img2->height);
    //cvSetImageROI(img1, CvRect(0, 0, min_width, min_height));
    //cvSetImageROI(img2, CvRect(0, 0, min_width, min_height));

    cout << "图片一:" << img1->width << " " << img1->height << endl;
    cout << "图片二:" << img2->width << " " << img2->height << endl;


    for (int i = 0; i < min_height; i ++) {
        uchar* ptr = (uchar*)(img1->imageData + i* img1->widthStep);
        uchar* ptr2 = (uchar*)(img2->imageData + i* img2->widthStep);
        for (int j = 0; j < min_width; j++) {
            if (ptr[3 * j] < 10)
                ptr2[3 * j] = 0;
            if (ptr[3 * j + 1] < 10)
                ptr2[3 * j + 1] = 0;
            if(ptr[3 *j + 2] < 10)
                ptr2[3 * j + 2] = 0;
            /*
            if (ptr[3 * j] == 0) {
                ptr2[3 * j] = ptr[3 * j + 1] = ptr[3 * j + 2] = 0;
            }
            */
        }
    }
    //cvMul(img2, img1, img1);

    cvShowImage("图片相乘", img2);

    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&img2);
    //销毁窗口
    cvDestroyWindow("图片相乘");
}
这里写图片描述 这里写图片描述 这里写图片描述
图片一 图片二 结果

图像相除

void div() {
    cout << "图片除法运算" << endl;
    const char* imagename1 = "2_add.jpg";
    const char* imagename2 = "3.jpg";
    //const char* imagename1 = "1_mul.jpg";
    //const char* imagename2 = "2_mul.jpg";
    IplImage* img1 = cvLoadImage(imagename1);
    IplImage* img2 = cvLoadImage(imagename2);
    int min_width = min(img1->width, img2->width);
    int min_height = min(img1->height, img2->height);
    cvSetImageROI(img1, CvRect(0, 0, min_width, min_height));
    cvSetImageROI(img2, CvRect(0, 0, min_width, min_height));

    cout << "图片一:" << img1->width << " " << img1->height << endl;
    cout << "图片二:" << img2->width << " " << img2->height << endl;

    cvDiv(img2, img1, img2);
    cvShowImage("图片相除", img2);

    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&img2);
    //销毁窗口
    cvDestroyWindow("图片相除");
}
这里写图片描述 这里写图片描述 这里写图片描述
图片一 图片二 结果

2.图像灰度级变换

图像求反

void reverse() {

    cout << "图片求反运算" << endl;
    const char* imagename = "2_mul.jpg";
    IplImage* img = cvLoadImage(imagename);

    for (int i = 0; i < img->height; i++) {
        uchar* ptr = (uchar*)(img->imageData + i* img->widthStep);
        for (int j = 0; j < img->width; j++) {
            ptr[3 * j] = 255 - ptr[3 * j];
            ptr[3 * j + 1] = 255 - ptr[3 * j + 1];
            ptr[3 * j + 2] = 255 - ptr[3 * j + i];

        }
    }

    cvShowImage("图片求反", img);

    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&img);
    //销毁窗口
    cvDestroyWindow("图片求反");

}
这里写图片描述 这里写图片描述
图片一 结果

3.图像变换

图像平移

void transform() {

    cout << "图片平移" << endl;
    const char* imagename = "2_add.jpg";
    IplImage* img = cvLoadImage(imagename);
    int dx, dy;
    cout << "请输入平移的宽和高, 如:50 50" << endl;
    cin >> dx >> dy;
    int height = img->height;
    int width = img->width;
    IplImage* res = cvCreateImage(cvSize(width, height), img->depth, img->nChannels);

    for (int i = 0; i < height; i++) {
        int pos_x = i + dx;
        if (pos_x < height && pos_x > -1) {
            uchar* ptr = (uchar*)(img->imageData + i* img->widthStep);
            uchar* ptr2 = (uchar*)(res->imageData + pos_x * res->widthStep);
            for (int j = 0; j < width; j++) {
                int pos_y = j + dy;
                if (pos_y < width && pos_y > -1) {
                    ptr2[3 * pos_y] = ptr[3 * j];
                    ptr2[3 * pos_y + 1] = ptr[3 * j + 1];
                    ptr2[3 * pos_y + 2] = ptr[3 * j + 2];
                }
            }
        }
    }

    cvShowImage("图片平移", res);
    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&res);
    //销毁窗口
    cvDestroyWindow("图片平移");

}
这里写图片描述 这里写图片描述
图片一 结果

图像缩放

这里输入图像宽和高的缩放倍数(> 0), 对图像进行放大和缩小

void zoom() {

    cout << "图片缩放" << endl;
    const char* imagename = "2_add.jpg";
    IplImage* img = cvLoadImage(imagename);
    float dx, dy;
    cout << "请输入图片宽和高的放大倍数,如:1 0.5" << endl;
    cin >> dx >> dy;
    int height = img->height;
    int width = img->width;
    IplImage* res = cvCreateImage(cvSize(width*dx, height*dy), img->depth, img->nChannels);

    //二维旋转的仿射变换矩阵  
    float m[6] = {dx, 0, 0, 0, dy, 0};
    CvMat M = cvMat(2, 3, CV_32F, m);
    //变换图像
    cvWarpAffine(img, res, &M, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS);

    cvShowImage("图片缩放", res);
    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&res);
    //销毁窗口
    cvDestroyWindow("图片缩放");

}
这里写图片描述 这里写图片描述
图片1 结果

图像旋转

图像旋转后,会导致图像显示不全,这里图像旋转后,大小会发生变化,使图片能够显示完全

void rotate() {

    cout << "图片旋转" << endl;
    const char* imagename = "2_add.jpg";
    IplImage* img = cvLoadImage(imagename);
    int degree;
    cout << "请输入图像旋转角度, 如:30" << endl;
    cin >> degree;
    double angle = degree  * CV_PI / 180.; // 弧度    
    double sina = sin(angle), cosa = cos(angle);

    int height = img->height;
    int width = img->width;
    int width_rotate = int(height * fabs(sina) + width * fabs(cosa));
    int height_rotate = int(width * fabs(cosa) + height * fabs(sina));
    cout << width << " " << height << endl;
    cout << width_rotate << " " << height_rotate << endl;

    IplImage* res = cvCreateImage(cvSize(width_rotate, height_rotate), img->depth, img->nChannels);

    //旋转中心 
    CvPoint2D32f center;
    center.x = float(width / 2.0);
    center.y = float(height / 2.0);
    //二维旋转的仿射变换矩阵
    float m[6];
    //float m[6];
    CvMat M = cvMat(2, 3, CV_32F, m);
    cv2DRotationMatrix(center, degree, 1, &M);
    m[2] += (width_rotate - width) / 2;
    m[5] += (height_rotate - height) / 2;
    //变换图像,其余值填充用白色
    cvWarpAffine(img, res, &M, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(255));  

    cvShowImage("图片旋转", res);
    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&res);
    //销毁窗口
    cvDestroyWindow("图片旋转");

}
这里写图片描述 这里写图片描述
图片1 结果

4.直方图均衡化处理

要求:自己编写函数,不能使用opencv自带函数(虽然我也不知道自带函数是什么…)

直方图均衡化是将原图像通过某种变换,得到一幅图像,整个图像灰度直方图为均匀分布的新图像的方法。

根据个人理解,直方图均衡化处理大致有如下步骤:

  1. 灰度直方图统计hist[0..L-1]: 图像有L灰度级(L=256,即8位灰度级),统计各个灰度级在图像中出现的次数,之后hist[]/=图像像素。
  2. 归一化累积直方图t[0..L-1]: 计算方式为t[x] = t[x-1] + s[x]
  3. 遍历图像,根据t[0..L-1],计算每一点新的像素值: f(x,y) = t[f(x,y)]*L
void equalization() {
    cout << "直方图均衡化" << endl;
    const char* imagename = "4.jpg";
    IplImage* img = cvLoadImage(imagename);
    double *hist = new double[256];
    double *t = new double[256];
    for (int i = 0; i < 256; i++) {
        hist[i] = 0;
        t[i] = 0;
    }

    for (int i = 0; i < img->height; i++) {
        uchar* ptr = (uchar*)(img->imageData + i* img->widthStep);
        for (int j = 0; j < img->width; j++) {
            hist[ptr[3 * j]]++;
            hist[ptr[3 * j + 1]]++;
            hist[ptr[3 * j + 2]]++;
        }
    }

    int result = img->width*img->height*3;

    t[0] = hist[0]/result;

    for (int i = 1; i < 256; i++) { 
        t[i] = t[i - 1] + (double)(hist[i]/result);
    }

    for (int i = 0; i < img->height; i++) {
        uchar* ptr = (uchar*)(img->imageData + i* img->widthStep);
        for (int j = 0; j < img->width; j++) {
            ptr[3 * j] = t[ptr[3*j]]*255;
            ptr[3 * j + 1]=t[ptr[3*j + 1]]*255;
            ptr[3 * j + 2]=t[ptr[3*j + 2]]*255;
        }
    }

    cvShowImage("直方图均衡化", img);

    cvWaitKey(0);
    //释放内存
    cvReleaseImage(&img);
    //销毁窗口
    cvDestroyWindow("直方图均衡化");
}
这里写图片描述 这里写图片描述
原图片 增强后图片
2018-04-10 00:00:51 weixin_39569242 阅读数 5180

实验一 图像的基本运算

一、实验目的

1)掌握点运算和代数运算的算法实现和概念

2)掌握和几何运算的算法实现和概念

2)掌握灰度变换和几何变换的基本方法

3)理解图像灰度直方图的概念

二、实验内容

1)任意选择几幅图像,查看其直方图,说明直方图和图像的对应关系。

2)任意选择几幅图像,对其进行灰度线性变换,结合以下情况分析输入图像和输出图像两者有何变化。

Ø  当斜率a>1时;

Ø  当斜率 a<1时;

Ø  当斜率a1b<0时;

Ø  当斜率a1b>0时;

Ø  当斜率a1b=0时;

Ø  当斜率a-1b=255时;

3)选择几幅图像,对其进行灰度拉伸,选择不同的拉伸参数,观察图像与原图有何不同,总结灰度拉伸的原理。

4)选择几幅图像对其进行几何变换,理解不同变换对图像产生的影响。

三、实验代码、结果、分析

1代码:

I=imread('C:\Users\xxxy\Desktop\1.jpg'); imshow(I)

I=rgb2gray(I); %真彩色图像转换为灰度图像,即灰度化处理

add=[];  tab1=zeros(1,256);

for n=0:255

    X=I==n;      add=[add;sum(sum(X))];

end;  

[a b]=size(I);   final=add/(a*b);

figure; imshow(I);

figure;  bar(0:255,final,'g')

figure; imhist(I)

结果:

                

1-1:原图                                                      1-2:灰度图

            

1-3 直方图                                                        1-4 纵坐标扩大直方图

分析:灰度直方图描述了该灰度级的像素的个数,其横坐标是灰度级,纵坐标是该灰度级出现的概率,eg:灰度值为100的概率可近似看做0.004

2代码

I=imread('C:\Users\xxxy\Desktop\2.jpg');    imshow(I)

y=a*I+b/255;    %线性点运算

figure   subplot(2,2,1);    imshow(y);

 

2-1  原图

a,b值分别如下,及结果图:

[1]a=2;b=10;                             [2]a=0.3;b=1;

             

2-2:a>1                                 2-3a<1

[3]a=1;b=-10;             [4]a=1;b=10;              [5]a=1;b=0;

       

2-4a1b<0        2-5a1b>0          2-6a1b=0

[7]a=-1;b=255;

 

                                               图2-7a-1b=255

分析:

[1] 如果a>1,输出图像的对比度变大,即图像变得更亮

[2] 如果a<1,输出图像的对比度减小,即图像变得更暗

[3] 如果a=1,b<0,输出图像下移,图像显示的更暗

[4] 如果a=1,b>0,输出图像上移,图像显示的更亮

[5] 如果a=1,b=0,输出图像不变,与原图像一样

[6] 如果a=1,b<0,输出图像下移,图像显示的更暗

[7] 如果a<0,b<0,输出图像亮区变暗,暗区变亮

3代码:

I=imread('C:\Users\xxxy\Desktop\3.jpg');imshow(I)

Y=double(I);  %将参数I转为双精度浮点类型

[M,N]=size(Y);

for i=1:M          

    for j=1:N              

        if Y(i,j)<=30                 

            Y(i,j)=I(i,j);             

        else if Y(i,j)<=150                  

                Y(i,j)=(200-30)/(160-30)*(I(i,j)-30)+30;            

            else   Y(i,j)=(255-200)/(255-150)*(I(i,j)-150)+200;             

            end

        end

    end

end

    figure(2);     imshow(uint8(Y))

结果:

                    

       3-1:原图                                     图3-2:灰度拉伸

分析:

将其小于30的灰度值不变,将30150的灰度值拉伸到30200,同时压缩150255的灰度值到200255之间

4代码:

I=imread('C:\Users\xxxy\Desktop\4.jpg'); imshow(I);  figure;

se = translate(strel(1), [100 100]);  

a = imdilate(I,se);     imshow(a)%平移      figure;

b = imresize(I,1.5)     imshow(b)%放大1.5   figure;

c= imresize(I,0.5)      imshow(c)%缩小0.5    figure;

[height,width,dim]=size(I);

tform1=maketform('affine',[-1 0 0;0 1 0;width 0 1]);

d1=imtransform(I,tform1,'nearest');  imshow(d1);%水平镜像 figure;

tform2=maketform('affine',[1 0 0;0 -1 0;0 height 1]);

d2=imtransform(I,tform2,'nearest');  imshow(d2);%垂直镜像 figure;

e1 = imrotate(I,90);  imshow(e1)%旋转90    figure;

e2 = imrotate(I,180); imshow(e2)%旋转180   figure;

e3 = imrotate(I,270);  imshow(e3)%旋转270  figure;

e4 = imrotate(I,360);  imshow(e4)%旋转360  figure;

          

        图4-1:原图                                  图4-2:平移

           

        图4-3:放大1.5                                                4-4:缩小0.5

                

           图4-5:水平镜像                                4-5:垂直镜像

            

              4-7:旋转90度                                       4-8:旋转180

                    

            图4-9:旋转270度                            4-10:旋转360度  

2018-05-26 02:21:17 klaus_x 阅读数 2222

数字图像处理 实验1

基本实验一 利用反转变化实现图像增强

实验代码:

f = imread('breast.tif');
g = 255-f;
subplot(121);
imshow(f);
subplot(122)
imshow(g)

实验现象图
1

基本实验2 利用matlab提供的直方图修正函数对图像做直方图均衡化处理

实验代码

I = imread('tire.tif');
J = histeq(I);
subplot(221); imshow(I);
subplot(222); imshow(J);
subplot(223); imhist(I,64);
subplot(224); imhist(J,64);

实验现象图
2

基本实验3 利用基本filter2函数和fspecial函数来实现图像平滑滤波效果,对一幅图像进行不同大小 模板的均值滤波

实验代码

I = imread('eight.tif');
J = imnoise(I,'salt & pepper',0.02);%加椒盐噪声
subplot(121);
imshow(I);
title('原始图像');
subplot(122);
imshow(J);
title('噪声图像');
IM1=filter2(fspecial('average',3),J)/255;%3*3均值滤波
IM2=filter2(fspecial('average',5),J)/255;%5*5均值滤波
IM3=filter2(fspecial('average',7),J)/255;%7*7均值滤波
IM4=filter2(fspecial('average',9),J)/255;%9*9均值滤波
figure;
subplot(221);imshow(IM1);title('3*3模板均值滤波');
subplot(222);imshow(IM2);title('5*5模板均值滤波');
subplot(223);imshow(IM3);title('7*7模板均值滤波');
subplot(224);imshow(IM4);title('9*9模板均值滤波');

实验现象图
3
思考题题目:
4.1 利用matlab对数变换实现个人照片的频谱图像的显示,并与原频谱进行对比。
4.2 利用matlab编程实现图像直方图均衡化算法。
4.2 利用matlab编程实现基于线性空间滤波的低通滤波器。

思考题1:

选取实验二中的图,可以随意,注意图片应该同新建的脚本文件在同一个文件夹内,图片格式不限,jpg,bmp等图片格式都可以。
2
左图为实验2原图,右图为对数变换后

程序源码:

I = imread('tire.tif');
tmp=double(I)+1;
Y=uint8(log(tmp))-1;
S=im2uint8(mat2gray(Y));
J = histeq(S);
subplot(221); imshow(I);
subplot(222); imshow(J);
subplot(223); imhist(I,64);
subplot(224); imhist(J,64);

思考题2:

直方图程序过程如下如下,这里我们还是选取实验2中的图像用来输出验证
同时注意像素点在[0,255]之间
3
程序源码如下:

I = imread('tire.tif');
subplot(121);
imshow(I);
title('灰度图·');

[R, C] = size(I);

% 统计每个像素值出现次数
cnt = zeros(1, 256);
for i = 1 : R
    for j = 1 : C
        cnt(1, I(i, j) + 1) = cnt(1, I(i, j) + 1) + 1;
    end
end

f = zeros(1, 256);
f = double(f); cnt = double(cnt);

%统计每个像素出现概率,得到直方图
for i = 1 : 256
    f(1, i) = cnt(1, i) / (R * C);
end

% 求累计概率,得到累计直方图
for i = 2 : 256
    f(1, i) = f(1, i - 1) + f(1, i);
end

% 用f数组实现像素值[0,255]的映射
for i = 1 : 256
    f(1, i) = f(1, i) * 255;
end

% 每个像素点映射
I = double(I);
for i = 1 : R
    for j = 1 : C
        I(i, j) = f(1, I(i, j) + 1);
    end
end

% 输出
I = uint8(I);
subplot(122);
imshow(I);
title('直方图均衡化');

实验输出比较:
4
左图为实验二matlab自带函数实现,右图为程序实现,效果可以;

思考题3

线性空间的低通滤波,这里低通滤波的类型不确定,拟定为高斯低通滤波
程序源码如下:

f = imread('tire.tif');
f = mat2gray(f,[0 255]);

[M,N] = size(f);
P = 2*M;
Q = 2*N;
fc = zeros(M,N);

for x = 1:1:M
    for y = 1:1:N
        fc(x,y) = f(x,y) * (-1)^(x+y);
    end
end

F = fft2(fc,P,Q);

H_1 = zeros(P,Q);
H_2 = zeros(P,Q);

for x = (-P/2):1:(P/2)-1
     for y = (-Q/2):1:(Q/2)-1
        D = (x^2 + y^2)^(0.5);
        D_0 = 60;
        H_1(x+(P/2)+1,y+(Q/2)+1) = exp(-(D*D)/(2*D_0*D_0));  
        D_0 = 160;
        H_2(x+(P/2)+1,y+(Q/2)+1) = exp(-(D*D)/(2*D_0*D_0));
     end
end

G_1 = H_1 .* F;
G_2 = H_2 .* F;

g_1 = real(ifft2(G_1));
g_1 = g_1(1:1:M,1:1:N);

g_2 = real(ifft2(G_2));
g_2 = g_2(1:1:M,1:1:N);        

for x = 1:1:M
    for y = 1:1:N
        g_1(x,y) = g_1(x,y) * (-1)^(x+y);
        g_2(x,y) = g_2(x,y) * (-1)^(x+y);
    end
end


%% -----显示-------
figure();
subplot(1,2,1);
imshow(f,[0 1]);
xlabel('a).原始图像');

subplot(1,2,2);
imshow(H_1,[0 1]);
xlabel('b).高斯低通滤波(D_{0}=60)');

实验得到图像:
5
参考地址1: https://blog.csdn.net/qq_29721419/article/details/53142320
参考地址2:https://www.cnblogs.com/zhaopengcheng/p/5386595.html

2018-01-08 18:51:21 aninstein 阅读数 7021

数字图像处理实验1-9点击下列链接有源码和链接:

1、什么是平滑处理?

    首先明白几个名词:
      (1)噪声:图像噪声是指存在于图像数据中的不必要的或多余的干扰信息。
1.高斯噪声:高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。常见的高斯噪声包括起伏噪声、宇宙噪声、热噪声和散粒噪声等等。除常用抑制噪声的方法外,对高斯噪声的抑制方法常常采用数理统计方法。高斯噪声最常见最普通的噪声。正态分布(高斯分布)的公式(高中知识不详解了):

2.椒盐噪声:椒盐噪声(salt-and-pepper noise)又称脉冲噪声,它随机改变一些像素值,在二值图像上表现为使一些像素点变白,一些像素点变黑(可以理解为随机概率的像素点变色)。
3.泊松噪声:泊松噪声,就是符合泊松分布的噪声模型,泊松分布适合于描述单位时间内随机事件发生的次数的概率分布。
泊松分布公式(高中知识不解释了):

几种噪声的对比:
(2)滤波:图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。
针对不同噪声,也有不同的滤波方式:
1.高斯滤波-------顾名思义解决高斯噪声问题。
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。方法主要有两种:
一是用离散化窗口滑窗卷积:就是选定一定大小的滑窗,遍历整个图像。比如我取像素9x9的矩阵滑窗,遍历整个图像进行卷积,一般我们都这样处理高斯噪声。
二是通过傅立叶变换。
只有当离散化的窗口非常大,用滑窗计算量非常大(即使用可分离滤波器的实现)的情况下,可能会考虑基于傅里叶变化的实现方法。
2.中值滤波-------解决椒盐噪声效果比较好。
中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。一般用于处理椒盐噪声。
3.均值滤波-------解决泊松噪声效果比较好。
均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。

回答题目的问题:平滑处理就是用滤波器去除噪声!

2、使用matlab添加噪声

先做一个guide:

打开图片和灰度代码:

% --- Executes on button press in 打开位图.
function openFile_Callback(hObject, eventdata, handles)
[filename,pathname]=uigetfile('*.bmp','select image');
str=[pathname filename];
[handles.I,handles.map]=imread(str);
guidata(hObject,handles);
axes(handles.axes1);
imshow(handles.I,handles.map);
% --- Executes on button press in 转化灰度.
function togray_Callback(hObject, eventdata, handles)
handles.I=rgb2gray(handles.I);% 转灰度图像
guidata(hObject,handles);
axes(handles.axes1);
imshow(handles.I,handles.map);

原图:


(1)添加高斯噪声

% --- Executes on button press in 高斯噪声.
function guassian_Callback(hObject, eventdata, handles)
handles=guidata(hObject);
I2=handles.I;
handles.J=imnoise(I2, 'gaussian', 0,0.05);% 添加高斯噪声,方差值为0.01
guidata(hObject,handles);
axes(handles.axes2);
imshow(handles.J);
效果:

(2)添加椒盐噪声:
% --- Executes on button press in  椒盐噪声.
function slat_Callback(hObject, eventdata, handles)
handles=guidata(hObject);
I2=handles.I;
handles.J=imnoise(I2, 'salt & pepper', 0.01);
guidata(hObject,handles);
axes(handles.axes2);
imshow(handles.J);
效果:

(3)泊松噪声

% --- Executes on button press in 泊松噪声.
function poission_Callback(hObject, eventdata, handles)
handles=guidata(hObject);
I2=handles.I;
handles.J=imnoise(I2, 'poisson');
guidata(hObject,handles);
axes(handles.axes2);
imshow(handles.J);

效果:

3、平滑处理(图像滤波)

(1)对添加了高斯噪声的图像进行高斯滤波:
% --- Executes on button press in 高斯滤波.
function gaussianwave_Callback(hObject, eventdata, handles)
handles=guidata(hObject);
J2=handles.J;
grayImg=J2;
gausFilter = fspecial('gaussian',[5,5],1.6);
H=imfilter(grayImg,gausFilter,'replicate');
axes(handles.axes3);
imshow(H,handles.map);
效果:

(2)使用中值滤波处理椒盐噪声
% --- Executes on button press in 中值滤波.
function midwave_Callback(hObject, eventdata, handles)
handles=guidata(hObject);
J2=handles.J;
Z=medfilt2(J2,[3,3]);
axes(handles.axes3);
imshow(Z,handles.map);
效果:
3)使用均值滤波处理泊松噪声
% --- Executes on button press in 均值滤波.
function avgwave_Callback(hObject, eventdata, handles)
handles=guidata(hObject);
J2=handles.J;
PSF=fspecial('average', 5);
P=imfilter(J2, PSF);
axes(handles.axes3);
imshow(P,handles.map);
效果:

2019-01-05 23:28:27 LVJINYANJY 阅读数 286
%读入1幅512*512的灰度图像,随即选取1000个像素,将其置0,计算置0后图像与原始图像间的峰值信噪比

% 读入图像函数- imread()
% 随即生成函数- randperm()
% 自定义PSNR函数

im = imread('11-Mary.bmp');
[M,N] = size(im);
P = randperm(M*N);
P = P(1:1000);
im1 = im;
im1(P) = 0;
subplot(121)
imshow(im)
subplot(122)
imshow(im1)
%
psnr = PSNR(im,im1);
fprintf('PSNR = %.2f dB\n',psnr);
function psnr = PSNR(x,y)
x = double(x);
y = double(y);
cnt = length(x(:));
mse = sum((x(:)-y(:)).^2)/cnt;
psnr = 10*log10(255^2/mse);
end