博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Matlab图像处理系列1———线性变换和直方图均衡
阅读量:6799 次
发布时间:2019-06-26

本文共 3610 字,大约阅读时间需要 12 分钟。

注:本系列来自于图像处理课程实验,用Matlab实现最主要的图像处理算法

图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境。灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对灰度值分布的变换。


1.灰度线性变换

(1)线性变换函数

原图向灰度值为g。通过线性函数f(x)=kx+b转换为f(g)得到灰度的线性变换。

(2)代码实现

Matlab中支持矩阵作为函数參数传入。定义一个线性转换函数,利用Matlab矩阵操作,用一行代码就可以对整个二维图像矩阵中所有点的灰度进行线性变换:

function [ new ] = LinearTransformFunc( original, k, d )    new = original * k + d;end

当中k和d是线性函数的斜率和截距。由用户输入指定,用户输入为空时赋予默认值:

  • input函数获取用户输入
  • isempty推断用户输入是否为空:
k = input('please input the slope(k) of grayscale linear transformation function:\n');b = input('please input the intercept(b) of grayscale linear transformation function:\n');if isempty(k)    k = 1;endif isempty(b)    b = 0;end

变换图像名也能够由用户input指定。默觉得lena图:

  • imread读出图片。返回值第一个是我们须要的灰度图(二维矩阵)
  • 对变换后的灰度图,用imshowfigure中显示图像
name = input('please input the name of image:\n');if isempty(name)     name = 'lena'; endoriginal = imread(strcat('../exp/', name, '.bmp'));transformed = LinearTransformFunc(original, k, b);figureimshow(transformed)

在这个实验的操作中说明怎样读入、显示,后面实验不在赘述

(3)执行结果

利用subplot作图,把原图和线性变换后的图像对照,线性变换函数是f(x)=2x+10:

这里写图片描写叙述

左图是原图像,右图是线性变换后图像。


2.灰度拉伸变换

(1)灰度拉伸变换和线性分段函数

灰度拉伸变换和线性变换类似,仅仅是是将灰度值做分段线性变换。分段函数控制点(x1,y1)(x2,y2)

这里写图片描写叙述

(2)代码实现

整个程序用户接口和流程和线性变换相同,仅仅是须要用户输入两个控制点,并传入下面的分段线性变换函数:

function [ new ] = StretchFunc(original, x1, y1, x2, y2 )    new = original;    w = size(new, 1);    h = size(new, 2);    k1 = y1 / x1;    dk1 = (y2 - y1) / (x2 - x1);    dk2 = (255 - y2) / (255 - x2);    for i = 1 : w        for j = 1 : h            x = new(i, j);            if x < x1                new(i, j) = k1 * x;            elseif x < x2                new(i, j) = dk1 * (x - x1) + y1;            else                new(i, j) = dk2 * (x - x2) + y2;            end        end    endend

这里不可避免要使用到for循环。

(3)执行结果

相同对照原图。默认控制点选取(-100,20)和(100,180)

这里写图片描写叙述


3.灰度直方图

(1)灰度直方图

灰度直方图就是对图像中每一个像素点的灰度值出现的频数或频率(归一化)的统计,那么我们直接遍历整个图像统计出每一个灰度值出现次数再做对应处理就可以。

(2)代码实现

首先须要遍历统计灰度,我在GrayScaleStatistic函数里完毕统计,区间[low, high]是目标灰度统计区间,默认是[0,255]:

function [ result ] = GrayScaleStatistic( original, low, high )    w = size(original, 1);    h = size(original, 2);    result = zeros(1, high - low + 1);    for i = 1 : w        for j = 1 : h            g = original(i, j);            if g >= low && g <= high                g = g - low + 1;                result(g) = result(g) + 1;             end        end    endend

然后就使用Matlab条形图作图函数bar完毕灰度图作图:

y = GrayScaleStatistic(original, low, high);x = low : 1 : high;bar(x, y)

