Opencv的Gamma转换与二值化处理
1. 头文件和命名空间
1 2 3 4 5 6 7
| #include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include <cmath>
using namespace cv; using namespace std;
|
通俗理解:就像在游戏开始前要导入各种工具包,这些#include就是告诉编译器我们需要用到哪些工具。
2. Gamma变换函数详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Mat gammaCorrection(const Mat& src, double gamma) { Mat lookupTable(1, 256, CV_8U); uchar* p = lookupTable.ptr(); for (int i = 0; i < 256; ++i) { p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma) * 255.0); } Mat dst; LUT(src, lookupTable, dst); return dst; }
|
Gamma变换原理: - gamma < 1:增强暗部细节(让暗的地方变亮) - gamma > 1:增强亮部细节(让亮的地方更突出) - gamma = 1:不做任何改变
3. 二值化函数详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| Mat adaptiveBinary(const Mat& src) { Mat gray, binary; if (src.channels() == 3) { cvtColor(src, gray, COLOR_BGR2GRAY); } else { gray = src.clone(); } adaptiveThreshold(gray, binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2); return binary; }
|
4. 主函数详细解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| int main() { Mat src = imread("src.png"); if (src.empty()) { cout << "无法读取图像文件 src.png" << endl; return -1; } cout << "图像尺寸: " << src.size() << endl; cout << "图像通道数: " << src.channels() << endl; namedWindow("原始图像", WINDOW_NORMAL); imshow("原始图像", src); double gamma = 0.5; Mat gamma_img = gammaCorrection(src, gamma); namedWindow("Gamma变换后", WINDOW_NORMAL); imshow("Gamma变换后", gamma_img); Mat gray; cvtColor(gamma_img, gray, COLOR_BGR2GRAY); Mat binary = adaptiveBinary(gray); Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); morphologyEx(binary, binary, MORPH_OPEN, kernel); namedWindow("二值化结果", WINDOW_NORMAL); imshow("二值化结果", binary); vector<int> compression_params; compression_params.push_back(IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); imwrite("processed_result.png", binary, compression_params); cout << "处理后的图像已保存为 processed_result.png" << endl; waitKey(0); return 0; }
|
核心概念解释
1. Mat 是什么?
Mat 是OpenCV的图片容器类,可以理解为: - 一个智能的图片数据盒子 - 自动管理内存,不用手动分配和释放 - 存储像素数据、尺寸、颜色通道等信息
2. 关键函数的作用:
imread():读取图片文件
imshow():显示图片
imwrite():保存图片
cvtColor():颜色空间转换
namedWindow():创建显示窗口
waitKey():等待用户输入
3. 处理流程总结:
- 读图 → 2. Gamma增强 → 3. 转灰度 → 4. 二值化 → 5. 去噪 → 6. 显示保存
完整可运行代码
把以下代码保存为 main.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include <opencv2/opencv.hpp> #include <iostream>
using namespace cv; using namespace std;
Mat gammaCorrection(const Mat& src, double gamma) { Mat lookupTable(1, 256, CV_8U); uchar* p = lookupTable.ptr(); for (int i = 0; i < 256; ++i) { p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma) * 255.0); } Mat dst; LUT(src, lookupTable, dst); return dst; }
Mat adaptiveBinary(const Mat& src) { Mat gray, binary; if (src.channels() == 3) { cvtColor(src, gray, COLOR_BGR2GRAY); } else { gray = src.clone(); } adaptiveThreshold(gray, binary, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2); return binary; }
int main() { Mat src = imread("src.png"); if (src.empty()) { cout << "错误:找不到src.png文件!" << endl; return -1; } Mat gamma_img = gammaCorrection(src, 0.5); Mat binary = adaptiveBinary(gamma_img); imshow("原始图像", src); imshow("处理结果", binary); imwrite("processed_result.png", binary); cout << "处理完成!结果已保存为processed_result.png" << endl; waitKey(0); return 0; }
|
这样解释后,你应该能理解每一行代码的作用了!这个程序的核心思想就是:先调整亮度让数字更明显,然后转换成黑白图让数字突出显示。
Author:
Lyxy-szs
Permalink:
http://lyxy-szs.github.io/2025/11/15/opencv/
Slogan:
永远相信美好的事情即将發生?