当前位置: 首页 > news >正文

opencv调整图像亮度和对比度,以及opencv种的做法

1. 调整图像亮度和对比度

原理可以参考 opencv关于对比度和亮度的误解
通过设计一个映射曲线就可完成对比度、亮度调整,具体过程如上图所示,
(a) 为原图;
(b) 把亮度调高,像素强度+固定值;
© 把亮度调低,像素强度-固定值;
(d) 增大像素强度75附近的对比度;增大附近的斜率
(e) 增大像素强度150附近的对比度;
(f) 增大像素强度75和225附近的对比度。

曲线斜率大于45度角的区域灰度拉伸、精度上升、对比度变高;小于45度角的区域灰度被压缩、精度下降、对比度变低。

在这里插入图片描述
python实现的一个代码如下
首先减去均值,然后调整对比度,然后加上均值,最后调整亮度。
img_a = aa * (img - bri_mean) + bb + bri_mean

import cv2
import numpy as np
from matplotlib import pyplot as plt

if __name__ == "__main__":
    file = r'D:\dataset\data_gain1_2\cap_frame_0002_raw.png'
    img = cv2.imread(file).astype(np.float32)
    bri_mean = np.mean(img)

    a = np.arange(5, 16, 5) / 10
    b = np.arange(-30, 31, 30)

    a_len = len(a)
    b_len = len(b)
    print(a_len, b_len)
    plt.figure()

    for i in range(a_len):
        for j in range(b_len):
            aa = a[i]
            bb = b[j]
            img_a = aa * (img-bri_mean) + bb + bri_mean
            print(i, j, aa, bb)
            img_a = np.clip(img_a,0,255).astype(np.uint8)
            plt.subplot(a_len+1, b_len, (j + b_len * i + 1))
            plt.imshow(img_a, cmap='gray')
    plt.subplot(a_len + 1, b_len, a_len*b_len+1)
    plt.imshow(img.astype(np.uint8), cmap='gray')
    plt.show()
  1. 在opencv种有一个调节图像和对比度的方法

opencv demo code
对应直方图的变化:
原图
在这里插入图片描述
增加亮度,直方图向右平移
在这里插入图片描述
增加对比度, 直方图更加均衡
在这里插入图片描述

a. opencv方法:
if (contrast > 0)
    {
        delta = 127. * contrast / 100;
        a = 255. / (255. - delta * 2);
        b = a * (brightness - delta);
    }
    else
    {
        delta = -128. * contrast / 100;
        a = (256. - delta * 2) / 255.;
        b = a * brightness + delta;
    }
b. 按照下面公式的方法

img_a = aa * (img - bri_mean) + bb + bri_mean
bri_mean锚定为127的时候

    a = _contrast / 100.0f;
    b = (1 - a) * 127 + _brightness - 100;

通过对比直方图的变化效果 可知上面两个方法 作用是类似的。
本来想找opencv的方法链接,但是链接已经失效

完整demo:

#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"

#include <iostream>

using namespace cv;
using namespace std;

int _brightness = 100;
int _contrast = 100;

Mat image;

/* brightness/contrast callback function */
static void updateBrightnessContrast(int /*arg*/, void*)
{
    int histSize = 64;
    int brightness = _brightness - 100;
    int contrast = _contrast - 100;

    /*
     * The algorithm is by Werner D. Streidt
     * (http://visca.com/ffactory/archives/5-99/msg00021.html)
     */
    double a, b;
    
    double delta=0;
    
    if (contrast > 0)
    {
        delta = 127. * contrast / 100;
        a = 255. / (255. - delta * 2);
        b = a * (brightness - delta);
    }
    else
    {
        delta = -128. * contrast / 100;
        a = (256. - delta * 2) / 255.;
        b = a * brightness + delta;
    }
    
    a = _contrast / 100.0f;
    b = (1 - a) * 127 + _brightness - 100;
    printf("ab value :%.4lf, %.4lf, %.4lf\n",delta, a, b);
    Mat dst, hist;
    image.convertTo(dst, CV_8U, a, b);
    imshow("image", dst);

    calcHist(&dst, 1, 0, Mat(), hist, 1, &histSize, 0);
    Mat histImage = Mat::ones(200, 320, CV_8U) * 255;

    normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, CV_32F);

    histImage = Scalar::all(255);
    int binW = cvRound((double)histImage.cols / histSize);

    for (int i = 0; i < histSize; i++)
        rectangle(histImage, Point(i * binW, histImage.rows),
            Point((i + 1) * binW, histImage.rows - cvRound(hist.at<float>(i))),
            Scalar::all(0), -1, 8, 0);
    imshow("histogram", histImage);
}

const char* keys =
{
    "{help h||}{@image|baboon.jpg|input image file}"
};

int main(int argc, const char** argv)
{
    CommandLineParser parser(argc, argv, keys);
    parser.about("\nThis program demonstrates the use of calcHist() -- histogram creation.\n");
    if (parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }
    string inputImage = parser.get<string>(0);
    // Load the source image. HighGUI use.
    image = imread(samples::findFile(inputImage), IMREAD_GRAYSCALE);
    if (image.empty())
    {
        std::cerr << "Cannot read image file: " << inputImage << std::endl;
        return -1;
    }

    namedWindow("image", 0);
    namedWindow("histogram", 0);

    createTrackbar("brightness", "image", &_brightness, 200, updateBrightnessContrast);
    createTrackbar("contrast", "image", &_contrast, 200, updateBrightnessContrast);

    updateBrightnessContrast(0, 0);
    waitKey();

    return 0;
}

相关文章:

  • django之静态文件配置 请求方式 request对象方法 pycharm连接数据库 django连接MySQL 初识ORM
  • 自动控制原理6.3---串联校正
  • Windows下Jenkins的运行环境由Java8 升级为Java11
  • Linux中用户组管理
  • 【前端】html+js+css开发入门超详细介绍
  • 车企上市只是时间问题,零跑只是抢先一步而已
  • 软件工程考试选择题:模块的扇入扇出 深度宽度
  • 黑马C++ 02 核心5 —— 类和对象_运算符重载(重难点)
  • 移动办公平台迎来定制潮,WorkPlus如何在钉钉和企微光环下 “出圈”?
  • Keras - ModelCheckpoint
  • 【零基础学Python】Day10 Python解释器
  • 搭建网课查题搜题公众号
  • Nginx的rewrite
  • redux入门详解
  • WRF学习笔记之三:使用ERA5数据驱动并运行WRFV4.4(一层嵌套)/WRF运行实录/WRF报错(踩坑)记录
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • 2017-09-12 前端日报
  • input实现文字超出省略号功能
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Java,console输出实时的转向GUI textbox
  • Java教程_软件开发基础
  • oldjun 检测网站的经验
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • PAT A1017 优先队列
  • PhantomJS 安装
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • spring学习第二天
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 从重复到重用
  • 简单实现一个textarea自适应高度
  • 前端攻城师
  • 入口文件开始,分析Vue源码实现
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 使用common-codec进行md5加密
  • 事件委托的小应用
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 手写一个CommonJS打包工具(一)
  • 我从编程教室毕业
  • 源码安装memcached和php memcache扩展
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • python最赚钱的4个方向,你最心动的是哪个?
  • ​TypeScript都不会用,也敢说会前端?
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (02)vite环境变量配置
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (太强大了) - Linux 性能监控、测试、优化工具
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .form文件_SSM框架文件上传篇
  • .NET gRPC 和RESTful简单对比
  • .NET Micro Framework初体验
  • .NET Micro Framework初体验(二)