OpenCV 任意曲线(S型等)调整图像色调,对比度小工具 C++

2023-10-29 03:10

本文主要是介绍OpenCV 任意曲线(S型等)调整图像色调,对比度小工具 C++,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

色调变换

改善图像色调的变换通常交互的选择。其概念是实验性的调整图像的亮度和对比度,以便在合适的灰度范围提供最多的细节。

彩色本身并不改变。在RGB和CMYK空间中,这意味着使用相同的变换函数映射3个(或4个)彩色分量。在HSI中则改进了亮度分量;

下面显示了3个常见的色调不平衡的几个典型变换----平淡的,较亮的,较暗的图像。

S型曲线可以增强对比度,凹凸曲线分别减小、增加亮度。

下图是S曲线调整后的效果:

凹曲线降低亮度

 

凸曲线增强亮度:

单独修改RGB中的某一个通道,会改变色调;

R通道上凸,色调偏红;

R通道下凹,色调偏青色(蓝绿色),相当于红色的补色;G 、B通道同理。

 

代码实现:

 实现两个类,Curve 和 Curves 在文件Curves.cpp中

下面是主函数实现:

/*
 * test_Curves
 *
 *  Created on: 2019.03.21
 *      Author: cui
 */


#include <cstdio>
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "Curves.hpp"

using namespace std;
using namespace cv;

static string window_name = "Photo";
static Mat src;

static string curves_window = "Adjust Curves";
static Mat curves_mat;
static int channel = 0;
Curves  curves;

static void invalidate()
{
    curves.draw(curves_mat);
    imshow(curves_window, curves_mat);

    Mat dst;
    curves.adjust(src, dst);
    imshow(window_name, dst);

    int y, x;
    uchar *p;

    y = 150; x = 50;
    p = dst.ptr<uchar>(y) + x * 3;
    cout << "(" << int(p[2]) << ", " << int(p[1]) << ", " << int(p[0]) << ")  ";

    y = 150; x = 220;
    p = dst.ptr<uchar>(y) + x * 3;
    cout << "(" << int(p[2]) << ", " << int(p[1]) << ", " << int(p[0]) << ")  ";

    y = 150; x = 400;
    p = dst.ptr<uchar>(y) + x * 3;
    cout << "(" << int(p[2]) << ", " << int(p[1]) << ", " << int(p[0]) << ")  " << endl;
}

static void callbackAdjustChannel(int , void *)
{
    switch (channel) {
    case 3:
        curves.CurrentChannel = &curves.BlueChannel;
        break;
    case 2:
        curves.CurrentChannel = &curves.GreenChannel;
        break;
    case 1:
        curves.CurrentChannel = &curves.RedChannel;
        break;
    default:
        curves.CurrentChannel = &curves.RGBChannel;
        break;
    }


    invalidate();
}

static void callbackMouseEvent(int mouseEvent, int x, int y, int flags, void* param)
{
    switch(mouseEvent) {
    case CV_EVENT_LBUTTONDOWN:
        curves.mouseDown(x, y);
        invalidate();
        break;
    case CV_EVENT_MOUSEMOVE:
        if ( curves.mouseMove(x, y) )
            invalidate();
        break;
    case CV_EVENT_LBUTTONUP:
        curves.mouseUp(x, y);
        invalidate();
        break;
    }
    return;
}


int main()
{
    //read image file
    src = imread("635c.tif");
    if ( !src.data ) {
        cout << "error read image" << endl;
        return -1;
    }
//    resize(src,src,Size(), 0.5,0.5);
    //create window
    namedWindow(window_name);
    imshow(window_name, src);

    //create Mat for curves
    curves_mat = Mat::ones(256, 256, CV_8UC3);

    //create window for curves
    namedWindow(curves_window);
    setMouseCallback(curves_window, callbackMouseEvent, NULL );
    createTrackbar("Channel", curves_window, &channel, 3, callbackAdjustChannel);


// 范例:用程序代码在Red通道中定义一条曲线
    curves.RGBChannel.clearPoints();
    curves.RGBChannel.addPoint( Point(0,  0) );
    curves.RGBChannel.addPoint( Point(64,  27) );
    curves.RGBChannel.addPoint( Point(127, 127) );
    curves.RGBChannel.addPoint( Point(192,  229) );
    curves.RGBChannel.addPoint( Point(256, 256) );

    invalidate();

    waitKey();

    return 0;

}

 

全部代码和测试图片下载地址:

https://download.csdn.net/download/cyf15238622067/11044921

这篇关于OpenCV 任意曲线(S型等)调整图像色调,对比度小工具 C++的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/297865

相关文章

利用c++判断水仙花数并输出示例代码

《利用c++判断水仙花数并输出示例代码》水仙花数是指一个三位数,其各位数字的立方和恰好等于该数本身,:本文主要介绍利用c++判断水仙花数并输出的相关资料,文中通过代码介绍的非常详细,需要的朋友可以... 以下是使用C++实现的相同逻辑代码:#include <IOStream>#include <vec

基于C++的UDP网络通信系统设计与实现详解

《基于C++的UDP网络通信系统设计与实现详解》在网络编程领域,UDP作为一种无连接的传输层协议,以其高效、低延迟的特性在实时性要求高的应用场景中占据重要地位,下面我们就来看看如何从零开始构建一个完整... 目录前言一、UDP服务器UdpServer.hpp1.1 基本框架设计1.2 初始化函数Init详解

C++ 右值引用(rvalue references)与移动语义(move semantics)深度解析

《C++右值引用(rvaluereferences)与移动语义(movesemantics)深度解析》文章主要介绍了C++右值引用和移动语义的设计动机、基本概念、实现方式以及在实际编程中的应用,... 目录一、右值引用(rvalue references)与移动语义(move semantics)设计动机1

python版本切换工具pyenv的安装及用法

《python版本切换工具pyenv的安装及用法》Pyenv是管理Python版本的最佳工具之一,特别适合开发者和需要切换多个Python版本的用户,:本文主要介绍python版本切换工具pyen... 目录Pyenv 是什么?安装 Pyenv(MACOS)使用 Homebrew:配置 shell(zsh

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias

Python+wxPython开发一个文件属性比对工具

《Python+wxPython开发一个文件属性比对工具》在日常的文件管理工作中,我们经常会遇到同一个文件存在多个版本,或者需要验证备份文件与源文件是否一致,下面我们就来看看如何使用wxPython模... 目录引言项目背景与需求应用场景核心需求运行结果技术选型程序设计界面布局核心功能模块关键代码解析文件大