<冈萨雷斯图像处理>3.9-利用模糊集合(Fuzzy Sets)实现强度转换和空间滤波

利用模糊(Fuzzy)集合实现强度转换和空间滤波


基础

什么是模糊集合?

假设我们要将一批人(集合Z)分为年轻人和非年轻人,但我们很难说多少岁的人是真正的年轻人,通常只能说他计较年轻,他不算老。但是如何用数学的方式来表达呢?此时我们需要一个函数来表达这种功能。
我们知道18岁一定是年轻人,40岁一定不是年轻人。20~30岁之间的人我们只能用一个模糊的说法来表达(比较年轻)。这样我们可以得到一个隶属函数(Membership Function)如蓝色线段。 如图所示

111
纵轴表示的是程度(degree),我们可以看到20岁以前都是年轻人,30岁以后都不是年轻人,而20~30之间有一个年轻程度。
注意和概率的不同是:概率:这个人10%是年轻人(90%的概率不是年轻人);隶属函数:这人不太年轻了(但他是年轻人))

定义

相关数学定义和运算这里不做介绍,大家可以简单了解一下,下面直接上图。

一.模糊集使用举例

假设我们想要构建一个系统,该系统能够根据水果的颜色判断三种水果成熟状态。比如根据下面规则

IF 绿色:THEN 未熟;
IF 黄色:THEN 半熟;
IF 红色:THEN 成熟。

通常我们能够根据颜色的波长分辨颜色,比如绿色波长范围为:505-585nm,黄色:570-620nm,红色610-700nm。但波长会有部分叠加,说不清到底是哪种颜色。如图所示:
在这里插入图片描述 输入图像

这时我们给定一个水果颜色的波长,就能知道水果的颜色,但是我们还要根据颜色来对水果进行分类。此时我们需要另一个对应的模糊集(输出),如图:

在这里插入图片描述
此时,我们可以根据水果的成熟度对水果分为上面三类。
但现在的问题是,我们如何把输入输出联系起来。例如:水果颜色是红色且成熟的表示方式是两个模糊集合的交集,但这两个集合不同,所以交集为2维。如图:

在这里插入图片描述

上图得到了一个新的集合,该集合如图

在这里插入图片描述
在这里插入图片描述

我们给定一个红色水果z0,同时也会得到对应的隶属函数值。带入上式中就会得到一个关于红色红色和成熟的新的模糊集。

在这里插入图片描述

在这里插入图片描述

通过隶属函数值就可以剪切掉大于该值的部分。
可见z0是一个常数,变量只有v。同理,我们也能得到绿色和未熟黄色和半熟的模糊集。我们取这三个集合的并集就会得到一个拥有全部信息的模糊集。

在这里插入图片描述
在这里插入图片描述
至此,我们得到了一个关于特定输入的完整的输出。但是我们处理的还是模糊集合,因此我们需要逆变换将该集合变为一个特定的数值。根据一下公式得到:
在这里插入图片描述
我们通过给定z0的值就可以得到一个v0的值,即颜色对应成熟度的值。

二、使用模糊集合进行强度转换

1.使用模糊集合提高图像对比度

强度转换的一个应用是对比度增强。利用下面模糊集的规则提高对比度。

IF a pixel is dark, THEN make it darker.
IF a pixel is gray, THEN make it gary,
IF a pixlel is bright, THEN make it brighter.

我们写出输入,输出模糊集,如图

在这里插入图片描述
左图为输入,右图为输出。我们通过设定abc的值可以定义dark,gray,bright的范围。输出为三个亮度的常数值。输入matlab代码如下

function y = fuzzy_set(x,char,a,b,c)
if strcmp(char,'dark')
    if x < a
        y = 1;
    elseif x>a && x<=b
        y = 1-(x-a)/(b-a);
    else
        y = 0;
    end
elseif strcmp(char,'gray')
    if x < a
        y = 0;
    elseif x>=a && x<b
        y = (x-a)/(b-a);
    elseif x>=b && x<c
        y = 1-(x-b)/(c-b);
    else
        y = 0;
    end
else
    if x < b
        y = 0;
    elseif x>b && x<=c
        y = (x-b)/(c-b);
    else
        y = 1;
    end
end
    

只需要遍历图片全部像素点z0,应用下面公式可得到输出像素v0。
在这里插入图片描述

2.实现代码如下

clear;clc;
img_1 = imread('D:\design\Einstein.jpg');
img_1 = rgb2gray(img_1);
[m1,n1] = size(img_1);
outp_img = zeros(m1,n1);

vd = 0; vg = 127; vb = 255;
a = 105; b = 160; c = 180 ;  %参数要自己调一下

for i=1:m1
    for j=1:n1
        dark = fuzzy_set(double(img_1(i,j)), 'dark', a, b, c);
        gray = fuzzy_set(double(img_1(i,j)), 'gray', a, b, c);
        bright = fuzzy_set(double(img_1(i,j)), 'bright', a, b, c);
        v0 = (dark * vd + gray * vg + bright * vb) / (dark + gray + bright);
        outp_img(i,j) = v0;
    end
