【图像处理】第一次实验

1、任务说明


打开一幅图像,进行直方图均衡。将灰度线性变化,将灰度拉伸。

2、算法原理

1)        图像灰度化

  在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫做灰度值,灰度范围为0-255。一般有四种方法对彩色进行灰度化,分别为:

分量法,最大值法,平均值法和加权平均法。本实验中采用平均值法,即

           

2)        直方图均衡

  直方图表示数字图像中每一个灰度级与其出现频率间的统计关系。设有某一个灰度等级,属于该灰度等级的像素个数为nk,图像总像素个数为n,则直方图的定义为

                  

图像的直方图反映了图像的灰度范围、灰度分布、图像的平均亮度等。

  直方图均衡化也叫直方图均匀化,其目的是使所有灰度级出现的相对频率表相同,此时图像的熵最大,图像所包含的信息量最大。

  本实验处理在离散情况下的直方图修正。其中第k个灰度级出现的概率为:

             

  进行均匀化处理的变换函数为:

              

由新rk得到均衡化处理后的直方图。

  

3)        线性变化

  设输入图像的的灰度范围为[a,b],希望经过变换后的输出图像的灰度范围变化为[c,d],则变换函数T的表达式可以表示为

              

  根据不同的线性变换的斜率和截距,可以达到对图像不同的处理效果。当斜率大于1时,可以增加图像的对比度;当斜率在0与1之间时,

图像的对比度和整体效果都被削弱,灰度会被集中在一段区域上,灰度取值变窄,使图片趋于灰色。当斜率为负时,源图像较亮的区域变暗,

较暗的区域变量,可以实现反色效果。而当截距为正时,图像的亮度将会增加;截距为负时,图像的亮度将会降低。

4)        灰度拉伸(分段线性变化)

  为了突出感兴趣的目标或灰度区间,相对一致不感兴趣的灰度区间,可以采用分段线性变换。本实验采用常用的三段线性变换方法。

                  

  具体算法如下:

            

3、算法实现

1)        图像灰度化

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public void turnGray()

    {

        for
(int i=minx;i<width;i++)

        {

            for(int
j=miny;j<height;j++)

            {

                int
pixel=bi.getRGB(i,j);//获得8位的RGB值

                int
a = (pixel >> 24) & 0xff//提取前两位透明度

                int
r = (pixel >> 16) & 0xff//提取次两位,R值

                int
g = (pixel >> 8) & 0xff//提取再次两位,G值

                int
b = pixel & 0xff//提取最后两位,B值

                int
gray=(r+g+b)/3;   //计算平均值,得到像素灰度

                //根据灰度得到完整8位RGB值

                pixel= (a<<24)|(gray<<16)|(gray<<8)|gray;

                //将新的RGB值赋给像素点

                bi.setRGB(i, j,pixel);

            }

        }

        //输出图像

        try{

            ImageIO.write(bi, "jpg", new
File("D://gray.jpg"));

        }catch(IOException e)

        {

            e.printStackTrace();

        }

    }

  

2)        直方图均衡

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

public void histEqua()

    {

        int[] gray = new
int[sum]; //保存初始灰度值

        int[] newgray = new
int[sum]; //保存新灰度值

        int[] oldgrayscale = new
int[256]; //保存灰度累加值

        double[] grayscale = new
double[256];

        double[] cumulative = new
double[256];

        //统计所有像素中各灰度值出现的次数

        for(int
i=minx;i<width;i++){

            for(int
j=miny;j<height;j++){

                int
pixel=bi.getRGB(i, j);

                gray[height*i+j] = (pixel & 0xff);

                oldgrayscale[gray[height*i+j]]++;  

            }

        }

        for(int
i=0;i<256;i++){

             //计算原直方图中各灰度值出现的频率

            grayscale[i] = ((double)oldgrayscale[i])/sum;  

            for(int
j=0;j<=i;j++){

                 //计算累加后的直方图

                cumulative[i] += grayscale[j];

            }

             //得到新的映射关系

            cumulative[i] = (int)(cumulative[i]*256);  

        }

        

        BufferedImage hist_equa = new
BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //根据累加数组得到新的像素灰度

        for(int
i=minx;i<width;i++){

            for(int
j=miny;j<height;j++){

                newgray[height*i+j] = (int)cumulative[gray[height*i+j]];   

                int
pixel = (newgray[height*i+j])|(newgray[height*i+j]<<8)|(newgray[height*i+j]<<16);

                    hist_equa.setRGB(i, j, pixel);

            }

        }

//输出图像

        try
{

            ImageIO.write(hist_equa,"jpg", new
File("D://histEqua.jpg"));

        } catch
(IOException e) {

            e.printStackTrace();

        }

    }

  

