#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> using namespace cv; int main()
{
Mat Valley = imread("/home/ttwang/Valley.jpg");
Mat ValleyLogo = imread("/home/ttwang/ValleyLogo.jpg");
namedWindow("[1] ValleyPic");
imshow("[1] ValleyPic",Valley);
namedWindow("[2] ValleyLogo");
imshow("[2] ValleyLogo",ValleyLogo);
Mat valleyROI;

/******************实现两个图像混合****************************/
valleyROI = Valley(Rect(,,ValleyLogo.cols,ValleyLogo.rows));
addWeighted(valleyROI,0.5,ValleyLogo,0.3,.,valleyROI);
namedWindow("valley+logo");
imshow("valley+logo",Valley);
// imwrite("",Valley);
waitKey();
return ; }



二、创建滑动条:createTrackbar()函数  (利用滑动条实现两幅图的Alpha混合)

 #include <QCoreApplication>  //本人所用的IDE是QT,,终端编译时不需要该声明
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv; #define WINDOW_NAME "[Alpha]" //窗口名的宏定义 const int g_nMaxAlphaValue = ;
int g_nAlphaValueSlider;
double g_dAlphaValue;
double g_dBetaValue; Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
/**********响应滑动条的回调函数*************/
void on_Trackbar( int ,void*)
{
g_dAlphaValue = (double) g_nAlphaValueSlider/g_nMaxAlphaValue;
g_dBetaValue = (1.0 - g_dAlphaValue);
//根据Alpha beta的值进行线性混合
    addWeighted(g_srcImage1,g_dAlphaValue,g_srcImage2,g_dBetaValue,0.0,g_dstImage);
imshow(WINDOW_NAME,g_dstImage);
} int main()
{
g_srcImage1 = imread("/home/ttwang/11.jpg");  //两幅图的尺寸要相同,否则出现如下图错误
g_srcImage2 = imread("/home/ttwang/12.jpg"); g_nAlphaValueSlider = ;
namedWindow(WINDOW_NAME,); char TrackbarName[];
sprintf(TrackbarName,"透明值 %d", g_nMaxAlphaValue);
createTrackbar(TrackbarName,WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue,on_Trackbar);
on_Trackbar(g_nAlphaValueSlider,); waitKey();
return ; }

由于程序不是直接粘贴过来的,按该程序进行编译时候,总出现错误,可以参考下面的链接感谢分享





三、鼠标操作:SetMouseCallback()函数

#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv; #define WINDOW_NAME "[Program window]" //为窗口标题定义的宏 /******************全局函数的声明********************/
void on_MouseHandle(int event,int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& img, cv::Rect box);
void ShowHelpText(); /******************全局变量声明*********************/
Rect g_rectangle;
bool g_bDrawingBox = false;//是否绘制
RNG g_rng(); int main()
{
g_rectangle = Rect(-,-,,);
Mat srcImage(,,CV_8UC3),tempImage;
srcImage.copyTo(tempImage);
g_rectangle = Rect(-,-,,);
srcImage = Scalar::all(); //设置鼠标操作回调函数
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
while()
{
srcImage.copyTo(tempImage); //复制源图到临时变量
if(g_bDrawingBox) DrawRectangle(tempImage,g_rectangle);//当绘制标识符为真,进行绘制
imshow(WINDOW_NAME,tempImage);
if(waitKey() == ) break; //按下Esc,程序退出
}
return ;
} /*********鼠标回调函数,根据不同的鼠标事件进行不同的操作*******************/
void on_MouseHandle(int event, int x, int y, int flags, void *param)
{
Mat& image = *(cv::Mat*) param;
switch (event)
{
//鼠标移动消息
case EVENT_MOUSEMOVE:
{
if(g_bDrawingBox)//如果是否进行绘制额标识符为真,则记录下长和宽到RECT型变量中
{
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y- g_rectangle.y;
}
}
break;
//左键按下消息
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x,y,,);//记录起始点
}
break;
//左键抬起消息
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false; //置标识符为false
//对宽和高小于0的进行处理
if(g_rectangle.width < )
{
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -;
}
if(g_rectangle.height < )
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -;
}
//调用回调函数进行绘制
DrawRectangle( image, g_rectangle);
}
break; }
} /********************自定义的矩形绘制函数DrawRectangle() ********************/
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(,),g_rng.uniform(,),g_rng.uniform(,)));
}