end

imshow(uint8(outp_img))

v0代表黑色,vd代表灰色,vg代表白色。参数需要自己调一下。

处理图像如图:
在这里插入图片描述

在这里插入图片描述
脸有点黑哈,参数自己调一下效果会有所改善。这里为什么不适用直方图均值处理呢?因为直方图均衡会损失像素值,效果比较浮夸,你们可以试一试。

三,使用模糊集进行空间滤波

1.基于模糊集的边界提取

之前学过Sobel算子,是基于梯度实现边界提取。我们得到的基本思想就是像素间的变化率。而基于模糊集也是这个思想,下面我们的提取规则:

IF 像素属于uniform region(非边界) THEN 使像素变白
ELSE 使像素变黑

白,黑,uniform region都是模糊集,没有“精确“的概念。因此我们要确定输入和输出模糊集。

我们可以通过中心像素和邻域像素的差值来判断是否为uniform region,因此我们通过以下规则定义Space Filtering。

IF d2 is zero AND d6 is zero THEN z5 is white
IF d6 is zero AND d8 is zero THEN z5 is white
IF d8 is zero AND d4 is zero THEN z5 is white
IF d4 is zero AND d2 is zero THEN z5 is white
ELSE z5 is black

注意:zero并不是真正的0,它也是一个模糊集,表示差异的程度。

在这里插入图片描述

那么zero,黑,白模糊集如下图:

在这里插入图片描述
代码如下:

if strcmp(char,'white')
    if x < a
        y = 0;
    else 
        y = (x-a)/(255-a);
    end
end
if strcmp(char,'black')
    if x < a
        y = 1 - x/a;
    else
        y = 0;
    end
end
if strcmp(char,'zero')
    p = (a+b)/2;
    if x < p
        if x < a
            y = 0;
        elseif x >= a && x < (a+p)/2
            y = 2 * ((x - a) / (p - a))^2;
        elseif x >= (a+p)/2 && x < p
            y = 1 - 2 * ((x - p) / (p - a))^2;
        else
            y = 1;
        end
    else
        if x > b
            y = 0;
        elseif x <= (2*p-a) && x > (3*p-a)/2
            y = 2 * ((b-x) / (p - a))^2;
        elseif x <= (3*p-a)/2 && x > p
            y = 1 - 2 * ((p - x) / (p - a))^2;
        else
            y = 1;
        end
    end
end

现在我们的思想就是:遍历图片的每一个像素点,通过上面的规则,来确定使该像素点是亮是暗。
由于上述IF的四个规则会分别得到一个隶属度z1,z2,z3,z4。且这4个规则是OR的关系,根据模糊集理论我们令z=max(z1,z2,z3,z4),可以得到输入规则的一个最终隶属度。

我们知道前4个规则表示领域与中心像素的差异,得到的结果也是表示一种差异程度,根据规则,我们要使该像素点变白,我们通过输入隶属度根据公式来影响亮度(隶属度越大代表对变白的影响越大,变黑影响越小),而ELSE中的隶属度值为1-z,这个值为对变黑的影响权重。最后通过反模糊得到一个确切的像素值。

2.程序实现代码

clear;clc;
img_1 = imread('D:\design\fs_spa_fil.jpg');
img_1 = rgb2gray(img_1);
[m1,n1] = size(img_1);
outp_img = zeros(m1,n1);
img_1_expand = zeros(m1+2,n1+2); 
img_1_expand([2:m1+1],[2:n1+1]) = img_1;
a = -20; b = 20; %zero所代表接近程度的范围

for i=2:m1+1
    for j=2:n1+1
        temp = img_1_expand(i,j);
        d2 = temp - img_1_expand(i-1,j);
        d4 = temp - img_1_expand(i,j-1);
        d6 = temp - img_1_expand(i,j+1);
        d8 = temp - img_1_expand(i+1,j);
        z1 = min(fuzzy_set(d2, 'zero', a, b),fuzzy_set(d6,'zero', a, b));
        z2 = min(fuzzy_set(d6, 'zero', a, b),fuzzy_set(d8,'zero', a, b));
        z3 = min(fuzzy_set(d8, 'zero', a, b),fuzzy_set(d4,'zero', a, b));
        z4 = min(fuzzy_set(d4, 'zero', a, b),fuzzy_set(d2,'zero', a, b));
        z = max([z1 z2 z3 z4]);
        bz = 1 - z; 
        deno = 0; nume = 0;
        for k=1:255
            Q = max(min(z,fuzzy_set(k,'white',30)), min(1-z,fuzzy_set(k,'black',210)));%30210是折线的角点,参数可以调。
            deno = Q + deno;
            nume = k * Q + nume;
        end
        outp_img(i-1,j-1) = nume / deno; %反模糊
    end
end

程序耗时10分多钟,可见计算量十分的大,所以对于较小规格的图片可以应用这种算法。结果如图:
在这里插入图片描述

在这里插入图片描述

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值