OpenCV 图像对比度的实践
作者:翟天保Steven 发布时间:2023-07-29 09:09:27
标签:OpenCV,图像对比度
本文主要介绍了OpenCV 图像对比度,具有一定的参考价值,感兴趣的可以了解一下
实现原理
图像对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,即指一幅图像灰度反差的大小。差异范围越大代表对比越大,差异范围越小代表对比越小。设置一个基准值thresh,当percent大于0时,需要令图像中的颜色对比更强烈,即数值距离thresh越远,则变化越大;当percent等于1时,对比强到极致,只有255和0的区分;当percent等于0时,不变;当percent小于0时,对比下降,即令远离thresh的数值更近些;当percent等于-1时,没有对比了,全是thresh值。
对比度调整算法的实现流程如下:
1.设置调整参数percent,取值为-100到100,类似PS中设置,归一化后为-1到1。
2.针对图像所有像素点单个处理。当percent大于等于0时,对比增强,调整后的RGB三通道数值为:
3.若percent小于0时,对比降低,此时调整后的图像RGB三通道值为:
4.若percent等于1时,大于thresh则等于255,小于则等于0。
至此,图像实现了明度的调整,算法逻辑参考xingyanxiao。C++实现代码如下。
功能函数代码
// 对比度
cv::Mat Contrast(cv::Mat src, int percent)
{
float alpha = percent / 100.f;
alpha = max(-1.f, min(1.f, alpha));
cv::Mat temp = src.clone();
int row = src.rows;
int col = src.cols;
int thresh = 127;
for (int i = 0; i < row; ++i)
{
uchar *t = temp.ptr<uchar>(i);
uchar *s = src.ptr<uchar>(i);
for (int j = 0; j < col; ++j)
{
uchar b = s[3 * j];
uchar g = s[3 * j + 1];
uchar r = s[3 * j + 2];
int newb, newg, newr;
if (alpha == 1)
{
t[3 * j + 2] = r > thresh ? 255 : 0;
t[3 * j + 1] = g > thresh ? 255 : 0;
t[3 * j] = b > thresh ? 255 : 0;
continue;
}
else if (alpha >= 0)
{
newr = static_cast<int>(thresh + (r - thresh) / (1 - alpha));
newg = static_cast<int>(thresh + (g - thresh) / (1 - alpha));
newb = static_cast<int>(thresh + (b - thresh) / (1 - alpha));
}
else {
newr = static_cast<int>(thresh + (r - thresh) * (1 + alpha));
newg = static_cast<int>(thresh + (g - thresh) * (1 + alpha));
newb = static_cast<int>(thresh + (b - thresh) * (1 + alpha));
}
newr = max(0, min(255, newr));
newg = max(0, min(255, newg));
newb = max(0, min(255, newb));
t[3 * j + 2] = static_cast<uchar>(newr);
t[3 * j + 1] = static_cast<uchar>(newg);
t[3 * j] = static_cast<uchar>(newb);
}
}
return temp;
}
C++测试代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
cv::Mat Contrast(cv::Mat src, int percent);
int main()
{
cv::Mat src = imread("5.jpg");
cv::Mat result = Contrast(src, 50.f);
imshow("original", src);
imshow("result", result);
waitKey(0);
return 0;
}
// 对比度
cv::Mat Contrast(cv::Mat src, int percent)
{
float alpha = percent / 100.f;
alpha = max(-1.f, min(1.f, alpha));
cv::Mat temp = src.clone();
int row = src.rows;
int col = src.cols;
int thresh = 127;
for (int i = 0; i < row; ++i)
{
uchar *t = temp.ptr<uchar>(i);
uchar *s = src.ptr<uchar>(i);
for (int j = 0; j < col; ++j)
{
uchar b = s[3 * j];
uchar g = s[3 * j + 1];
uchar r = s[3 * j + 2];
int newb, newg, newr;
if (alpha == 1)
{
t[3 * j + 2] = r > thresh ? 255 : 0;
t[3 * j + 1] = g > thresh ? 255 : 0;
t[3 * j] = b > thresh ? 255 : 0;
continue;
}
else if (alpha >= 0)
{
newr = static_cast<int>(thresh + (r - thresh) / (1 - alpha));
newg = static_cast<int>(thresh + (g - thresh) / (1 - alpha));
newb = static_cast<int>(thresh + (b - thresh) / (1 - alpha));
}
else {
newr = static_cast<int>(thresh + (r - thresh) * (1 + alpha));
newg = static_cast<int>(thresh + (g - thresh) * (1 + alpha));
newb = static_cast<int>(thresh + (b - thresh) * (1 + alpha));
}
newr = max(0, min(255, newr));
newg = max(0, min(255, newg));
newb = max(0, min(255, newb));
t[3 * j + 2] = static_cast<uchar>(newr);
t[3 * j + 1] = static_cast<uchar>(newg);
t[3 * j] = static_cast<uchar>(newb);
}
}
return temp;
}
测试效果
图1 原图
图2 参数为50的效果图
图3 参数为-50的效果图
通过调整percent可以实现图像对比度的调整。
来源:https://blog.csdn.net/zhaitianbao/article/details/120107171


