OpenCV调整图像亮度和对比度
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】
1、基本方法---线性变换
// 亮度和对比度调整
cv::Mat adjustBrightnessContrast(const cv::Mat& src, double alpha, int beta) {
cv::Mat dst;
src.convertTo(dst, -1, alpha, beta);
return dst;
}
// 使用示例
cv::Mat image = cv::imread("image.jpg");
cv::Mat brightened = adjustBrightnessContrast(image, 1.0, 50); // 增加亮度
cv::Mat darkened = adjustBrightnessContrast(image, 1.0, -50); // 降低亮度
cv::Mat increased_contrast = adjustBrightnessContrast(image, 1.5, 0); // 增加对比度
2、通道分离调整
cv::Mat adjustChannelBrightness(const cv::Mat& src) {
// 分离BGR通道
std::vector<cv::Mat> channels;
cv::split(src, channels);
// 调整蓝色通道亮度
channels[0] = channels[0] * 1.2 + 30;
// 重新合并通道
cv::Mat result;
cv::merge(channels, result);
return result;
}
3、查找表方法
cv::Mat createBrightnessLUT(double contrast, int brightness) {
cv::Mat lookupTable(1, 256, CV_8U);
uchar* lut = lookupTable.ptr();
for (int i = 0; i < 256; i++) {
// 对比度和亮度调整公式
lut[i] = cv::saturate_cast<uchar>(contrast * i + brightness);
}
return lookupTable;
}
// 应用LUT
cv::Mat applyLUTAdjustment(const cv::Mat& src, double contrast, int brightness) {
cv::Mat lookupTable = createBrightnessLUT(contrast, brightness);
cv::Mat result;
cv::LUT(src, lookupTable, result);
return result;
}
4、高级对比度增强
cv::Mat enhanceContrast(const cv::Mat& src) {
cv::Mat dst;
// 直方图均衡化
if (src.channels() == 1) {
// 灰度图
cv::equalizeHist(src, dst);
} else {
// 彩色图转换到YUV空间
cv::Mat yuv;
cv::cvtColor(src, yuv, cv::COLOR_BGR2YUV);
// 仅均衡化亮度通道
std::vector<cv::Mat> channels;
cv::split(yuv, channels);
cv::equalizeHist(channels[0], channels[0]);
// 合并通道
cv::merge(channels, yuv);
cv::cvtColor(yuv, dst, cv::COLOR_YUV2BGR);
}
return dst;
}
5、伽马校正
cv::Mat gammaCorrection(const cv::Mat& src, double gamma = 1.0) {
cv::Mat dst;
// 归一化
cv::Mat normalized;
src.convertTo(normalized, CV_32F, 1.0/255);
// 伽马变换
cv::pow(normalized, gamma, dst);
// 还原到0-255
dst = dst * 255;
dst.convertTo(dst, CV_8U);
return dst;
}
// 使用示例
cv::Mat gammaEnhanced1 = gammaCorrection(image, 0.5); // 变亮
cv::Mat gammaEnhanced2 = gammaCorrection(image, 2.0); // 变暗
6、自适应对比度增强
cv::Mat adaptiveContrastEnhancement(const cv::Mat& src) {
cv::Mat lab;
cv::cvtColor(src, lab, cv::COLOR_BGR2Lab);
// 分离通道
std::vector<cv::Mat> channels;
cv::split(lab, channels);
// 限制对比度自适应直方图均衡化(CLAHE)
cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(2.0, cv::Size(8, 8));
clahe->apply(channels[0], channels[0]);
// 合并通道
cv::merge(channels, lab);
cv::Mat result;
cv::cvtColor(lab, result, cv::COLOR_Lab2BGR);
return result;
}
7、通用图像增强类
class ImageEnhancer {
private:
cv::Mat image;
public:
ImageEnhancer(const cv::Mat& src) : image(src.clone()) {}
// 线性变换
cv::Mat linearTransform(double contrast = 1.0, int brightness = 0) {
cv::Mat dst;
image.convertTo(dst, -1, contrast, brightness);
return dst;
}
// 伽马校正
cv::Mat gammaCorrection(double gamma = 1.0) {
cv::Mat normalized, corrected;
image.convertTo(normalized, CV_32F, 1.0/255);
cv::pow(normalized, gamma, corrected);
corrected = corrected * 255;
cv::Mat result;
corrected.convertTo(result, CV_8U);
return result;
}
// 自适应对比度增强
cv::Mat adaptiveCLAHE() {
cv::Mat lab;
cv::cvtColor(image, lab, cv::COLOR_BGR2Lab);
std::vector<cv::Mat> channels;
cv::split(lab, channels);
cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(2.0, cv::Size(8, 8));
clahe->apply(channels[0], channels[0]);
cv::merge(channels, lab);
cv::Mat result;
cv::cvtColor(lab, result, cv::COLOR_Lab2BGR);
return result;
}
};
// 使用示例
cv::Mat image = cv::imread("image.jpg");
ImageEnhancer enhancer(image);
cv::Mat brightened = enhancer.linearTransform(1.0, 50);
cv::Mat gammaEnhanced = enhancer.gammaCorrection(0.5);
cv::Mat adaptiveEnhanced = enhancer.adaptiveCLAHE();
8、完整示例
int main() {
// 读取图像
cv::Mat image = cv::imread("image.jpg");
// 创建增强器
ImageEnhancer enhancer(image);
// 多种增强方法
cv::Mat result1 = enhancer.linearTransform(1.2, 30); // 增加亮度和对比度
cv::Mat result2 = enhancer.gammaCorrection(0.8); // 伽马校正
cv::Mat result3 = enhancer.adaptiveCLAHE(); // 自适应对比度增强
// 显示结果
cv::imshow("Original", image);
cv::imshow("Brightened and Enhanced", result1);
cv::imshow("Gamma Corrected", result2);
cv::imshow("Adaptive CLAHE", result3);
cv::waitKey(0);
return 0;
}
注意事项
- 使用
cv::saturate_cast
防止溢出 - 注意数据类型转换
- 考虑图像通道数
- 处理边界情况
- 性能优化
性能建议
- 使用
cv::Mat
操作替代逐像素遍历 - 利用OpenCV的矩阵运算
- 对于大图像,考虑并行处理
- 使用
cv::cuda
进行GPU加速