图像的均衡化和规定化

图像的均衡化

步骤

  1. 读取图像,得到行和列的值。并显示圆图像和对应的直方图。
  2. 编写Histeq函数。
  3. 统计各灰度出现次数,并算出概率,求出累计概率 $S$ 。
  4. 把每个灰度值 $a(i,j)$ 映射到 $S(a(i,j))$
  5. 结束

下面代码应该改进,在画直方图时可以返回 $num$ 数组,这样后面也不必统计了,实现的功能也和系统函数类似。

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
close all;
clear;

img = imread('pout.tif');
[row,col] = size(img);
subplot(2,2,1); imshow(img);
subplot(2,2,2); Imhist(img);

img_changed = Histeq(img);
subplot(2,2,3); imshow(img_changed);
subplot(2,2,4); Imhist(img_changed);

figure(2);
A = histeq(img);
B = Histeq(img);
A = A-B;
imshow(A);

function [] = Imhist(a) % 画直方图
    num = zeros(1,256);
    for i=1:256
        num(i) = sum(sum(a==(i-1)));
    end
    bar(0:255,num);
end

function [out] = Histeq(a)
    [row,col] = size(a);
    Pr = zeros(1,256);
    for i=1:256 % 每个灰度值出现次数
        Pr(i) = sum(sum(a==(i-1)));
    end
    Pr = double(Pr);
    Pr = Pr./(row*col); % 灰度值概率分布
    S = zeros(1,256);
    for i=1:256
        for j=1:i
            S(i) = S(i)+255*Pr(j);
        end
    end
    S = uint8(S);
    for i=1:row % 映射到新的灰度值
        for j=1:col
            a(i,j)=S(a(i,j));
        end
    end
    out = a;
end

图像的规定化

步骤:

TIM截图20191126184620

函数可以直接给两个函数图像,可以得到原图匹配到标准图的结果。

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
clear all;
close all;

orgin=imread('test.jpg');           % 读入原图像
standard=imread('flamingos.jpg');   % 读入标准图像

newimg = Hist_eq(orgin, standard);

subplot(2,3,1);imshow(orgin);title('原图');
subplot(2,3,4);imhist(orgin);title('原图');
subplot(2,3,2);imshow(standard);title('标准图');
subplot(2,3,5);imhist(standard);title('标准图');
subplot(2,3,3);imshow(newimg);title('匹配到标准图');
subplot(2,3,6);imhist(newimg);title('匹配到标准图');

function [out] = Hist_eq(orgin, standard)
    orgin=rgb2gray(orgin);              % 可能不是必须的
    standard=rgb2gray(standard);
    [m_o,n_o]=size(orgin); [m_s,n_s]=size(standard);
    orgin_hist=imhist(orgin)/(m_o*n_o); % 各灰度值的概率分布
    standard_hist=imhist(standard)/(m_s*n_s);
    
    startdard_value=[];                 % 标准图累积直方
    orgin_value=[];                     % 原图像累积直方

    for i=1:256                         % [a,x]相当于a拼接x
       startdard_value = [startdard_value, sum(standard_hist(1:i))]; 
       orgin_value = [orgin_value, sum(orgin_hist(1:i))];
    end

    for i=1:256							% 找到最接近的位置
        value{i} = abs(startdard_value-orgin_value(i));
        [~, index(i)] = min(value{i});  % 不需要最小值,只要下标
    end
    newimg=zeros(m_o,n_o);
    for i=1:m_o							% 映射
        for j=1:n_o
            newimg(i,j)=index(orgin(i,j)+1)-1;
        end
    end
    newimg = uint8(newimg);
    out = newimg;
end

此处的标准直方图是斜坡函数型的,自己构造的。

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
clear all;
close all;

orgin=imread('test.jpg');           % 读入原图像

for i=1:256							% 构造斜坡型直方图
    standard_hist(i) = 1000*i;
end
standard_hist=standard_hist/sum(standard_hist); % 灰度值分布概率

Newimg = histeq(orgin, standard_hist);
newimg = Hist_eq(orgin, standard_hist);

subplot(2,3,1);imshow(orgin);title('原图');
subplot(2,3,4);imhist(orgin);title('原图');
subplot(2,3,2);imshow(newimg);title('匹配到标准图');
subplot(2,3,5);imhist(newimg);title('匹配到标准图');
subplot(2,3,3);imshow(Newimg);title('系统函数');
subplot(2,3,6);imshow(newimg-Newimg);title('相减');
S=max(max(newimg-Newimg));

function [out] = Hist_eq(orgin, standard_hist)
    orgin=rgb2gray(orgin);
    [m_o,n_o]=size(orgin);
    orgin_hist=imhist(orgin)/(m_o*n_o);

    startdard_value=[];                 % 标准图累积直方
    orgin_value=[];                     % 原图像累积直方

    for i=1:256                         % 求图像累计概率
       startdard_value = [startdard_value, sum(standard_hist(1:i))]; 
       orgin_value = [orgin_value, sum(orgin_hist(1:i))];
    end

    for i=1:256                         % 保存相差最小的值的下标位置
        value{i} = abs(startdard_value-orgin_value(i));
        [~, index(i)] = min(value{i});
    end
    newimg=zeros(m_o,n_o);
    for i=1:m_o							% 做映射
        for j=1:n_o
            newimg(i,j)=index(orgin(i,j)+1)-1;
        end
    end
    newimg = uint8(newimg);
    out = newimg;
end

总结

其实均衡化和规定化可以合并为一个函数,毕竟库函数就是这么写的。

参考

matlab实现直方图规定化

# 使用单$作为行内数学公式分界符