zoukankan      html  css  js  c++  java
  • opencv直方图均衡化算法及实现

    opencv直方图均衡化算法及实现

    1、为什么要直方图均衡化

    很多时候,我们的图片看起来的效果不是那么的清晰,这时候可以对图像进行一些处理来扩大图像像素值显示的范围。例如有些图像整体像素值偏低,图像中的一些特征看的不是很清晰,只是隐约看到一些轮廓痕迹,这时可以经过图像直方图均衡化之后使得图像看起来亮一些,也便于后续的处理。直方图均衡化是灰度变换的一个重要应用,它高效且易于实现,广泛应用于图像增强处理中。图像的像素灰度变化是随机的,直方图的图形高低不齐,直方图均衡化就是用一定的算法使直方图大致平和的方法。

    2、opencv中直方图均衡化算法

    opencv中直方图均衡化算法的输入图像需为八位单通道图像,也就是灰度图像。若想要处计算彩色图像的均衡化图,可以先将图像用split函数进行通道分离,分别处理每一个通道的图像,在用merge函数进行合并。算法实现步骤如下: 
    第一步:依次扫描原始灰度图像的每一个像素,计算出图像的直方图H。’ 
    第二步:进行归一化处理,即将0~255像素值的每一个像素值在图像中出现的次数除以图像的大小,得到归一化直方图。 
    第三步:计算直方图积分,公式:这里写图片描述 
    第四步:以H’作为查询表进行图像变换dst(x,y)=H’(src(x,y))

    #include <opencv2opencv.hpp>
    #include <iostream>
    
    using namespace cv;
    
    int main()
    {
        Mat srcImg,grayImg;//声明原始图和灰度度
        srcImg = imread("1.jpg");//载入原始图
        if(!srcImg.data)
        {
            std::cout<<"请确认路径下存在图片";
            return -1;
        }
        imshow("原始图",srcImg);//显示原始图
        cvtColor(srcImg,grayImg,CV_RGB2GRAY);//将rgb图像转化为灰度图
        int rowNumber = grayImg.rows;//得到行
        int colNumber = grayImg.cols;//得到列
        int sumNumber = rowNumber*colNumber;//得到图像整个像素个数
        Mat dstImg(rowNumber,colNumber,CV_8UC1,Scalar(0,0,0));//初始化直方图均衡化后的图
        double hist[256] = {0.00};//直方图
        double dhist[256] = {0.00};//直方图归一化图
        double Dhist[256] = {0.00};//直方图积分图,每一个像素点
        for(int i = 0;i<rowNumber;i++)//遍历原始图像,得到直方图
        {
            uchar* data = grayImg.ptr<uchar>(i);
            for(int j = 0;j<colNumber;j++)
            {
                int temp = data[j];//得到图像像素值
                hist[temp] = hist[temp]+1;//将相应像素值在直方图中加1
            }
        }
    
        for(int i = 0;i<256;i++)//遍历直方图,得到归一化直方图和积分图
        {       
            dhist[i] = hist[i]/sumNumber;//得到归一化图
            for(int j = 0;j<=i;j++)
            {
                Dhist[i] = Dhist[i] + dhist[j]; //得到积分图
            }
        }
    
    
        for(int i = 0;i<rowNumber;i++)//以积分图为查找表得到均衡化后的图
        {
            uchar* data1 = dstImg.ptr<uchar>(i);
            uchar* data2 = grayImg.ptr<uchar>(i);
            for(int j = 0;j<colNumber;j++)
            {
                int temp1 = data2[j]; //查找到原始图相应位置的像素值
                int temp2 = (int)(Dhist[temp1]*255); //在积分图中找到相应像素值的映射值
                data1[j] = temp2;//将映射值赋值给目标图像相应值
            }
        }
        imshow("均衡化后的图",dstImg);
        waitKey(0);
        return 0;
    }
    
  • 相关阅读:
    利用RxJava获取手机已安装的App的图片、应用名称和版本号
    个人开源作品,即时通讯App支持文本、语音、图片聊天
    将博客搬至CSDN
    Fragments之间的交互(实现参数传递)
    Android ListView用EditText实现搜索功能
    自定义控件--CircleImageView(类似于QQ、微信圆形头像自定义控件)
    js获取当天0点和24点的时间戳
    js将时间转换为时间戳在苹果手机上为NaN
    根据当前日期获取本周的日期数组
    js中页面加载完成后执行的几种方式及执行顺序
  • 原文地址:https://www.cnblogs.com/yumoye/p/10512693.html
Copyright © 2011-2022 走看看