四章、OpenCV数据结构与基本绘图

1. Mat M(2,2,CV_8UC3,Scalar(0,0,255)); //使用Mat()构造函数创建Mat对象

 两行两列、CV_8UC3: CV_[位数][带符号与否]C[通道数] Scalar是个short类型的向量,可以使用指定的值来初始化矩阵

2.Mat M;  M.create(4,4,CV_8UC3);  //使用create()函数创建Mat对象,,此方法不能为矩阵设初值

3.颜色的表示类:Scalar()是具有四个元素的数组,,第四个用不到,则不写 格式如下:

        Scalar(a, b,  c)定义的RGB颜色值:红色分量c 绿色分量b  蓝色分量 a

4.尺寸的表示类: Size()  常用格式: Size(5,5)表示构造出的Size高度和宽度都为5

5.矩形的表示类: Rect类的成员有x,y,width,height,分别为左上角的坐标和矩形的宽、高

         格式: Rect rect(0,0,200,400)

6.颜色空间转换:cvtColor()函数  格式:cvtColor(InputArraysrc, OutputArray dst, int code, int dstCn=0) 

                 第一个参数:输入图像;

                 第二个参数:输出图像;

                 第三个参数:颜色空间转换的标识符; (详见:P98)

                                                                第四个参数:目标图像的通道数,若为0,则表示其取源图像的通道数。

7.基本图型的绘制涉及的函数:   (通过例程学习 P100) 

              绘制直线的line函数

              绘制椭圆的ellipse函数

              绘制矩形的rectangle函数

              绘制圆的circle函数

              绘制填充的多边形的fillPloy函数


第五章 core组件进阶

1.计时函数:  getTickCount()和getTickFrequency()

       getTickCount()函数返回CPU自某个事件以来走过的时钟周期数

       getTickFrequency()函数返回CPU一秒钟走过的周期数

显然: 二者结合可以实现对某种图像处理方法的计时

double time0 = static_cast<double>(getTickCount());  //记录起始时间

time0= ((double)getTickCount() - time0)/getTickFrequency();////计算运行时间并输出

cout<<"\t此方法运行时间为:"<<time0<<"秒"<<endl;  //输出运行时间

2.访问图像中像素的几种方法 (简单介绍,具体P110)

需要先明白以下知识: 

(1) Mat类的公有成员变量cols和rows给出了图像的宽和高

   image.cols       image.rows

(2)    Mat类的成员函数channels()用于返回图像的通道数;

  灰度图像通道数1,彩色图像通道数为3  image.channels()

(4)    每一行的像素个数= image.cols*image.channels()       

a.直接遍历,使用Mat里的成员函数data

/*********只用于访问连续空间********/
Mat mat (,,CV_8UC3)
int es = mat.eleSize(); //定义步长,因为定义为3通道的,实质该值为3
int size = mat.rows*mat.cols*es;
for(int i = ; i < size; i += es)
{
mat.data[i] = ; // B通道
mat.data[i+] = ; // G通道
mat.data[i+] = ; //  R通道
}

b.直接访问不连续空间

for (int row = ; row < mat.rows; row++)
{
for (int col = ; col < mat.cols; col++)
{
(&mat.data[row*mat.step])[col*es] = ;
(&mat.data[row*mat.step])[col*es + ] = ;
(&mat.data[row*mat.step])[col*es + ] = ;
}
}

c.通过opencv ptr模板函数遍历

 for (int row = ; row < mat.rows; row++)
{
  for (int col = ; col < mat.cols; col++)
  {
     Vec3b *c = mat.ptr<Vec3b>(row,col);
     c->val[] = ;
8      c->val[] = ;
10      c->val[] = ;
    }
}

c.通过at遍历

   for (int row = ; row < mat.rows; row++)
{
for (int col = ; col < mat.cols; col++)
{
Vec3b &m = mat.at<Vec3b>(row, col);
m[] = ;
m[] = ;
m[] = ;
}
}

d.通过迭代器遍历

   auto it = mat.begin<Vec3b>();   //自动类型匹配auto
  auto it_end = mat.end<Vec3b>();
  for (; it != it_end; it++)
  {
   (*it).val[] = ;
   (*it).val[] = ;
   (*it).val[] = ;
  }