3)        线性变换

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

public void linTrans()

    {

         //得到线性变换函数的斜率和截距

        double
slope;

        double
intercept;

        Scanner in = new
Scanner(System.in);

        System.out.println("输入线性变换斜率:");

        slope=in.nextDouble();

        System.out.println("输入线性变换截距:");

        intercept=in.nextDouble();

        

        BufferedImage lt =new
BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);

        for(int
i=minx;i<width;i++)

        {

            for(int
j=miny;j<height;j++)

            {

             //提取灰度值

                int
pixel = bi.getRGB(i, j);

                pixel = pixel & 0xff;

             //进行线性变换

                pixel = (int)(pixel*slope + intercept);

             //对超出边界的值进行处理

                if(pixel<0)

                    pixel=0;

                if(pixel>255)

                    pixel=255;

             //恢复为RGB值

                pixel = (pixel<<16)|(pixel<<8)|pixel;

                lt.setRGB(i, j, pixel);

            }

        }

        //输出图像

        try
{

            ImageIO.write(lt,"jpg", new
File("D://linTrans.jpg"));

        } catch
(IOException e) {

            e.printStackTrace();

        }

        

    }

  

4)        灰度拉伸

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

public void linStr()

    {

        int
x1,x2,y1,y2;

        double
k1,k2,b1,b2,k3,b3;

        //读入线性变换两份转折点的坐标

        Scanner in = new
Scanner(System.in);

        System.out.println("输入灰度拉伸第一个点的坐标,以空格分开:");

        x1 = in.nextInt();

        y1 = in.nextInt();

        System.out.println("输入灰度拉伸第二个点的坐标,以空格分开:");

        x2 = in.nextInt();

        y2 = in.nextInt();

        in.close();

        //计算三段线性变换各阶段的斜率与截距

        k1 = y1/x1;

        b1 = 0;

        k2 = (y2-y1)/(x2-x1);

        b2 = y1-k2*x1;

        k3 = (255-y2)/(255-x2);

        b3 = y2-k3*x2;

         

        

        BufferedImage ls =new
BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);

        for(int
i=minx;i<width;i++)

        {

            for(int
j=miny;j<height;j++)

            {//提取像素点灰度值

                int
pixel = bi.getRGB(i, j);

                pixel = pixel & 0xff;

              //分段进行线性变化

                if(pixel<x1)

                    pixel = (int)(pixel*k1  + b1);

                else
if(pixel>=x2)

                    pixel = (int)(pixel*k3  + b3);

                else

                    pixel = (int)(pixel*k2  + b2);

                //对于超出边界的值进行处理

                if(pixel<0)

                    pixel=0;

                if(pixel>255)

                    pixel=255;

                pixel = (pixel<<16)|(pixel<<8)|pixel;

                ls.setRGB(i, j, pixel);

            }

        }

        //输出图像

        try
{

            ImageIO.write(ls,"jpg", new
File("D://linStr.jpg"));

        } catch
(IOException e) {

            e.printStackTrace();

        }

    }

    

    private
BufferedImage bi=null;

    private
int width;

    private
int height;

    private
int minx;

    private
int miny;

    private
int
sum;

}

  

4、实验

源图像    
                     
        灰度图像

直方图均衡化        
         (-1,255)线性变换,相当于反色

灰度拉伸,某些像素得到凸显

【图像处理】第一次实验,布布扣,bubuko.com

时间: 2024-10-13 09:00:05

【图像处理】第一次实验的相关文章

第一次实验报告

