博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
3.5 其他常见的灰度变换技术
阅读量:5012 次
发布时间:2019-06-12

本文共 9041 字,大约阅读时间需要 30 分钟。

1 ////https://blog.csdn.net/uestc_c2_403/article/details/72814206 2 #include "opencv2/highgui/highgui.hpp" 3 #include "opencv2/imgproc/imgproc.hpp" 4 #include "opencv2/opencv.hpp" 5 #include "opencv2/core/core.hpp" 6 #include 
7 using namespace std; 8 using namespace cv; 9 //图像线性变换操作10 cv::Mat linearTransform(cv::Mat srcImage, float a, int b)11 {12 if (srcImage.empty())13 {14 std::cout << "No data!" << std::endl;15 }16 const int nRows = srcImage.rows;17 const int nCols = srcImage.cols;18 cv:; Mat resultImage =19 cv::Mat::zeros(srcImage.size(), srcImage.type());20 //图像元素遍历21 for (int i = 0; i < nRows; i++)22 {23 for (int j = 0; j < nCols; j++)24 {25 for (int c = 0; c < 3; c++)26 {27 //矩阵at操作,检查下标防止越界28 resultImage.at
(i, j)[c] = saturate_cast
(a * (srcImage.at
(i, j)[c]) + b);29 }30 }31 }32 return resultImage;33 }34 int main()35 {36 cv::Mat srcImage = cv::imread("D:\\大海.jpg");37 if (srcImage.empty())38 {39 return -1;40 }41 42 cv::imshow("源图像", srcImage);43 //线性变换44 float a = 1.2;45 int b = 50;46 cv::Mat new_image = linearTransform(srcImage, a, b);47 cv::imshow("dst", new_image);48 cv::waitKey(0);49 return 0;50 }
View Code

 

3.5.2 对数变换

对数变换的公式为:

其中c为常数,r>=0 

对数变换目前我知道的有两个作用:

①因为对数曲线在像素值较低的区域斜率较大,像素值较高的区域斜率比较低,所以图像经过对数变换之后,在较暗的区域对比度将得到提升,因而能增强图像暗部的细节。

②图像的傅里叶频谱其动态范围可能宽达0~10^6。直接显示频谱的话显示设备的动态范围往往不能满足要求,这个时候就需要使用对数变换,使得傅里叶频谱的动态范围被合理地非线性压缩。

在OpenCV中,图像对数变换的实现可以直接通过对图像中每个元素运算上述公式完成,也可以通过矩阵整体操作来完成。下面的代码中给了三种方法,其中方法一和方法三都是通过矩阵整体操作来完成,第二种方法是对图像中每个元素操作来完成。方法一和方法三的区别是前者是对源图像作对数运算,后者是对目标图像作对数运算!

1 //https://blog.csdn.net/gone_huilin/article/details/53223118 2 //https://blog.csdn.net/spw_1201/article/details/53482877 3 #include 
4 #include
5 #include
6 #include
7 using namespace cv; 8 using namespace std; 9 //基于源图像的方法110 Mat logTransform1(Mat srcImage, int c)11 {12 if (srcImage.empty())13 cout << "No data" << endl;14 Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());15 add(srcImage, Scalar(1.0), srcImage); //计算 r+116 srcImage.convertTo(srcImage, CV_32F); //转化为32位浮点型17 log(srcImage, resultImage); //计算log(1+r)18 resultImage = c*resultImage;19 //归一化处理20 normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);21 convertScaleAbs(resultImage, resultImage);22 return resultImage;23 24 }25 //方法226 Mat logTransform2(Mat srcImage, float c)27 {28 if (srcImage.empty())29 cout << "No data" << endl;30 Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());31 double gray = 0;32 for (int i = 0; i < srcImage.rows; i++)33 {34 for (int j = 0; j < srcImage.cols; j++)35 {36 gray = (double)srcImage.at
(i, j);37 gray = c*log((double)(1 + gray));38 resultImage.at
(i, j) = saturate_cast
(gray);39 }40 }41 //归一化处理42 normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);43 convertScaleAbs(resultImage, resultImage);44 return resultImage;45 }46 //方法347 Mat logTransform3(Mat srcImage, float c)48 {49 if (srcImage.empty())50 cout << "No data" << endl;51 Mat resultImage = Mat::zeros(srcImage.size(), srcImage.type());52 srcImage.convertTo(resultImage, CV_32F); //图像类型转换53 resultImage = resultImage + 1; //图像矩阵元素加154 log(resultImage, resultImage);55 resultImage = c*resultImage;56 //归一化处理57 normalize(resultImage, resultImage, 0, 255, NORM_MINMAX);58 convertScaleAbs(resultImage, resultImage);59 return resultImage;60 }61 int main()62 {63 Mat srcImage = imread("D:\\大海.jpg");64 if (!srcImage.data)65 return -1;66 cvtColor(srcImage, srcImage, CV_BGR2GRAY);67 imshow("srcImage", srcImage);68 float c = 1.2;69 Mat resultImage;70 double tTime;71 tTime = (double)getTickCount();72 const int nTimes = 100;73 for (int i = 0; i < nTimes; i++)74 {75 resultImage = logTransform3(srcImage, c);76 }77 tTime = 1000 * ((double)getTickCount() - tTime) / getTickFrequency();78 tTime /= nTimes;79 cout << tTime << endl;80 imshow("resultImage", resultImage);81 waitKey(0);82 return 0;83 }
View Code

 

 

