OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Adding(blending) two images using OpenCV

2.5 改变图像的对比度和明暗

目标

在教程中,你会学到如何:

1、读取像素值

2、用0初始化一个矩阵

3、学习staurate_cast是做什么的

4、获取有关像素变换的一些更酷的信息(Get some cool info about pixel transformations)

理论

注意,下面的解释来自于Richard Szeliski所写的《Computer Vision:Algorithms and Applications》

图像处理

1、一般的图像处理机是一个接受一个或多个输入图像的并且产生一个暑促图像的函数。

2、图像转换可以被看作:

—点处理机(像素转换)

—邻域(基于区域)处理机

像素转换

1、在这种图像处理中,每一个输出的像素值只依赖于与之对应的输入像素值(加,隐式的,一些全局收集的信息或者参数)。

2、例子中的操作包括亮度和对比度的调整也有颜色的修正和转换。

亮度和对比度的调整

1、两个常用于图像处理的被乘和被加的常数:

g(x)=αf(x)+β

2、参数α>0,β经常被称作gain和bias参数;有时候这些参数被独立的(resepctively)称作控制对比度和明暗度的部分。

3、你可以把f(x) 当作源图像的像素,g(x)当作输出图像像素。这样我们可以更为明显的将表达式写为:

g(i,j)=α*f(i,j)+β

其中i和j就是指在第i行和第j列的像素的坐标。

代码

下面就是g(i,j)=α*f(i,j)+β的体现

#include<cv.h>

#include<highgui.h>

#include<iostream>

using namespace cv;

double  alpha;

int      beta;

int   main(int argc,char**argv)

{

Mat image=imread(argv[1]);

Mat new_image=Mat::zeros(image.size(),image.type());

std::cout<<”Basic Linear Transforms”<<std::endl;

std::cout<<”___________________:<<std::endl;

std::cout<<”Enter the alpha value[1.0-3.0]:”;

std::cin>>alpha;

std::cout<<”Enter the beta value[0-100]:”;

std::cin>>beta;

for(int y=0;y<image.rows;y++)

{

for(int x=0;x<image.cols;x++)

{

for(int c=0;c<3:c++)

{

new_image.at<Vec3b>(y,x)[c]=saturate_cast<uchar>(alpha*(image.at<Vec3b<y,x>[c])+beta);
}
}
}

nameWindow(“Original Image”,1);

nameWindow(“New Image”,1);

imshow(“Original Image:,image);

imshow(“New Image”,new_Image);

waitKey();

return 0;
}

解释

1、我们首先构造参数来保存α和β,两个参数的值由用户输入:

double alpha;

int beta;

2、使用imread载入图像并将其保存至Mat 对象中:

Mat image=imread(argv[1]);

3、现在,由于我们将要对这个图像进行一些转变,因此我们需要一个新的Mat 对象来存储这个转变。我们希望新的Mat 对象能有一下几个特征:

(1)初始的像素值都为0

(2)和原始图像相同的尺寸和类型

Mat new_image=Mat::zeros(image.size(),image.type());

我们可以看到Mat::zeros在image.size()和image.type()的基础上返回了一个matlab式样的0的初始化对象。

4、现在为了进行g(i,j)=α*f(i,j)+β操作,我们读取图像中每个像素的值。因为我们在RGB图像中进行操作,我们的每个像素中会有三个数值(R,G和B),因此我们要独立的读取他们。这里是部分代码:

for(int y=0;y<image.rows;y++)

{

for(int x=0;x<image.cols;x++)

{

For(int c=0;c<3;c++)

{

new_image.at<Vec3b>(y,x)[c]=saturate_cast<uchar>(alpha*(image.at<Vec3b>(y,x)[c])+beta);
}
}
}

请注意下面:

(1)为了进入每一个图像中的像素,我们使用这样的语句:image.at<Vec3b>(y,x)[c]。在这里y是行,x是列,c是R,G或者B(0,1或者2)。

(2)因为α*p(i,j)+β这个操作可能得到的数值超过范围或者不是整数(如果α是float数值),我们使用saturate_cast来确保数值是可用的。

5、最后,我们用最常见的方法创建窗口并且显示图像。

namedWindow(“Original Image”,1);

namedWindow(“New Image,1);

imshow(“Original Image”,image);

imshow(“New Image”,new_image);

waitKey(0);

注意:除了使用for循环来读取每个像素,我们可以简单的使用image.convertTo(new_image,-1,alpha,beta)这个命令。

converTo在new_image=a*image+beta有着高效的性能体现。然而,我们想要让你看一下如何读取每个元素。不管使用哪种方式,都会得到相同的结果。

