opencv 直方图_OpenCV 直方图匹配

直方图匹配又称直方图规定化。按照给定的直方图形状调整原先图像的直方图信息。直方图匹配使用到了直方图变换以及均衡化的思想,通过建立映射关系,使期望图像的直方图达到一种特定的形态。

直方图匹配的步骤如下:

1. 分别计算原图像与目标图像的累计概率分布

2. 分别对源图像和目标图像进行直方图均衡化操作

3. 利用映射关系使源图像直方图按照规定进行变换

示例代码如下:

#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>

int main(int argc,char* argv[])
{
    cv::Mat srcImage = cv::imread(R"(E:CodeBlocksdatalena.jpg)");
    cv::Mat dstImage = cv::imread(R"(E:CodeBlocksdatastarry_night.jpg)");
    if (!srcImage.data || ! dstImage.data)
    {
        std::cerr << "fail to load image" <<std::endl;
        exit(-1);
    }
    cv::resize(dstImage,dstImage,srcImage.size(),0,0,cv::INTER_LINEAR);
    cv::imshow("srcImage",srcImage);
    cv::imshow("testImage",dstImage);
    //统计直方图参数
    float srcCdf[256];
    float dstCdf[256];
    int srcAddTemp[256];
    int dstAddTemp[256];
    int histMatchMap[256];
    for(int i=0;i<256;i++)
    {
        srcCdf[i] = 0;
        dstCdf[i] = 0;
        srcAddTemp[i] = 0;
        dstAddTemp[i] = 0;
        histMatchMap[i] = 0;
    }
    float srcSumTemp = 0;
    float dstSumTemp = 0;

    int srcNPixel = srcImage.rows * srcImage.cols;
    int dstNPixel = dstImage.rows * dstImage.cols;
    int matchFlag = 0;
    //统计像素
    for(int i=0;i < srcImage.rows; i++)
    {
        for(int j = 0; j < srcImage.cols;j++)
        {
            srcAddTemp[(int)srcImage.at<uchar>(i,j)]++;
            dstAddTemp[(int)dstImage.at<uchar>(i,j)]++;
        }
    }
    //计算累计概率分布
    for(int i=0;i < 256;i++)
    {
        srcSumTemp += srcAddTemp[i];
        srcCdf[i] = srcSumTemp/ srcNPixel;
        dstSumTemp += dstAddTemp[i];
        dstCdf[i] = dstSumTemp/ dstNPixel;
    }
    //直方图匹配实现
    for(int i=0;i<256;i++)
    {
        float minMatchPara = 20;
        for(int j=0;j<256;j++)
        {
            if (minMatchPara > cv::abs(srcCdf[i] - dstCdf[j]))
            {
                minMatchPara = cv::abs(srcCdf[i] - dstCdf[j]);
                matchFlag = j;
            }
        }
        histMatchMap[i] = matchFlag;
    }
    //初始化匹配图像
    cv::Mat HistMatchImage = cv::Mat::zeros(srcImage.size(),CV_8UC3);
    cv::cvtColor(srcImage,HistMatchImage,cv::COLOR_BGR2GRAY);
    //映射
    for(int i=0;i<HistMatchImage.rows;i++)
    {
        for(int j=0;j<HistMatchImage.cols;j++)
        {
            HistMatchImage.at<uchar>(i,j) = histMatchMap[(int)HistMatchImage.at<uchar>(i,j) ];
        }
    }
     cv::imshow("ResultImage",HistMatchImage);
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

结果展示:

6de2f1af8ea92320ddff4fa80db9e3a6.png

70af5a30d0b234024e41e4eac26bea67.png

6ac5e780956089b9202f655f22674d3a.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值