【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 ...
随机推荐
- 【angular5项目积累总结】消息订阅服务
code import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable ...
- TextBox 控件
TextBox控件上有一个箭头,MultiLine属性,是多行显示 TextBox控件有System.Windows.TextBox类提供,提供了基本的文本输入和编辑功能 属性 A ...
- <深入理解JavaScript>学习笔记(1)_编写高质量JavaScript代码的基本要点
注:本文是拜读了 深入理解JavaScript 之后深有感悟,故做次笔记方便之后查看. JQuery是一个很强大的JavaScript 类库,在我刚刚接触JavaScript的就开始用了. JQuer ...
- Spring MVC 实现Excel的导入导出功能(2:Excel的导入优化和Excel的导出)
Excel的导入V2优化版 有些时候文件上传这一步骤由前端来处理,只将上传后的 URL 传输给后端(可以参考上一文中的图片上传功能),也就是导入请求中并不会直接处理 MultipartFile 对象, ...
- java工厂模式个人体会
上一边文章主要对单例模式做了一个总结,这篇文章主要对工厂模式也写一写个人的体会. 工厂模式是设计模式的一种,它主要是把实现产品对象的过程封装起来,然后提供给客户端相应的接口.工厂模式也是有3种,分别为 ...
- C#画个控件,指定字符特殊颜色显示
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- OpenStack IceHouse 部署 - 3 - 控制节点部署
Mysql部署配置 安装 安装mysql,mysql的python绑定 apt-get install mysql-server 安装过程中会要求设定mysql的root账户的密码,这里假定设为my ...
- python可变容器类型做函数参数的坑
def extendList(val, list=[]): # []默认参数的只指向一个地址 list.append(val) return list list1 = extendList(10) l ...
- Bzoj2395: [Balkan 2011]Timeismoney(最小乘积生成树)
问题描述 每条边两个权值 \(x,y\),求一棵 \((\sum x) \times (\sum y)\) 最小的生成树 Sol 把每一棵生成树的权值 \(\sum x\) 和 \(\sum y\) ...
- Bzoj3277:串
题面 传送门 Sol 广义\(sam\) 每个\(sam\)的状态开\(set\)记录属于哪些串 \(parent\)树上启发式合并\(set\) 然后每个串就在上面走,通过不停地跳\(parent\ ...