【OpenCV】图像增强---灰度变换、直方图均衡化

图像增强的目的:改善图像的视觉效果或使图像更适合于人或机器的分析处理。通过图像增强,可以减少图像噪声,提高目标与背景的对比度,也可以增强或抑制图像中的某些细节。

 ---------------------------------------------------------------------------------------------------

灰度变换:把原图像的像素灰度经过某个函数变换成新图像的灰度。可分为直线灰度变换法和直方图修正法。

直线灰度变换法:线性、分段线性、非线性变换。

直方图修正法:直方图均衡化、直方图规定化。

 ---------------------------------------------------------------------------------------------------

图像直方图:是对像素的某种属性(如灰度、颜色、梯度等)分布进行统计分析的重要手段。

灰度直方图:是灰度级的函数,它反映了图像中每一灰度级出现的次数或频率。

直方图均衡化:把原始图像的直方图变换为均匀分布的形式,从而增加图像灰度的动态范围,以达到增强图像对比度的效果。

经过均衡化处理的图像,其灰度级出现的概率相同,此时图像的熵最大,图像所包含的信息量最大。

【注意,离散后是每块区域的概率相等,均衡化后并不是条直线哦。】

  细节概念等省略......

---------------------------------------------------------------------------------------------------

 线性灰度增强、对数变换、指数变换、直方图均衡化。代码见下(代码略粗糙...)【ImageEnhance.cpp部分代码】

  1 //线性灰度增强
  2 bool CImageEnhance::GrayLinearTransform(Mat &src, Mat &dst, uchar c, uchar d)
  3 {
  4     int b=0,a=255;
  5     dst = src.clone();
  6     int row = dst.rows, col = dst.cols * dst.channels();
  7     uchar *cc = dst.data;
  8     for(int i = 0; i < row; ++i) {
  9         for(int j = 0; j < col; ++j) {
 10             int val = *cc;
 11             if(a > val) a = val;
 12             if(b < val) b = val;
 13             cc++;
 14         }
 15     }
 16     cc = dst.data;
 17     float k = float(d - c)/(b-a);
 18     //CString c1; c1.Format(_T("a=%d,b=%d,c=%d,d=%d,k=%.2f\n"), a,b,c,d,k);MessageBox(c1);
 19     for(int i = 0; i < row; ++i) {
 20         for(int j = 0; j < col; ++j) {
 21             int val = *cc;
 22             int s = (int)(k*(val - a) + c);
 23             *cc = s;
 24             cc++;
 25         }
 26     }
 27     return true;
 28 }
 29 //对数变换
 30 bool CImageEnhance::GraynoLinearlog(Mat &src, Mat &dst)  {
 31     dst = src.clone();
 32     int row = dst.rows, col = dst.cols * dst.channels();
 33     uchar *cc = dst.data;
 34     double k = 255 / log10(256.0);
 35     for(int i = 0; i < row; ++i) {
 36         for(int j = 0; j < col; ++j) {
 37             int val = *cc;
 38             *cc = k * log10(1.0*(val + 1));
 39             cc++;
 40         }
 41     }
 42     return true;
 43 }
 44 //指数变换
 45 bool CImageEnhance::GraynoLinearindex(Mat &src, Mat &dst)  {
 46     dst = src.clone();
 47     int row = dst.rows, col = dst.cols * dst.channels();
 48     uchar *cc = dst.data;
 49     double k = 1.0 / 255;
 50     for(int i = 0; i < row; ++i) {
 51         for(int j = 0; j < col; ++j) {
 52             int val = *cc;
 53             *cc = k * val * val;
 54             cc++;
 55         }
 56     }
 57     return true;
 58 }
 59
 60 MatND CImageEnhance::getHist1(Mat& image)
 61 {
 62     MatND hist;
 63     int channels[] = {0};
 64     int dims = 1;
 65     int histSize[] = {256};   //直方图箱子的个数
 66     float granges[] = {0, 255};
 67     const float *ranges[] = {granges};  //像素值范围
 68     //计算直方图
 69     calcHist(&image, 1, channels, Mat()/*不使用掩码*/, hist, dims/*这是一维的直方图*/, histSize, ranges);
 70     return hist;  //这里得到的hiat是256行一列的Mat
 71 }
 72
 73 //直方图均衡化
 74 bool CImageEnhance::Equalize_hist(cv::Mat& src,cv::Mat& dst)
 75 {
 76     //CMFC_Test_lyyDlg pic;
 77     MatND hist;
 78     int channels[] = {0};
 79     int dims = 1;
 80     int histSize[] = {256};   //直方图箱子的个数
 81     float granges[] = {0, 255};
 82     const float *ranges[] = {granges};  //像素值范围
 83     //计算直方图
 84     Mat image = src.clone();
 85     calcHist(&image, 1, channels, Mat()/*不使用掩码*/, hist, dims/*这是一维的直方图*/, histSize, ranges);
 86
 87     //MatND hist = getHist1(src);//pic.getHist(dst);
 88     float s[256];
 89     float p[256];
 90
 91     cv::Mat lookup(cv::Size(1, 256), CV_8U);
 92     int pixNum = src.cols * src.rows;//总像素个数
 93     for (int i =0; i <256; i++) {
 94         s[i] = hist.at<float>(i) / pixNum;
 95         if (i ==0) {
 96             p[i] = s[i];
 97         }
 98         else {
 99             p[i] = p[i -1] + s[i];
100         }
101     }
102     for (int i =0; i <256; i++) {
103         lookup.at <uchar>(i) = static_cast<uchar>(p[i]*255.0);
104     }
105
106     cv::LUT(src, lookup, dst);//创建矩阵,把一个像素值映射到另一个像素值
107     return true;
108 }

