3.1 直方图
概念:计算图像单个通道像素的分布。
步骤:把图像灰度级分为n个区间,计算每个区间像素的频数,把频数转化为频率,得到图像的直方图。如果图像有多个通道,分别计算每个通道的直方图。
Mat calcGrayHist02(const Mat &image,int bins)
{ // histogram矩阵
Mat histogram = Mat::zeros(Size(1, bins), CV_32SC1);
int step = int(256/bins);
//图像的高和宽
int rows = image.rows;
int cols = image.cols;
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
int index = int(image.at<uchar>(r, c));
index /= step;
if index>bins-1{index-=index}
histogram.at<int>(0, index) += 1;
}
}
return histogram;
}
3.2 线性变换
/*
Mat::convertTo(OutputArray m, int rtype, double alpha=1, double beta=0)
m 代表输出矩阵;
参数 rtype 是输出矩阵 m 的数据类型;
参数 alpha 和 beta 分别可以理解为线性变换中的 ? 和 ?。
*/
Mat I = (Mat_<uchar>(2, 2) << 10, 30, 31, 25);
Mat O;
I.convertTo(O, CV_8UC1, 1.5, 3);
//第二种方法
Mat O=1.5*I+20;
//线性变换的第三种方式
//convertScaleAbs(InputArray src, OutputArray dst, double alpha=1, double beta=0)
Mat I = (Mat_<uchar>(2, 2) << 0, 200, 23, 4);
Mat O;
convertScaleAbs(I,O,1.23,10);
3.3 直方图归一化
把图像直方图缩放到指定区间
/*
o(i,j) = o_min+ (img(i,j)-img_min)*((o_max-o_min)/(img_max-img_min))+
void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc
=0, Point* maxLoc=0, InputArray mask=noArray())
src 输入矩阵
minVal 最小值,double 类型指针
maxVal 最大值,double 类型指针
minLoc 最小值的位置索引,Point 类型指针
maxLoc 最大值的位置索引,Point 类型指针
*/
Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//找到 I 的最大值和最小值
double Imax, Imin;
minMaxLoc(I, &Imin, &Imax, NULL, NULL);
//设置 Omin和Omax
double Omin = 0, Omax = 255;
//计算 a 和 b
double a = (Omax - Omin) / (Imax - Imin);
double b = Omin - a*Imin;
//线性变换
Mat O;
convertScaleAbs(I, O, a, b);
//显示原图和直方图正规化的效果
imshow("I", I);
imshow("O", O);
归一化函数 normalize
/*
void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0,
int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray())
src 输入矩阵
dst 输出矩阵
alpha 系数
beta 系数
norm_type 归一化类型:一范数、二范、无穷大范数、NORM_MINMAX(先把像素值缩放到0~1之间,再乘以目标区间范围(最大减最小),最后加上目标区间的最小值。
dtype 数据类型
*/
#include<opencv2/core.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/highgui.hpp>
using namespace cv;
int main(int argc, char*argv[])
{
//输入图像
Mat src = imread(argv[1], CV_LOAD_IMAGE_ANYCOLOR);
if (!src.data)
return -1;
//直方图正规化
Mat dst;
normalize(src, dst, 255-20, 20, NORM_MINMAX, CV_8U);
}
3.4 Gamma变换
Gamma变换用来调节图像的亮度,先把图像I除以255得到I1,使得像素值归一化到0~1之间,再求I1的r次方。当r<1时,图像整体变亮;当r>1时,图像整体变暗。
/*
Gamma变换公式
img = (img/255.0)**y
对矩阵中的每一个值进行幂运算:
void pow(InputArray src, double power, OutputArray dst)
*/
//输入图像矩阵
Mat I = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
//灰度值归一化
Mat fI;
I.convertTo(fI, CV_64F, 1.0 / 255, 0);
//伽马变换
double gamma = 0.5;
Mat O;
pow(fI, gamma, O);//注意 O 和 fI 有相同的数据类型
//显示伽马变换后的效果
imshow("O",O);
O.convertTo(O, CV_8U, 255,0);
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » C++版OpenCV_03_图像增强
发表评论 取消回复