参考:

 

3.5.3 对比度拉伸

1 //https://blog.csdn.net/spw_1201/article/details/53486594 2 #include 
3 #include
4 #include
5 #include
6 using namespace cv; 7 using namespace std; 8 Mat contrastStretch(Mat srcImage) 9 {10 Mat resultImage = srcImage.clone();//"=";"clone()";"copyTo"三种拷贝方式,前者是浅拷贝,后两者是深拷贝。11 int nRows = resultImage.rows;12 int nCols = resultImage.cols;13 //判断图像的连续性14 if (resultImage.isContinuous())15 {16 nCols = nCols*nRows;17 nRows = 1;18 }19 //图像指针操作20 uchar *pDataMat;21 int pixMax = 0, pixMin = 255;22 //计算图像的最大最小值23 for (int j = 0; j < nRows; j++)24 {25 pDataMat = resultImage.ptr
(j);//ptr<>()得到的是一行指针26 for (int i = 0; i < nCols; i++)27 {28 if (pDataMat[i] > pixMax)29 pixMax = pDataMat[i];30 if (pDataMat[i] < pixMin)31 pixMin = pDataMat[i];32 }33 }34 //对比度拉伸映射35 for (int j = 0; j < nRows; j++)36 {37 pDataMat = resultImage.ptr
(j);38 for (int i = 0; i < nCols; i++)39 {40 pDataMat[i] = (pDataMat[i] - pixMin) * 255 / (pixMax - pixMin);41 }42 }43 return resultImage;44 }45 int main()46 {47 Mat srcImage = imread("D:\\小女孩与熊.jpg");48 if (!srcImage.data)49 return -1;50 Mat srcGray;51 cvtColor(srcImage, srcGray, CV_RGB2GRAY);52 imshow("srcGray", srcGray);53 Mat resultImage = contrastStretch(srcGray);54 imshow("resultImage", resultImage);55 waitKey(0);56 return 0;57 }
View Code

 

3.5.4 灰度级分层