ImageEnhance.cpp

效果如下:

原图像:

线性灰度增强:我这里默认a和b表示原图像灰度值的最小与最大值。以下示例取c=255,d=0,效果为使图像负像,即黑变白,白变黑。

  

对数变换:(使图像的低灰度范围得以扩展而高灰度范围得以压缩,变换后的图像更符合人的视觉效果,因为人眼对高亮度的分辨率要求高于对低亮度的分辨率)

  

指数变换:(指数大于1。与对数变换相反。)

 直方图均衡化:

求原图像的灰度直方图代码:

 1 //获得直方图
 2 MatND getHistt(Mat& image){
 3     MatND hist;
 4     int channels[] = {0};
 5     int dims = 1;
 6     int histSize[] = {256};   //直方图箱子的个数
 7     float granges[] = {0, 255};
 8     const float *ranges[] = {granges};  //像素值范围
 9     //计算直方图
10     calcHist(&image, 1, channels, Mat()/*不使用掩码*/, hist, dims/*这是一维的直方图*/, histSize, ranges);
11     return hist;  //这里得到的hiat是256行一列的Mat
12 }
13 //  将图像的直方图展示出来
14 Mat draw_Hist(Mat &inputImage)
15 {
16     cv::MatND hist = getHistt(inputImage);
17     Mat showImage(256, 256, CV_8U,Scalar(255));
18     int i;
19     double maxValue = 0;
20     minMaxLoc(hist, 0, &maxValue, 0, 0);
21     for(i = 0; i < 256; i++)
22     {
23         float value = hist.at<float>(i);
24         int intensity = saturate_cast<int>(256 - 256 * (value/maxValue));
25         rectangle(showImage, Point(i, 256 - 1), Point((i+1)-1, intensity), Scalar(0));
26     }
27     //namedWindow("gray"); imshow("gray", showImage);
28     //cvMoveWindow("gray", 300, 300);
29     //waitKey(0);
30     return showImage;
31 }

 直方图显示:以下展示的 为以上的原图像以及直方图均衡化后的图像的  灰度直方图。

  

原文地址:https://www.cnblogs.com/GraceSkyer/p/8613042.html

时间: 2024-10-09 20:02:11

【OpenCV】图像增强---灰度变换、直方图均衡化的相关文章

opencv:图像直方图均衡化

// 直方图均衡化 Mat gray, dst; cvtColor(src, gray, COLOR_BGR2GRAY); equalizeHist(gray, dst); imshow("gray", gray); imshow("equalizeHist", dst); 原文地址:https://www.cnblogs.com/wbyixx/p/12246837.html

