灰度图像的直方均衡、线性变换与线性拉伸
2017-03-16 09:21
211 查看
前些天本来打算用VC6.0 + opencv1.0去学习图像处理,但后来发现还是VS + opencv2以上版本做比较顺手,所以装了vs2015,配置了环境什么的(VS2015配置opencv3.1.0)。在把环境配置好后,我就上网学习了别人写的代码,自己也开始写写简单的代码练手。因为作业的要求,所以写了实现了灰度图像的直方均衡、线性变换与线性拉伸的程序。如果对上述几个概念不是很清楚可以参考下这篇文章。
程序运行完后的效果图:
使用的原图:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace std; using namespace cv; Mat XianChange(Mat &img, double alt, int base)//灰度线性变化、 { CV_Assert(img.depth() != sizeof(uchar)); //声明只对深度8bit的图像操作 Mat temp = img.clone(); int channels = img.channels(); //获取图像channel int nrows = img.rows; //矩阵的行数 int ncols = img.cols*channels; //矩阵的总列数=列数*channel分量数 if (img.isContinuous()) //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组 { ncols *= nrows; nrows = 1; //一维数组 } //遍历像素点灰度值 for (int i = 0; i<nrows; i++) { uchar *p = temp.ptr<uchar>(i); //获取行地址 for (int j = 0; j<ncols; j++) { p[j] = alt*p[j] + base;//修改灰度值 if (p[j] > 255) p[j] = 255; if (p[j] < 0) p[j] = 0; } } return temp; } Mat XianStretch(Mat &img, int a, int b, int c, int d)//线性灰度拉伸,将[a,b]拉伸到[c,d] { CV_Assert(img.depth() != sizeof(uchar)); //声明只对深度8bit的图像操作 Mat temp = img.clone(); int channels = img.channels(); //获取图像channel int nrows = img.rows; //矩阵的行数 int ncols = img.cols*channels; //矩阵的总列数=列数*channel分量数 if (img.isContinuous()) //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组 { ncols *= nrows; nrows = 1; //一维数组 } //遍历像素点灰度值 for (int i = 0; i<nrows; i++) { uchar *p = temp.ptr<uchar>(i); //获取行地址 for (int j = 0; j<ncols; j++) { if (p[j] < a) p[j] = c / b * p[j]; else if (p[j] > a && p[j] < b) p[j] = (d - c) / (b - a) * (p[j] - a) + c; else p[j] = (255 - d) / (255 - b) *(p[j] - b) + d; } } return temp; } Mat HistogramEqu(Mat &img) //直方均衡 { CV_Assert(img.depth() != sizeof(uchar)); //声明只对深度8bit的图像操作 Mat temp = img.clone(); int grayNum[260] = { 0 }; int grayMap[260] = { 0 }; int channels = img.channels(); //获取图像channel int nrows = img.rows; //矩阵的行数 int ncols = img.cols*channels; //矩阵的总列数=列数*channel分量数 int allPixel = nrows*ncols; //图像的像素总数 int c; //用于计算累积分布概率 if (img.isContinuous()) //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组 { ncols *= nrows; nrows = 1; //一维数组 } //遍历像素点灰度值 for (int i = 0; i<nrows; i++) { uchar *p = temp.ptr<uchar>(i); //获取行地址 for (int j = 0; j<ncols; j++) { grayNum[p[j]]++; //原图像的直方图 } } for (int i = 0; i < 256; i++) //重新定义新的直方图 { c = 0; for (int j = 0; j<=i; j++) { c += grayNum[j]; grayMap[i] = int (255 * c / allPixel); } //printf("%d %d\n", i, grayMap[i]); } for (int i = 0; i < nrows; i++) //重新定义新的直方图 { uchar *p = temp.ptr<uchar>(i); //获取行地址 for (int j = 0; j < ncols; j++) { p[j] = grayMap[p[j]]; } } return temp; } int main() { string picName = "lena256.jpg"; Mat A = imread(picName, CV_LOAD_IMAGE_GRAYSCALE); //读入灰度图像 imshow("变换前", A); Mat B = XianChange(A, 1, 20);//根据需要设置不同的参数 imshow("线性变换后", B); Mat C = XianStretch(A, 10, 100, 20, 50);//根据需要设置不同的参数 imshow("线性拉伸后", C); Mat D = HistogramEqu(A); imshow("直方均衡后", D); waitKey(); return 0; }
程序运行完后的效果图:
使用的原图:
相关文章推荐
- java实现图像的直方图均衡以及灰度线性变化,灰度拉伸
- 数字图像点运算实践 (直方图均衡和分段线性拉伸)
- java实现图像的直方图均衡以及灰度线性变化,灰度拉伸
- 图像灰度化 直方均衡
- 数字图像处理MFC程序设计之灰度图像的线性变换
- 图像处理-基本算法之灰度拉伸
- 图像处理-基本算法之灰度均衡
- 灰度图像直方图均衡处理
- 图像灰度拉伸
- 【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
- (原)Opencv中直方图均衡和图像动态范围拉伸的代码
- 在MATLAB和OpenCV环境下写的灰度图像分段线性变换源码!
- 图像的灰度变换——图像旋转、图像的反色处理、对比度拉伸
- 灰度或者彩色图像的直方图均衡化+Opencv(可以选择其中的某一个区域进行均衡)
- 图像处理-基本算法之灰度均衡 form(同串口)
- matlab中图像灰度拉伸的问题
- CImgProcess::Histeq(CImgProcess * pTo) 图像的灰度 均衡化
- 灰度图像拉伸方法
- Android下常用的图像处理程序(灰度化、线性灰度变化、二值化)
- 【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理具体解释