一、函数:
a.MatIterator_
类:
(1)模板类定义:
/** @brief Matrix read-write iterator
*/
template<typename _Tp>
class MatIterator_ : public MatConstIterator_<_Tp>
{
public:
typedef _Tp* pointer;
typedef _Tp& reference;
typedef std::random_access_iterator_tag iterator_category;
//! the default constructor
MatIterator_();
//! constructor that sets the iterator to the beginning of the matrix
MatIterator_(Mat_<_Tp>* _m);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(Mat_<_Tp>* _m, Point _pt);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(Mat_<_Tp>* _m, const int* _idx);
//! copy constructor
MatIterator_(const MatIterator_& it);
//! copy operator
MatIterator_& operator = (const MatIterator_<_Tp>& it );
//! returns the current matrix element
_Tp& operator *() const;
//! returns the i-th matrix element, relative to the current
_Tp& operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
MatIterator_& operator += (ptrdiff_t ofs);
//! shifts the iterator backward by the specified number of elements
MatIterator_& operator -= (ptrdiff_t ofs);
//! decrements the iterator
MatIterator_& operator --();
//! decrements the iterator
MatIterator_ operator --(int);
//! increments the iterator
MatIterator_& operator ++();
//! increments the iterator
MatIterator_ operator ++(int);
};
(2)继承关系:
MatIterator_
继承自MatConstIterator_<_Tp>
,这意味着它具有只读迭代器的特性,并添加了写入功能。
(3)类型定义:
pointer
和reference
类型别名分别定义了迭代器指向的指针类型和引用类型。
(4)迭代器类别:
iterator_category
定义了迭代器的类别,这里是std::random_access_iterator_tag
,表示迭代器支持随机访问。
(5)构造函数:
- 提供了多个构造函数,允许以不同的方式初始化迭代器,例如指定矩阵、行号、列号或点坐标。
(6)赋值操作:
- 复制构造函数和赋值运算符允许将一个迭代器赋值给另一个迭代器。
(7)解引用操作:
operator *
允许通过解引用迭代器来访问当前指向的矩阵元素。operator []
允许访问相对于当前迭代器位置的第 i 个元素。
(8)位移操作:
operator +=
和operator -=
分别用于将迭代器向前或向后移动指定数量的元素。operator ++
和operator --
用于递增和递减迭代器。
(9)前后缀递增/递减:
- 提供了前后缀版本的递增和递减运算符,以满足不同的使用场景。
b.saturate_cast
函数:
(1)函数原型:
template<> inline uchar saturate_cast<uchar>(float v) { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
(2) 模板特化:
template<>
表示这是一个模板函数的特化版本,即针对特定类型(这里是uchar
)的实现。
(3)内联函数:
-
inline
关键字表示这个函数在编译时会被插入到每个调用该函数的地方,以减少函数调用的开销。
(4)函数返回类型:
-
uchar
是 OpenCV 中定义的 8 位无符号整型别名。
(5)函数名:
-
saturate_cast
是函数的名称,表示执行饱和的类型转换。
(6)参数:
-
函数接受一个
float
类型的参数v
,这是要转换的值。
(7)转换逻辑:
int iv = cvRound(v);
首先将浮点数v
四舍五入到最近的整数iv
。cvRound
是 OpenCV 中的四舍五入函数。return saturate_cast<uchar>(iv);
然后调用saturate_cast
函数模板,将整数iv
转换为uchar
类型。如果iv
超出了uchar
类型可以表示的范围(0-255),这个函数会进行饱和处理,即把值限制在可表示的最大或最小范围内。
(8)饱和处理:
-
如果
iv
小于 0,它将被转换为 0;如果iv
大于 255,它将被转换为 255。
二、示例代码:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
#define RGB_image 1; //0,使用灰度图进行演示 1.使用RGB图进行演示
#define GAMMA_FACTOR 0.5; //gamma矫正的gamma值
int gammaCorrection(cv::Mat srcMat, cv::Mat& dstMat, float gamma);
int main() {
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
int readType = RGB_image; // 定义读取图像的类型
Mat srcMat; // 定义源图像的Mat对象
// 检查参数是否合法
if (readType == 0) {
//以灰度图方式读取图像
srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Gama.jpg",0);
}
else if (readType == 1) {
//以原图方式读取图像
srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Gama.jpg");
}
else {
cout << "参数错误!" << endl; // 参数错误提示
return -1; // 参数不合法时返回错误码
}
if (srcMat.empty()) { // 检查图像是否成功加载
cout << "fail to read pic!" << endl; // 读取图像失败提示
return -1; // 读取图像失败时返回错误码
}
Mat Gam_image; // 定义目标图像的Mat对象
float gamma = GAMMA_FACTOR; // 设置伽马值
// 对图像进行伽马校正
if (srcMat.type() == CV_8UC1) { // 如果图像是单通道(灰度图)
gammaCorrection(srcMat, Gam_image, gamma); // 调用伽马校正函数
}
else if (srcMat.type() == CV_8UC3) { // 如果图像是三通道(彩色图)
Mat channel[3]; // 定义颜色通道数组
Mat out[3]; // 定义输出图像数组
float hist[3][256]; // 定义直方图数组,未使用
// 分离颜色通道
split(srcMat, channel);
for (int i = 0; i < 3; i++) { // 对每个通道进行伽马校正
gammaCorrection(channel[i], out[i], gamma); // 调用伽马校正函数
}
// 合并校正后的通道
merge(out, 3, Gam_image);
}
// 显示原始图像和伽马校正后的图像
imshow("原图像", srcMat);
imshow("Gam_image", Gam_image);
waitKey(0); // 等待用户按键
destroyAllWindows(); // 销毁所有窗口
return 0; // 正常退出
}
//实现伽马校正,用于调整图像的亮度和对比度。
int gammaCorrection(Mat srcMat, Mat& dstMat, float gamma) {
// 本函数只处理单通道图像
if (srcMat.channels() != 1) return -1; // 如果不是单通道图像,则返回错误码
// 建立查询表
unsigned char lut[256]; // 定义查找表数组
for (int i = 0; i < 256; i++) {
// 计算查找表的每个值
lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0f), gamma) * 255.0f);
// 使用伽马函数计算
}
// 复制源图像到目标图像
srcMat.copyTo(dstMat);
// 使用MatIterator遍历目标图像的每个像素并应用查找表
MatIterator_<uchar> it, end; // 定义uchar类型的Mat迭代器
for (it = dstMat.begin<uchar>(), end = dstMat.end<uchar>(); it != end; it++) {
*it = lut[(*it)]; // 应用查找表进行伽马校正
}
return 0; // 函数成功执行返回0
}
三、运行结果: