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++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

C++的模板(八):子系统

平常所见的大部分模板代码,模板所传的参数类型,到了模板里面,或实例化为对象,或嵌入模板内部结构中,或在模板内又派生了子类。不管怎样,最终他们在模板内,直接或间接,都实例化成对象了。 但这不是唯一的用法。试想一下。如果在模板内限制调用参数类型的构造函数会发生什么?参数类的对象在模板内无法构造。他们只能从模板的成员函数传入。模板不保存这些对象或者只保存他们的指针。因为构造函数被分离,这些指针在模板外

揭秘未来艺术:AI绘画工具全面介绍

📑前言 随着科技的飞速发展,人工智能(AI)已经逐渐渗透到我们生活的方方面面。在艺术创作领域,AI技术同样展现出了其独特的魅力。今天,我们就来一起探索这个神秘而引人入胜的领域,深入了解AI绘画工具的奥秘及其为艺术创作带来的革命性变革。 一、AI绘画工具的崛起 1.1 颠覆传统绘画模式 在过去,绘画是艺术家们通过手中的画笔,蘸取颜料,在画布上自由挥洒的创造性过程。然而,随着AI绘画工

墨刀原型工具-小白入门篇

墨刀原型工具-小白入门篇 简介 随着互联网的发展和用户体验的重要性越来越受到重视,原型设计逐渐成为了产品设计中的重要环节。墨刀作为一款原型设计工具,以其简洁、易用的特点,受到了很多设计师的喜爱。本文将介绍墨刀原型工具的基本使用方法,以帮助小白快速上手。 第一章:认识墨刀原型工具 1.1 什么是墨刀原型工具 墨刀是一款基于Web的原型设计工具,可以帮助设计师快速创建交互原型,并且可以与团队

C++工程编译链接错误汇总VisualStudio

目录 一些小的知识点 make工具 可以使用windows下的事件查看器崩溃的地方 dumpbin工具查看dll是32位还是64位的 _MSC_VER .cc 和.cpp 【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了 include<> 和 include"" WinMain 和

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

vcpkg安装opencv中的特殊问题记录(无法找到opencv_corexd.dll)

我是按照网上的vcpkg安装opencv方法进行的(比如这篇:从0开始在visual studio上安装opencv(超详细,针对小白)),但是中间出现了一些别人没有遇到的问题,虽然原因没有找到,但是本人给出一些暂时的解决办法: 问题1: 我在安装库命令行使用的是 .\vcpkg.exe install opencv 我的电脑是x64,vcpkg在这条命令后默认下载的也是opencv2:x6