对于题目要求的可输入灰度区间显示,我们要么不统计区间[low, high]以外的灰度值。要么直接所有统计但在作图时用xlim函数限制x轴取值范围:

xlim([low, high])

(3)执行结果

对照Matlab标准直方图作图函数histogram,结果例如以下:

这里写图片

也能够通过input输入限定区间。这里是[20,150]区间的灰度直方图:

这里写图片描写叙述

左右对照,效果一致。


4.直方图均衡化

(1)直方图均衡算法

直方图均衡主要用于增强动态范围偏小的图像的反差,其基本思想是把原始图像的直方图变换为均匀分布,从而增强灰度值的动态范围,以达到增强对照度的效果。

直方图均衡化算法例如以下

  1. 归一化灰度频数直方图。得到频率直方图sk
  2. sk计算频率累计直方图tk
  3. tk做取整扩展:tk = int[(L - 1) * tk + 0.5]。将直方图灰度映射尽量满整个灰度取值空间L
  4. 确定变换映射关系k->tk
  5. 依据映射关系变换图像灰度值

(2)代码实现

在脚本中调用Normalize函数直接得到均衡化后的图像。再统计直方图并显示。

Normalize函数例如以下:

function [ new ] = Normalize( original, v )    s = sum(v);    tv = v / s;    l = length(v);    for i = 2 : l        tv(i) = tv(i) + tv(i - 1);    end    tk = uint8(255 * tv + 0.5);    w = size(original, 1);    h = size(original, 2);    new = original;    for i = 1 : w        for j = 1 : h            new(i, j) = tk(original(i, j) + 1);        end    endend

说明:

  • tv先计算频率直方图,再通过累加得到累计直方图
  • tk依据累计直方图计算新的灰度映射关系
  • 最后遍历整个图像把原灰度转换成均衡化后的灰度值

当中有一下几点须要注意,也是Matlab图操作的注意点:

  • Matlab默认类型是double。对灰度值赋值时注意强制转换类型,保证类型一致
  • Matlab坐标起始从1開始。而灰度值是uint8的0-255。因此映射数组tk把原始灰度映射到变换后灰度时须要加1

(3)结果展示

pout.bmp是一副灰度分布较为集中的图像,因此图像对照度不高,显示较为模糊。使用直方图均值化,分散灰度分布从而增强对照度:

j

通过对照均衡先后直方图分布,能够发现:

  • 灰度分布不能全然平均化,是因为均值化算法中运用了取整运算,而不是离散值的全然均衡化
  • 得到的均衡化后直方图走势没有发生变化。因此图像没有失真

你可能感兴趣的文章
使用注解干掉大量if else和switch
查看>>
【本人秃顶程序员】实战并发-使用分布式缓存和有限状态机
查看>>
[MySQL光速入门]019 分别使用loop, while, repeat 来计算 从0加到100 答案
查看>>
浅析libuv源码-node事件轮询解析(2)
查看>>
区块链软件公司:区块链技术去中心化
查看>>
Python爬虫的基本概念、分类、学习路线以及爬取数据思路
查看>>
BCH或许才是真正的未来
查看>>
python编程:从入门到实践学习笔记-函数
查看>>
SpringBoot使用Nacos配置中心
查看>>
Java四种线程池的使用
查看>>
Go学习系列——第一个 Go程序
查看>>
关于ntp时间同步理论及配置参数-20170804
查看>>
loadrunner 脚本开发-int型变量和字符串的相互转换
查看>>
为什么运行NOVA命令总要报一个DEBUG,没找到原因,路过的大侠一起看看啊
查看>>
北电ERS1600,8300,8600交换机的基本技术-第十章接口高级特征
查看>>
我的友情链接
查看>>
20170830L08-06老男孩linux实战运维培训-Lamp系列之-Apache服务生产实战应用指南03
查看>>
我的友情链接
查看>>
今天面试IBM CSDL
查看>>
React+Node.js+Express+mongoskin+MongoDB
查看>>