.感兴趣区域ROI

/******表示方法一 Rect矩形区域*******/

Mat imageROI
imageROI = image(Rect(,,logo.cols,logo.rows)); //image为已经载入好的图片 /******表示方法二 Range指定感兴趣的行和列********/ imageROI = image(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols)); //image为已经载入好的图片
 
.利用addWeighted可实现图像线性混合
数学公式: dst = src1[I] * alpha + src2[I]*beta + gamma (P117)
.分离颜色通道、多通道图像混合
通道分离:split()函数,将一个3通道图像转换成3个单通道
通道合并:merge()函数 ###例程:(课本P127,以多通道混合-蓝色分量部分为例)
###平台:QT5.7.1+OpenCV3.2.0
###时间:2017年12月11日 /********建立QT控制台程序*********/
#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv; //全局函数声明
bool MultiChannelBlending(); int main()
{
if(MultiChannelBlending())
{
cout << endl << "\n运行成功,得到目标图像" << endl;
}
waitKey();
return ;
}
/*********多通道混合的实现函数*********/
bool MultiChannelBlending()
{
Mat srcImage;
Mat logoImage;
vector<Mat> channels;
/********** 蓝色分量 *************/
Mat imageBlueChannel;
logoImage = imread("/home/ttwang/Valley_logo.jpg",);//一定要读入会灰度图像,不然addWeighted()会因为类型不匹配而报错
srcImage = imread("/home/ttwang/Valley.jpg");
split(srcImage,channels); //将一个3通道图像转换成3个单通道
imageBlueChannel = channels.at(); //将原图的蓝色通道引用返回给imageBlueChannel
addWeighted(imageBlueChannel(Rect(,,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,.,imageBlueChannel(Rect(,,logoImage.cols,logoImage.rows)));
merge(channels,srcImage);//将三个单通道重新合并成一个三通道
namedWindow("src+LogoBlue");
imshow("src+LogoBlue",srcImage); /*******绿色分量 ******/
Mat imageGreenChannel;
logoImage = imread("/home/ttwang/Valley_logo.jpg",);
srcImage = imread("/home/ttwang/Valley.jpg");
split(srcImage,channels); //将一个3通道图像转换成3个单通道
imageGreenChannel = channels.at();
addWeighted(imageGreenChannel(Rect(,,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.0,imageGreenChannel(Rect(,,logoImage.cols,logoImage.rows)));
merge(channels,srcImage);//将三个单通道重新合并成一个三通道
namedWindow("src+LogoGreen");
imshow("src+LogoGreen",srcImage); /*******红色分量 ******/
Mat imageRedChannel;
logoImage = imread("/home/ttwang/Valley_logo.jpg",);
srcImage = imread("/home/ttwang/Valley.jpg");
split(srcImage,channels); //将一个3通道图像转换成3个单通道
imageRedChannel = channels.at();
addWeighted(imageRedChannel(Rect(,,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.0,imageRedChannel(Rect(,,logoImage.cols,logoImage.rows)));
merge(channels,srcImage);//将三个单通道重新合并成一个三通道
namedWindow("src+LogoRed");
imshow("src+LogoRed",srcImage);
return true;
}
.图像对比度、亮度调整

公式: g(i,j)=a*f(i,j)+b;    (opencv控制图像对比度和亮度的理论公式)

        参数a(a>)通常被成为增益,控制图像的对比度
参数b称为偏置,控制图像的亮度 访问图片中的像素:(使用三个for循环,语法:image.at<Vec3b>(y,x)[c])
其中,y是像素所在的行,x是像素所在的列,c是B、G、 R(对应0、、)
.离散傅里叶变换(详细参照课本P135)
参考资料及函数说明,参照下面的链接:  opencv2教程之离散型傅里叶变换

 

opencv图像处理基础 (《OpenCV编程入门--毛星云》学习笔记一---五章)的更多相关文章

  1. 《Java核心技术·卷Ⅰ:基础知识(原版10》学习笔记 第5章 继承

    <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 目录 <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 5.1 类.超类和子类 5.1 ...

  2. 《Jave并发编程的艺术》学习笔记(1-2章)

    Jave并发的艺术 并发编程的挑战 上下文切换 CPU通过时间片分配算法来循环执行任务,当前时间片执行完之后会切换到下一个任务.但是,切换会保存上一个任务的状态,一遍下次切换回这个任务时,可以再次加载 ...

  3. 《Python基础教程(第二版)》学习笔记 -> 第五章 条件、循环 和 其他语句

    条件和条件语句 下面的值在作为布尔表达式的时候,会被解释器看作假(False):False None    0    ""    ()    []    {} 条件执行和if语句 ...

  4. c#高级编程第七版 学习笔记 第三章 对象和类型

    第三章 对象和类型 本章的内容: 类和结构的区别 类成员 按值和按引用传送参数 方法重载 构造函数和静态构造函数 只读字段 部分类 静态类 Object类,其他类型都从该类派生而来 3.1 类和结构 ...

  5. Dubbo入门到精通学习笔记(五):持续集成管理平台之sonarqube代码质量管理平台的介绍与安装

    文章目录 SonarQube的介绍 SonarQube的安装 安装简介 详细安装过程 详细使用过程 SonarQube的介绍 SonarQube是一个管理代码质量的开放平台. 可以从七个维度检测代码质 ...

  6. 小甲鱼零基础汇编语言学习笔记第五章之[BX]和loop指令

         这一章主要介绍什么是[BX]以及loop(循环)指令怎么使用,loop和[BX]又怎么样相结合,段前缀又是什么鬼,以及如何使用段前缀.   1.[BX]的概念      [BX]和[0]类似 ...

  7. opencv学习笔记(五)镜像对称

    opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...

  8. 《零基础学JavaScript(全彩版)》学习笔记

    <零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...

  9. 《C#并发编程经典实例》学习笔记—2.7 避免上下文延续

    避免上下文延续 在默认情况下,一个 async 方法在被 await 调用后恢复运行时,会在原来的上下文中运行. 为了避免在上下文中恢复运行,可让 await 调用 ConfigureAwait 方法 ...

随机推荐

  1. 为autoLayout 增加标识符,方便调试

     如上图,是一个十分简单的布局. root view 上加了一个 button 和一个 webview. 不加标识符的样子 视图层级中没有标识  只有 UIView.WKWebView 之类,如果 ...

  2. php unset变量

    <?php $a="abc"; $b="def"; unset($a,$b); echo $a."\n"; echo $b." ...

  3. 在阿里云服务器中安装配置mysql数据库完整教程

    阿里云ECS服务器CentOS7上安装MySql服务 (可选)1.确保服务器系统处于最新状态 [root@localhost ~]# yum -y update如果显示以下内容说明已经更新完成 Rep ...

  4. 目标检测算法—YOLO-V1

    为什么会叫YOLO呢? YOLO:you only look once.只需要看一眼,就可以检测识别出目标,主要是突出这个算法 快 的特点.(原文:Yolo系列之前的文章:主要是rcnn系列的,他们的 ...

  5. 【转】MySQL下载安装验证

    MySQL官网下载路径:https://dev.mysql.com/downloads/mysql/ MySQL安装步骤:转自博主 Smile_Coding 博文:https://www.cnblog ...

  6. json,DataTable,model

    1.DataTable转json public class DataTableConvertJson { #region dataTable转换成Json格式 /// <summary> ...

  7. SQL中文转拼音

    使用下方的函数.. 忘了从哪抄的了..留存一份 如果只要首字母..建议将数据  Left(tableFiled,1) 后传入函数 如果字段是空或者null, 不会报错..返回空 方法体: SET AN ...

  8. Java枚举源码分析

    1.是一个范型类, 实现了Serializable和Comparable接口 2.只有两个成员变量:name.ordinal 3.枚举类隐含一个values函数,需通过反射调用才可获取枚举实例化对象列 ...

  9. Filter应用之-自动登录

    自动登录,是为了帮助用户多次使用这个网页时,不用再次输入用户名和密码就可以登录. 是指用户将用户的登录信息,人,保存到本地的文件中Cookie中. Name,value – 声明时 new Cooki ...

  10. Linux的文件的打包(tar方法)

    Linux的文件的打包(tar方法) tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一 ...