《OpenCV:直方图应用:直方图均衡化,直方图匹配,对比直方图》

直方图均衡化 直方图均衡化(Histogram Equalization)是直方图最典型的应用,是图像点运算的一种.对于一幅输入图像,通过运算产生一幅输出图像,点运算是指输出图像的每个像素点的灰度值由输入像素点决定,即: 直方图均衡化是通过灰度变换将一幅图像转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数过程.从分布图上的理解就是希望原始图像中y轴的值在新的分布中尽可能的展开.变换过程是利用累积分布函数对原始分布进行映射,生成新的均匀拉伸的分布.因此对应每个点的操作是寻找原始分布

opencv图像直方图均衡化及其原理

直方图均衡化是什么有什么用 先说什么是直方图均衡化,通俗的说,以灰度图为例,原图的某一个像素为x,经过某个函数变为y.形成新的图.新的图的灰度值的分布是均匀的,这个过程就叫直方图均衡化. 图像直方图均衡化作用:用来增强对比度. 这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候.通过这种方法,亮度可以更好地在直方图上分布.这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能. 这种方法对于背景和前景都太亮或者太

OpenCV——直方图均衡化(用于图像增强)

1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include <math.h> 4 5 using namespace cv; 6 using namespace std; 7 8 9 int main(int argc, char** argv) 10 { 11 Mat src,src_gray,dst; 12 //src = imread("3 input.bmp"); 13 s

Opencv图像识别从零到精通(10)-----直方图均衡化与直方图拉伸

 一.直方图均衡化 直方图均衡化是灰度变换的一个重要应用,广泛应用在图像增强处理中,它是以累计分布函数变换为基础的直方图修正法,可以产生一幅灰度级分布具有均匀概率密度的图像,扩展了像素的取值动态范围.许多图像的灰度值是非均匀分布的,其中灰度值集中在一个小区间内的图像是很常见的,直方图均衡化是一种通过重新均匀地分布各灰度值来增强图像对比度的方法,经过直方图均衡化的图像对二值化阈值选取十分有利.一般来说,直方图修正能提高图像的主观质量,因此在处理艺术图像时非常有用.直方图均衡化处理的中心思想是把原始

图像直方图均衡化增强opencv与C语言版

本文实现彩色图像的全局直方图均衡.分别对R/G/B三通道均衡,读写图片采用OpenCV.代码如下: #include <opencv2/opencv.hpp> //#include <cv.h> //#include <cxcore.h> //#include <highgui.h> #include <time.h> #include <stdio.h> #include <math.h> #include "

Qt 5.3 下OpenCV 2.4.11 开发(9)直方图均衡化

接着上面的章节,我们在 Histogram1D 类中加入一个新方法,即直方图均衡化的方法,现在贴出完整的代码,Histogram1D 类 头文件如下: #ifndef HISTOGRAM1D_H #define HISTOGRAM1D_H #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/opencv.hpp> using namespace

灰度图像--图像增强 直方图均衡化(Histogram equalization)

学习DIP第38天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不满意.有些网站转载了我的博文,很开心的是自己写的东西被更多人看到了,但不开心的是这段话被去掉了,也没标明转载来源,虽然这并没有版权保护,但感觉还是不太好,出于尊重文章作者的劳动,转载请标明出处!!!! 文章代码已托管,欢迎共同开发:https://github.com/Tony-Tan/DIPpro

opencv —— equalizeHist 直方图均衡化

直方图均匀化简介 从这张未经处理的灰度图可以看出,其灰度集中在非常小的一个范围内.这就导致了图片的强弱对比不强烈. 直方图均衡化的目的,就是把原始的直方图变换为在整个灰度范围(0~255)内均匀分布的形式,从而增加像素灰度值的动态范围,达到增强图像整体对比度的效果. 直方图均衡化的列表计算 序号 运算 步骤和结果 1 列出原始图灰度值 f(0 ≤ f ≤ L-1) 0 1 2 3 4 5 6 7 2 列出原始直方图(概率表达) 0.02 0.05 0.09 0.12 0.14 0.2 0.22