猜你喜欢
- 上一篇我们写了Django基于类如何增删改数据的方法,方法虽然简单,但新手可能对其原理不是很清楚,那么我们这次就用Django提供的Mode
- 1.var、let、const简介 ECMAS
- 如下所示:def ref_txt_demo(): f = open('1.txt', 'r') data =
- typing为Python的一个标注库,此默认支持PEP 484和PEP 526指定的类型提示。最基本的支持由Any、Union、Tuple
- 作者:HelloGitHub-追梦人物文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库搜索是一个复杂的功能,但对于
- 【OpenCV】⚠️高手勿入! 半小时学会基本操作⚠️边界填充概述OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大. 今天
- 1.简介 蒙特卡洛又称随机抽样或统计试验,就是
- 一、概念二维列表的元素还是列表(列表的嵌套),称之为二维列表。需要通过行标和列标来访问二维列表的元素二、创建二维列表1、追加一维列标来生成二
- 本文实例讲述了python实现通过pil模块对图片格式进行转换的方法。分享给大家供大家参考。具体分析如下:python的pil模块相当的智能
- 在Python编程中,导入文本文件是常见的操作之一。Python提供了丰富的标准库,使得文件操作变得十分简单。那么,如何在Python中导入
- 函数原型pd.read_csv(filepath_or_buffer, sep=',', delimiter=None, h
- 刚刚心血来潮,编了一个国际域名查询的功能页面,比较简单,没有做什么美化和修饰,主要利用了服务器端的XMLHTTP访问第三方服务器实现域名查询
- ---- 一、 引言: ---- 回滚段是数据库的一部分,它记录数据库变更的信息。使用这些信息实现数据库的读一致性及其恢复。若回滚段出现故障
- 身边的人竟然不玩“跳一跳了”,都迷上了一个叫“冲顶大会”的东西,考了很多各学科的冷知识,文学、数学、地理、生物、动漫、八卦…小编网上找到一些
- 前言Python 中的 for 循环和其他语言中的 for 循环工作方式是不一样的,今天就带你深入了解 Python 的 for 循环,看看
- 如下所示:# -*- coding: utf-8 -*-import threadingimport threadimport timecl
- Python的sys模块提供访问解释器使用或维护的变量,和与解释器进行交互的函数。通俗来讲,sys模块负责程序与python解释器的交互,提
- 目录实现思路使用BackgroundSubtractorMOG2进行背景分割使用人像识别填充面部信息使用形态学填充分割出来的前景将人像与目标
- 1.MySQL8.0.20下载及解压下载链接https://dev.mysql.com/downloads/mysql/2.新建配置文件my
- 需要的软件phpStudy 用来导入一个数据库api-server 数据库功能可以开启一个服务器,让开发环境可以使用生产环境的网址请求安装