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

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

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

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

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

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

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

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

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

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

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

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

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

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

 //线性灰度增强
bool CImageEnhance::GrayLinearTransform(Mat &src, Mat &dst, uchar c, uchar d)
{
int b=,a=;
dst = src.clone();
int row = dst.rows, col = dst.cols * dst.channels();
uchar *cc = dst.data;
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
int val = *cc;
if(a > val) a = val;
if(b < val) b = val;
cc++;
}
}
cc = dst.data;
float k = float(d - c)/(b-a);
//CString c1; c1.Format(_T("a=%d,b=%d,c=%d,d=%d,k=%.2f\n"), a,b,c,d,k);MessageBox(c1);
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
int val = *cc;
int s = (int)(k*(val - a) + c);
*cc = s;
cc++;
}
}
return true;
}
//对数变换
bool CImageEnhance::GraynoLinearlog(Mat &src, Mat &dst) {
dst = src.clone();
int row = dst.rows, col = dst.cols * dst.channels();
uchar *cc = dst.data;
double k = / log10(256.0);
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
int val = *cc;
*cc = k * log10(1.0*(val + ));
cc++;
}
}
return true;
}
//指数变换
bool CImageEnhance::GraynoLinearindex(Mat &src, Mat &dst) {
dst = src.clone();
int row = dst.rows, col = dst.cols * dst.channels();
uchar *cc = dst.data;
double k = 1.0 / ;
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
int val = *cc;
*cc = k * val * val;
cc++;
}
}
return true;
} MatND CImageEnhance::getHist1(Mat& image)
{
MatND hist;
int channels[] = {};
int dims = ;
int histSize[] = {}; //直方图箱子的个数
float granges[] = {, };
const float *ranges[] = {granges}; //像素值范围
//计算直方图
calcHist(&image, , channels, Mat()/*不使用掩码*/, hist, dims/*这是一维的直方图*/, histSize, ranges);
return hist; //这里得到的hiat是256行一列的Mat
} //直方图均衡化
bool CImageEnhance::Equalize_hist(cv::Mat& src,cv::Mat& dst)
{
//CMFC_Test_lyyDlg pic;
MatND hist;
int channels[] = {};
int dims = ;
int histSize[] = {}; //直方图箱子的个数
float granges[] = {, };
const float *ranges[] = {granges}; //像素值范围
//计算直方图
Mat image = src.clone();
calcHist(&image, , channels, Mat()/*不使用掩码*/, hist, dims/*这是一维的直方图*/, histSize, ranges); //MatND hist = getHist1(src);//pic.getHist(dst);
float s[];
float p[]; cv::Mat lookup(cv::Size(, ), CV_8U);
int pixNum = src.cols * src.rows;//总像素个数
for (int i =; i <; i++) {
s[i] = hist.at<float>(i) / pixNum;
if (i ==) {
p[i] = s[i];
}
else {
p[i] = p[i -] + s[i];
}
}
for (int i =; i <; i++) {
lookup.at <uchar>(i) = static_cast<uchar>(p[i]*255.0);
} cv::LUT(src, lookup, dst);//创建矩阵,把一个像素值映射到另一个像素值
return true;
}

ImageEnhance.cpp

效果如下:

原图像:

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

  

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

  

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

 直方图均衡化:

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

 //获得直方图