实     验    报     告 课程:信息安全系统设计基础  班级:1353 姓名:黎静  学号:20135338 成绩:             指导教师:娄嘉鹏    实验日期:2015.9.20 实验密级:         预习程度:         实验时间:10:00--22:00 仪器组次:29         必修/选修: 选修            实验序号:1~12 第一次实验部分截图 一.Linux 简介 实验介绍 本节主要介绍 Linux 的历史,Linux 与 Wi

Java第一次实验要求

Java语言程序设计第一次实验要求 实验一 简单Java程序设计 一.实验目的 1. 熟悉Java开发及运行环境: 2. 掌握Java程序开发的基本步骤: 3. 了解Java程序开发中的常见错误及其解决办法. 二.实验要求 1. 使用记事本编写所给的Java程序: 2. 使用JDK中提供的javac编译程序: 3. 根据编译与运行过程中所获得的错误信息修改程序直至获得正确的结果: 4. 采用Java语言编写一个简单的应用程序. 三.实验步骤 1. Java开发环境的配置 (1)在命令行下运行ja

《信息安全系统设计基础》第一次实验报告--Linux 基础入门

<信息安全系统设计基础>第一次实验报告--Linux 基础入门 北京电子科技学院(BESTI) 实     验    报     告 课程:信息安全设计基础 班级:1352  姓名:孙小博  学号:20135217 成绩:            指导教师:娄嘉鹏      实验日期:2015.9.20 实验密级: 无     预习程度:           实验时间:12小时 仪器组次:17     必修/选修:必修   实验序号:01 实验目的与要求: 1. 学会安装使用Linux操作系统

20145216史婧瑶《Java程序设计》第一次实验报告

实验一 Java开发环境的熟悉(Linux + Eclipse) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程: 2.完成实验.撰写实验报告,实验报告模板见QQ群,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等).解决办法(空洞的方法如“查网络”.“问同学”.“看书”等一

Linux 基础入门第一次实验笔记

第一节.实验介绍 本节主要介绍 Linux 的历史,Linux 与 Windows 的区别等入门知识.如果你已经有过充分的了解,可以跳过本节,直接进入下一个实验. 一.Linux 为何物 Linux 就是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS ,至于操作系统是什么,就不用过多解释了,如果你学习过前面的入门课程,应该会有个基本概念了,这里简单介绍下操作系统在整个计算机系统中的角色. 我们的 Linux 也就是系统调用和内核那两层,当然直观的来看,我们使用

5233杨光--Linux第一次实验

学习计时:共14小时 读书:2小时 代码:7小时 作业:2小时 博客:3小时 一.学习目标 1. 能够独立安装Linux操作系统 2. 能够熟练使用Linux系统的基本命令 3. 熟练使用Linux中用户管理命令/系统相关命令/文件目录相关命令/打包压缩相关命令/比较合并相关命令/网络相关命令等 4. 熟练应用“搜索”进行举一反三的学习 二.学习资源 1. 课程资料:https://www.shiyanlou.com/courses/413   实验一,课程邀请码:W7FQKW4Y 2. Lin

大一C语言第一次实验:小学生教学系统

高级语言程序设计报告   打印版报告截止上交日期:2014年11 月 15 日 电子版报告发至[email protected]qq.com, 邮件标题写明报告次数序号姓名 序号 34 姓名 许恺 照片   成绩   E-MAIL及电话 18810556775 实习题目 第一次作业: 函数 七章实验题之素数探求2-6 七章实验题之小学生计算机辅助教学系统(用模块化程序设计方法完成六章之任务6即可) 此2题单独编程,即不在ACM系统中完成. 要求综合运用本章所学内容(注释.起名规则.缩进等).  

Java第一次实验报告——Java开发环境的熟悉

北京电子科技学院(BESTI) 实    验    报    告 课程名称:java程序设计实验      班级:1352         姓名:洪韶武      学号:20135219 成绩:                           指导教师:娄嘉鹏                    实验日期:2015.04.14 实验密级:                    预习程度:                               实验时间: 仪器组次:          

java第一次实验

一.实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 二.实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程: 2.完成实验.撰写实验报告 3.实验报告中统计自己的PSP(Personal Software Process)时间: 步骤 耗时 百分比 需求分析 30min 15% 设计 30min  15% 代码实现 60min  45% 测试  30min 15%