1 //https://blog.csdn.net/spw_1201/article/details/53487746 2 #include 
3 #include
4 #include
5 #include
6 using namespace cv; 7 using namespace std; 8 Mat grayLayered(Mat srcImage) 9 {10 Mat resultImage = srcImage.clone();11 int nRows = resultImage.rows;12 int nCols = resultImage.cols;13 if (resultImage.isContinuous())14 {15 nCols = nRows*nCols;16 nRows = 1;17 }18 uchar *pDataMat;19 int controlMin = 150;20 int controlMax = 200;21 for (int j = 0; j < nRows; j++)22 {23 pDataMat = resultImage.ptr
(j);24 for (int i = 0; i < nCols; i++)25 {26 //第一种方法:二值映射27 if (pDataMat[i] > controlMin)28 pDataMat[i] = 255;29 else30 pDataMat[i] = 0;31 //第二种方法:区域映射32 /*if (pDataMat[i] > controlMin && pDataMat[i] < controlMax)33 pDataMat[i] = controlMax;*/34 }35 }36 return resultImage;37 }38 int main()39 {40 Mat srcImage = imread("D:\\大海.jpg");41 if (!srcImage.data)42 return -1;43 Mat srcGray;44 cvtColor(srcImage, srcGray, CV_BGR2GRAY);45 imshow("srcGray", srcGray);46 Mat resultImage = grayLayered(srcGray);47 imshow("resultImage", resultImage);48 waitKey(0);49 return 0;50 }
View Code

 

3.5.5 灰度比特平面

1 //https://blog.csdn.net/gone_huilin/article/details/53223151 2 #include 
3 #include
4 #include
5 #include
6 #include
7 using namespace cv; 8 using namespace std; 9 void showMBitPlan(cv::Mat srcImage)10 {11 int nRows = srcImage.rows;12 int nCols = srcImage.cols;13 // 图像连续性判断14 if (srcImage.isContinuous())15 {16 nCols = nCols * nRows;17 nRows = 1;18 }19 // 图像指针操作20 uchar *pSrcMat;21 uchar *pResultMat;22 cv::Mat resultImage = srcImage.clone();23 int pixMax = 0, pixMin = 0;24 for (int n = 1; n <= 8; n++)25 {26 // 比特平面分层像素构成27 pixMin = pow(2, n - 1);28 pixMax = pow(2, n);29 for (int j = 0; j < nRows; j++)30 {31 // 获取图像数据指针32 pSrcMat = srcImage.ptr
(j);33 pResultMat = resultImage.ptr
(j);34 for (int i = 0; i < nCols; i++)35 {36 // 相应比特平面层二值化37 if (pSrcMat[i] >= pixMin && pSrcMat[i] < pixMax)38 pResultMat[i] = 255;39 else40 pResultMat[i] = 0;41 }42 }43 // 比特平面层输出 44 char windowsName[20];45 sprintf_s(windowsName, "BitPlane %d", n);46 imshow(windowsName, resultImage);47 }48 }49 int main()50 {51 cv::Mat srcImage = cv::imread("D:\\大海.jpg");52 if (!srcImage.data)53 return 0;54 cv::Mat srcGray;55 cvtColor(srcImage, srcGray, CV_BGR2GRAY);56 imshow("srcGray", srcGray);57 showMBitPlan(srcGray);58 cv::waitKey(0);59 return 0;60 }
View Code

 

转载于:https://www.cnblogs.com/thebreakofdawn/p/9489562.html

你可能感兴趣的文章
java性能调优工具
查看>>
C# 其他的Url 文件的路径转化为二进制流
查看>>
cmake使用
查看>>
ios7上隐藏status bar
查看>>
构造方法和全局变量的关系
查看>>
python3基础05(有关日期的使用1)
查看>>
ArrayList的使用方法
查看>>
面向对象高级
查看>>
Bitwise And Queries
查看>>
打印Ibatis最终的SQL语句
查看>>
HBase之八--(3):Hbase 布隆过滤器BloomFilter介绍
查看>>
oracle连接问题ORA-00604,ORA-12705
查看>>
NOI 2019 退役记
查看>>
java的几个日志框架log4j、logback、common-logging
查看>>
Java从零开始学十三(封装)
查看>>
Python2和Python3中的rang()不同之点
查看>>
MySQL的外键,修改表,基本数据类型,表级别操作,其他(条件,通配符,分页,排序,分组,联合,连表操作)...
查看>>
UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
查看>>
记忆--1.致我们不可缺少的记忆
查看>>
lintcode28- Search a 2D Matrix- easy
查看>>