结果

使用α=2.2,β=50来运行代码,我们可以得到如下结果:

时间: 2024-11-05 02:41:46

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Adding(blending) two images using OpenCV的相关文章

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Adding (blending) two images using OpenCV

目标 在教程中你会学到: 1.什么事线性混合,它有什么用. 2.如何使用addWeighted将两个图像相加 理论 注意:下面的解释来自Richard Szeliski写的<Computer Vision:Algorithms and Application>. 在前面的教程中,我们已经学习了一些像素的运算.一个有意思的二元(两个输入)运算符就是线性混合运算符: 通过α从0到1变化这个运算符可以被用做两个图像或者录像之间的时间交融(cross-dissolve,这里tutorial里面用的是c

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— File Input and Output using XML and YAML files

2.9XML和YAML格式作为文件输入输出 目标 你会从文中找到下面问题的答案: 1.如何从OpenCV使用的YAML或者XML文件中读取和打印文字条目.? 2.对于OpenCV数据结构如何做到相同的事情? 3.对你的数据结构如何做到? 4.OpenCV的数据结构,例如FileStorage,FileNode或者FileNodeIterator的使用方法. 源代码 你可以从这里下载代码或者从OpenCV的源代码库的samples/cpp/tutorial_code/core/file_input

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Interoperability with OpenCV 1

2.10 和OpenCV的互用性 目标 对于OpenCV的开发团队来说,不断提升OpenCV库是非常重要的.我们不断考虑那些可以减轻你工作过程的方法,同时还要保障库的灵活性.新的C++接口就是我们为了这个而开发出来的东西.然而,向后兼容性仍然是很重要的.我们不想打碎那些你使用更早的OpenCV库写下的代码.因此,我们为了保障这个事情从而加上了一些函数.在下面的教程中,你会学习到: 1.相比于同样使用的第一版本的OpenCV库,第二版本中有了什么变化. 2.如何在图像中添加一些高斯噪点. 3.什么

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Random genenrator and text with OpenCV

2.7 随机产生器和OpenCV当中的文字 目标 在教程中,你会学习到: 1.使用随机数字产生类(RNG)并且如何从均匀分布中获得随机数字. 2.使用OpenCV的putText函数在窗口中显示文字 代码 1.在前一个的教程(Basic Drawing)中,我们画了不同的几何图形,给出了例如坐标(使用Points形式的)的输入参数,颜色,线条粗细,等等.你可能已经注意到我们对于那些参数都是给出了特殊的值. 2.在本教程中,我们打算使用为绘图参数使用随机值.同样,我们打算使用大量的几何图形来填满我

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Discrete Fourier Transform

2.8 离散的傅立叶变换 目标 我们要寻找以下问题的答案: 1.什么是傅立叶变换,为什么我们要用这个? 2.在OpenCV中如何做到? 3.例如copyMakeBorder(),merge(),dft(),getOptimalDFGSize(),log()以及normalize()函数的用法. 源代码 你可以从这里下载或者从samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete找到代码. #include "openc

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Mat - The Basic Image Container

在家这段时间内,发现了这样的OpenCV库自带的教程,感觉不错,尝试翻译并且添加一些tips,帮助自己学习,同时也与各位交流一下. 核心模块.核心功能 这里这两部分说的是核心模块以及核心功能的简介,其中蓝字部分可以链接到相关部分,这里我采用顺序方法,从第一部分,即 “Mat:The Basic Image Container”开始叙述. 2.1 基本的图像容器—矩阵 目标 我们可以通过许多途径从真实世界获取数字图像,例如:数码相机.扫描仪.计算机断层扫描以及磁成像共振等等.不管怎样,那些都只是我

OpenCV Tutorials &mdash;&mdash; Adding (blending) two images using OpenCV

An interesting dyadic (two-input) operator is thelinear blend operator:   #include <cv.h> #include <highgui.h> #include <iostream> using namespace cv; int main( int argc, char** argv ) { double alpha = 0.5; double beta; double input; Mat

Nginx - Core Module Directives

The following is the list of directives made available by the Core module. Most of these directives must be placed at the root of the configuration file and can only be used once. However, some of them are valid in multiple contexts. If that is the c

AngularJS------Error: Cannot find module &#39;@angular-devkit/core&#39;

如图: 解决方法: 进入项目目录下执行以下代码 npm i --save-dev @angular-devkit/core AngularJS------Error: Cannot find module '@angular-devkit/core' 原文地址:https://www.cnblogs.com/tianhengblogs/p/8452045.html