• 直方图匹配原理与python、matlab实现


    直方图匹配本质上是让两幅图像的累积直方图尽量相似,累积直方图相似了,直方图也就相似了。

    把原图像img的直方图匹配到参考图像ref的直方图,包括以下几个步骤:

        1. 求出原图像img的累积直方图img_accu;

        2. 求出参考图像ref的累积直方图ref_accu;

        3. 灰度级g在img_accu中对应的值记为img_accu_g,找出ref_accu中与ref_accu_g最接近的值,记为ref_accu_G,记该值对应的灰度级为G;

        4. 根据g和G的对应关系,得到img经过匹配之后的直方图。

    为了说明该过程,我们举一个简单的例子,并把计算过程列在表格中。该例子中图像只有10个灰度级,总共3289个像素,如下图所示。

        

              (a) 原图像img的直方图                         (b) 参考图像ref的直方图

        

             (c) 原图像img的累积直方图                (d) 参考图像ref的累积直方图

    灰度级 ref直方图 ref累积直方图 img直方图
    img累积直方图 匹配之后的灰度级

     匹配之后的img累积直方图

     

    匹配之后的img直方图

    1 0 0 927 927(匹配第三列第七行的1137) 7  0  0
    2 0 0 690 1617(匹配第三列第八行的1672) 8  0  0
    3 20 20 535 2152(匹配第三列第九行的2362) 9  0  0
    4 112 132 450 2602(匹配第三列第九行的2362) 9  0  0
    5 221 353 334 2936(匹配第三列第十行的3289) 10  0  0
    6 334 687 221 3157(匹配第三列第十行的3289) 10  0  0
    7 450 1137 112 3269(匹配第三列第十行的3289) 10  927  927
    8 535 1672 20 3289(匹配第三列第十行的3289) 10  1617  690
    9 690 2362 0 3289(匹配第三列第十行的3289) 10  2152  985
    10 927 3289 0 3289(匹配第三列第十行的3289) 10  3289  687

     img在匹配之后的效果如下:

       

         (a) img的经过匹配之后的累积直方图       (b) img的经过匹配之后的直方图

     1. OpenCV-Python实现直方图匹配

    代码如下:

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = cv2.imread('C:\Users\admin\Desktop\original_img3\testimg\lena_300_500.jpg')
    ref = cv2.imread('C:\Users\admin\Desktop\original_img3\testimg\messi_300_500.jpg')
    
    out = np.zeros_like(img)
    _, _, colorChannel = img.shape
    for i in range(colorChannel):
        print(i)
        hist_img, _ = np.histogram(img[:, :, i], 256)   # get the histogram
        hist_ref, _ = np.histogram(ref[:, :, i], 256)
        cdf_img = np.cumsum(hist_img)   # get the accumulative histogram
        cdf_ref = np.cumsum(hist_ref)
    
        for j in range(256):
            tmp = abs(cdf_img[j] - cdf_ref)
            tmp = tmp.tolist()
            idx = tmp.index(min(tmp))   # find the smallest number in tmp, get the index of this number
            out[:, :, i][img[:, :, i] == j] = idx
    
    cv2.imwrite('C:\Users\admin\Desktop\lena.jpg', out)
    print('Done')

    效果如下:

     

    2. matlab实现直方图匹配

    程序如下:

    clear;
    % matching img's histogram to ref's histogram.
    path = 'C:\Users\admin\Desktop\original_img3\yijia0923_9\';
    ref = imread([path, '18.jpg']);
    img = imread([path, '21.jpg']);
    
    [H, W, colorChannel] = size(ref);
    out = zeros(H, W, colorChannel);
    for k = 1:colorChannel
        disp(k);
        hist_ref = imhist(ref(:, :, k));    % ref的直方图
        cumHist_ref = []; %ref的累积直方图
        for i=1:256
            cumHist_ref = [cumHist_ref sum(hist_ref(1:i))];
        end
     
        img1 = img(:, :, k);
        hist_img = imhist(img1); %img的直方图
        cumHist_img = []; %img的累积直方图
        for i=1:256
            cumHist_img = [cumHist_img sum(hist_img(1:i))];
        end
     
        for i=1:256
            tmp{i} = cumHist_ref - cumHist_img(i);
            tmp{i} = abs(tmp{i});               % 找到两个累积直方图距离最近的点
            [a, index(i)] = min(tmp{i});       % a是tmp{i}中最小的值,index是该值对应的下标
        end
     
        imgn = zeros(H,W);
        for i = 1:H
            for j = 1:W
                imgn(i,j) = index(img1(i,j)+1)-1;    % 由原图的灰度通过索引映射到新的灰度
            end
        end
        out(:, :, k) = imgn;
    end
    
    out=uint8(out);
    % imwrite(out, [path, 'new3.jpg']);
    figure; imshow(out); title('out')
    disp('Done');
  • 相关阅读:
    Fiddler抓包9-保存会话(save)
    Selenium2+python自动化61-Chrome您使用的是不受支持的命令行标记:--ignore-certificate-errors
    Fiddler抓包8-打断点(bpu)
    Fiddler抓包7-post请求(json)
    Java图片验证码
    servlet过滤器
    servlet监听器实现在线人数统计
    基于MVC模式的数据库综合练习
    JSTL详解
    初识EL表达式
  • 原文地址:https://www.cnblogs.com/picassooo/p/11504937.html
Copyright © 2020-2023  润新知