【OpenCV】图像增强---灰度变换、直方图均衡化
图像增强的目的:改善图像的视觉效果或使图像更适合于人或机器的分析处理。通过图像增强,可以减少图像噪声,提高目标与背景的对比度,也可以增强或抑制图像中的某些细节。
---------------------------------------------------------------------------------------------------
灰度变换:把原图像的像素灰度经过某个函数变换成新图像的灰度。可分为直线灰度变换法和直方图修正法。
直线灰度变换法:线性、分段线性、非线性变换。
直方图修正法:直方图均衡化、直方图规定化。
---------------------------------------------------------------------------------------------------
图像直方图:是对像素的某种属性(如灰度、颜色、梯度等)分布进行统计分析的重要手段。
灰度直方图:是灰度级的函数,它反映了图像中每一灰度级出现的次数或频率。
直方图均衡化:把原始图像的直方图变换为均匀分布的形式,从而增加图像灰度的动态范围,以达到增强图像对比度的效果。
经过均衡化处理的图像,其灰度级出现的概率相同,此时图像的熵最大,图像所包含的信息量最大。
【注意,离散后是每块区域的概率相等,均衡化后并不是条直线哦。】
细节概念等省略......
---------------------------------------------------------------------------------------------------
线性灰度增强、对数变换、指数变换、直方图均衡化。代码见下(代码略粗糙...)【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】图像增强---灰度变换、直方图均衡化的更多相关文章
- opencv:图像直方图均衡化
// 直方图均衡化 Mat gray, dst; cvtColor(src, gray, COLOR_BGR2GRAY); equalizeHist(gray, dst); imshow(" ...
- opencv C++全局直方图均衡化
cv::Mat histogramEqualization(cv::Mat img){ int rows=img.rows; int cols=img.cols; cv::Mat grayScale= ...
- opencv图像直方图均衡化及其原理
直方图均衡化是什么有什么用 先说什么是直方图均衡化,通俗的说,以灰度图为例,原图的某一个像素为x,经过某个函数变为y.形成新的图.新的图的灰度值的分布是均匀的,这个过程就叫直方图均衡化. 图像直方图均 ...
- OpenCV计算机视觉学习(9)——图像直方图 & 直方图均衡化
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 1, ...
- OpenCV图像增强算法实现(直方图均衡化、拉普拉斯、Log、Gamma)
http://blog.csdn.net/dcrmg/article/details/53677739 1. 基于直方图均衡化的图像增强 直方图均衡化是通过调整图像的灰阶分布,使得在0~255灰阶 ...
- OpenCV——直方图均衡化(用于图像增强)
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...
- 灰度图像--图像增强 直方图均衡化(Histogram equalization)
灰度图像--图像增强 直方图均衡化(Histogram equalization) 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些 ...
- 图像增强算法(直方图均衡化、拉普拉斯、Log、伽马变换)
一.图像增强算法原理 图像增强算法常见于对图像的亮度.对比度.饱和度.色调等进行调节,增加其清晰度,减少噪点等.图像增强往往经过多个算法的组合,完成上述功能,比如图像去燥等同于低通滤波器,增加清晰度则 ...
- 直方图均衡化的 C++ 实现(基于 openCV)
这是数字图像处理课的大作业,完成于 2013/06/17,需要调用 openCV 库,完整源码和报告如下: #include <cv.h> #include <highgui.h&g ...
随机推荐
- webstorm中es6语法报错,.vue文件中es6语法报错
1.webstorm中es6语法报错,解决方法: 打开 Settings => Languages & Frameworks => Javascript把 Javascript L ...
- jsonp_百度联想
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...
- Linq lambda 匿名方法
课程6 委托.匿名方法.Lambda表达式.Linq查询表达式 上课日志1 一.委托的基本认识 提问:能不能把方法作为参数传递??? 也即是能不能声明一个能存放方法的变量呢——委托. 委托是一种数据类 ...
- 【SSH网上商城项目实战05】完成数据库的级联查询和分页
转自:https://blog.csdn.net/eson_15/article/details/51320212 上一节我们完成了EasyUI菜单的实现.这一节我们主要来写一下CategorySer ...
- spss C# 二次开发 学习笔记(三)——Spss .Net 开发
Spss .Net 二次开发的学习过程暂停了一段时间,今天开始重启. 之前脑残的不得了,本想从网上下载一个Spss的安装包,然后安装学习.于是百度搜索Spss,在百度搜索框的列表中看到Spss17.S ...
- Thymeleaf学习记录(6)--迭代及条件语法
迭代: 条件选择: IF-THEN: (if) ? (then) IF-THEN-ELSE: (if) ? (then) : (else) 默认: (value) ?: (defaultvalue) ...
- Bzoj4766: 文艺计算姬(Matrix-tree/prufer)
BZOJ 答案就是 \(n^{m-1}m^{n-1}\) \(prufer\) 证明: \(n\) 中的数字出现 \(m-1\) 次,\(m\) 中出现 \(n-1\) 次,根据 \(prufer\) ...
- 苹果ios,下拉菜单错位的问题(目前iphone x没发现有这个问题)
苹果手机,点击下拉框,再点击确认按钮,页面位置错乱(感觉背景整体往上移动了一段距离,并且,页面所有的元素都往上移了一定的距离),导致手机页面底部留白的问题,并且,元素实际位置跟页面位置不一致. 解决方 ...
- IDEA 的缓存问题
当IDEA还是使用以前的配置时,大概率是缓存问题,查看target,里面的内容就是编译好的东西,问题都是出自这里.
- 一键清理 Nexus 中无用的 Docker 镜像
现许多团队使用 Nexus 来管理 Docker 镜像,产品不断迭代,镜像仓库占用的磁盘空间也越来越大.由于 Nexus 的控制台并未提供批量操作镜像功能,清理镜像十分不便.本文分享一个清理 Nexu ...