MatND getHistt(Mat& image){
MatND hist;
int channels[] = {};
int dims = ;
int histSize[] = {}; //直方图箱子的个数
float granges[] = {, };
const float *ranges[] = {granges}; //像素值范围
//计算直方图
calcHist(&image, , channels, Mat()/*不使用掩码*/, hist, dims/*这是一维的直方图*/, histSize, ranges);
return hist; //这里得到的hiat是256行一列的Mat
}
// 将图像的直方图展示出来
Mat draw_Hist(Mat &inputImage)
{
cv::MatND hist = getHistt(inputImage);
Mat showImage(, , CV_8U,Scalar());
int i;
double maxValue = ;
minMaxLoc(hist, , &maxValue, , );
for(i = ; i < ; i++)
{
float value = hist.at<float>(i);
int intensity = saturate_cast<int>( - * (value/maxValue));
rectangle(showImage, Point(i, - ), Point((i+)-, intensity), Scalar());
}
//namedWindow("gray"); imshow("gray", showImage);
//cvMoveWindow("gray", 300, 300);
//waitKey(0);
return showImage;
}

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

  

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

  1. opencv:图像直方图均衡化

    // 直方图均衡化 Mat gray, dst; cvtColor(src, gray, COLOR_BGR2GRAY); equalizeHist(gray, dst); imshow(" ...

  2. opencv C++全局直方图均衡化

    cv::Mat histogramEqualization(cv::Mat img){ int rows=img.rows; int cols=img.cols; cv::Mat grayScale= ...

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

    直方图均衡化是什么有什么用 先说什么是直方图均衡化,通俗的说,以灰度图为例,原图的某一个像素为x,经过某个函数变为y.形成新的图.新的图的灰度值的分布是均匀的,这个过程就叫直方图均衡化. 图像直方图均 ...

  4. OpenCV计算机视觉学习(9)——图像直方图 & 直方图均衡化

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...

  5. OpenCV图像增强算法实现(直方图均衡化、拉普拉斯、Log、Gamma)

    http://blog.csdn.net/dcrmg/article/details/53677739 1. 基于直方图均衡化的图像增强   直方图均衡化是通过调整图像的灰阶分布,使得在0~255灰阶 ...

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

    #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...

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

    灰度图像--图像增强 直方图均衡化(Histogram equalization) 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些 ...

  8. 图像增强算法(直方图均衡化、拉普拉斯、Log、伽马变换)

    一.图像增强算法原理 图像增强算法常见于对图像的亮度.对比度.饱和度.色调等进行调节,增加其清晰度,减少噪点等.图像增强往往经过多个算法的组合,完成上述功能,比如图像去燥等同于低通滤波器,增加清晰度则 ...

  9. 直方图均衡化的 C++ 实现(基于 openCV)

    这是数字图像处理课的大作业,完成于 2013/06/17,需要调用 openCV 库,完整源码和报告如下: #include <cv.h> #include <highgui.h&g ...

随机推荐

  1. Yii2:记一次尴尬的bug

    创建一个文章模块,写完添加动作之后,分配到视图,发现报错: Exception (Not Supported) 'yii\base\NotSupportedException' with messag ...

  2. json的使用(JObect,JsonData,JArray)

    JObect与JsonData的区别 JsonData是JObect的简化版本 2.转换过程容易出的bug JsonData:当里面存在null就无法转换 解决方案: JsonData teamjd ...

  3. HTML5--(3)过渡+动画+颜色+文本

    一.过渡transition transition-property指定属性名称 (如width.height.background-color.内外边距) all 所有属性都将获得过渡效果(默认) ...

  4. [javaSE] 多线程通信(等待-唤醒机制)

    两个线程操作同一个资源,比如,输入和输出,操作同一个对象,此时两个线程会争夺cpu的执行权,随机的进行切换.我们想实现先输入再输出,顺序的执行 目标对象定义一个标记字段,进行判断,wait()和not ...

  5. 撩课-Python-每天5道面试题-第1天

    一. 尽可能详细的描述出一个应用软件, 比如QQ, 在计算机中运行时涉及的软硬件, 以及说明我们编程的侧重点? 电脑开机, 从硬盘中(外部存储设备)加载操作系统(系统软件)到内存(内部存储设备), 并 ...

  6. JAVA基础之——使用idea创建maven项目 以及使用tomcat本地调试springmvc

    前言:关于这个话题网上有很多,本文旨在引导实战纠偏,理论偏少,如果按照步骤还不能达到本文目的,请留言. 1 环境准备 1.1 软件准备 idea:官方下载社区版,下载后安装 maven:Apache- ...

  7. Java线程入门第二篇

    Java线程通信方法 0.(why)每个线程都有自己的栈空间,我们要线程之间进行交流,合作共赢. 1.synchronized和volatile关键字 a)  看下面的synchronized关键字 ...

  8. Excel2010条件格式的位置

    以下是excel2010的条件格式设置方法(英文版) 具体使用方法可以参考 http://office.microsoft.com/zh-cn/excel-help/HA102809768.aspx

  9. Bootstrap网格

    首先了解一下,什么是网格? 在平面设计中,网格是一种由一系列用于组织内容的相交的直线(垂直的.水平的)组成的结构(通常是二维的).它广泛应用于打印设计中的设计布局和内容结构.在网页设计中,它是一种用于 ...

  10. HTTP协议笔记整理

    有人说过,精通HTTP协议能赢过95%的前端工程师,所以我毅然的踏上这条路,哈哈哈,接下来把自己的学习笔记整理出来. 我会从比较底层的模型开始: 1.网络的五层模型 2.TCP/IP协议 3.HTTP ...