学习opencv day2

学习opencv day2

今天是系统学习opencv的第二天
使用工具为opencv4.4.0+vs2019
并已使用cmake配置contrib
参考书目为《opencv计算机视觉编程攻略》+《学习opencv3》

一、day1程序实现原理

1、类和函数的定义

在OpenCV的C++ API中,所有类和函数都在命名空间cv内定义。访问他们的方法有两种。第一种是在定义main函数钱使用如下声明:

using namespace cv;

第二种是根据命名空间规范给所有OpenCV的类和函数加上前缀cv::,接下来学习主要采用此种方法,添加前缀后,代码中OpenCV的类和函数将更容易识别。

2、cv::flip函数

前程序中同时使用了输入和输出图像,可以改成就地处理的方式,即不定义输出图像而直接写入原图像:

cv::flip(image,image,1);     //就地处理

扩展阅读

highgui模块中有大量可用来处理图像的函数,他们可以使用程序对鼠标或键盘事件作出响应,也可以在图像上回执形状或写入文本。

1、在图像上点击

采用回调函数的形式,回调函数不会被显式地调用,但是会在响应特定事件(这里是指有关鼠标与 图像窗口交互的事件)的时候被程序调用。为了能被程序识别,回调函数需要具有特定的签名, 并且必须注册。对于鼠标事件处理函数,回调函数必须具有这种签名:

void onMouse( int event, int x, int y, int flags, void* param); 

Event是整数,表示出发会点函数的鼠标事件的类型。

X 和 Y为事件发生时鼠标的坐标,用像素坐标表示。

flags表示事件发生的时候按下鼠标的那个键。

param是指向任意对象的指针,作为附件的参数发送给函数。
你可用下面的方法在程序中注册回调函数:

cv::setMouseCallback("Original Image", onMouse,reinterpret_cast<void*>(&image)); 

原型如下:

void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0);

winname:窗口名称

onMouse:鼠标事件的回调函数。指定窗口里每次鼠标时间发生的时候被调用的函数指针。

userdate:传递给回调的可选参数。

鼠标事件
EVENT_MOUSEMOVE 滑动
EVENT_LBUTTONDOWN 左键点击
EVENT_RBUTTONDOWN 右键点击
EVENT_MBUTTONDOWN 中键点击
EVENT_LBUTTONUP 左键放开
EVENT_RBUTTONUP 右键放开
EVENT_MBUTTONUP 中键放开
EVENT_LBUTTONDBLCLK 左键双击
EVENT_RBUTTONDBLCLK 右键双击
EVENT_MBUTTONDBLCLK 中键双击

在本例中,函数 onMouse 与名为 Original Image(原始图像)的图像窗口建立了关联,同时把所显示图像的地址作为附加参数传给函数。现在,只要用下面的代码定义回调函数 onMouse,每当遇到鼠标点击事件时,控制台就会显示对应像素的值(这里假定它是灰度图像):

void onMouse( int event, int x, int y, int flags, void* param) {
 cv::Mat *im= reinterpret_cast<cv::Mat*>(param);
 switch (event) { // 调度事件
 case CV::EVENT_LBUTTONDOWN: // 鼠标左键按下事件
 // 显示像素值(x,y)
 std::cout << "at (" << x << "," << y << ") value is: "
 << static_cast<int>(
 im->at<uchar>(cv::Point(x,y))) << std::endl;
 break;
 }
} 

这里用 cv::Mat 对象的 at 方法来获取(x, y)的像素值:

适用于取具体第i行,第j列的像素,不适用于遍历像素im->at<uchar>(i,j); //取灰度图像中第i行第j列的点 im->at<Vec3b>(i,j)[K] //取彩色图像中第i行第j列第K通道的点

2、在图像上绘图

OpenCV 还提供了几个用于在图像上绘制形状和写入文本的函数。基本的形状绘制函数有circle、ellipse、line 和 rectangle。在 OpenCV 的方法和函数中,我们经常用 cv::Point 结构来表示像素的坐标。这里假定是在灰度图像上进行绘制的,因此用单个整数来表示颜色。

cv::circle(image, // 目标图像
 		   cv::Point(155,110), // 中心点坐标
 		   65, // 半径
 		   0, // 颜色(这里用黑色)
 		   3); // 厚度

在图像上写入文本:

cv::putText(image, // 目标图像
 		    "This is a dog.", // 文本
 cv::Point(40,200), // 文本位置
 		   cv::FONT_HERSHEY_PLAIN, // 字体类型
	       2.0, // 字体大小
		   255, // 字体颜色(这里用白色)
 		   2); // 文本厚度

注意:需加上顶层模块头文件 opencv2/imgproc.hpp

二、cv::Mat数据结构

cv::Mat ima(500, 500, CV_8U, 50); //500为尺寸,cv_8u表示8位无符号整数(灰度图像),50为灰度值或者颜色
//也可写作 cv::Mat image1(240,320,CV_8U,cv::Scalar(100));
// 所有这些图像都指向同一个数据块
	cv::Mat image4(image3);
	image1 = image3;
	// 这些图像是源图像的副本图像
	image3.copyTo(image2);
	cv::Mat image5 = image3.clone();

1、image.copyTo(image),作用是把image的内容粘贴到image中;
2、image.copyTo(image,mask),作用是把mask和image重叠以后把mask中像素值为0(black)的点对应的image中的点变为透明,而保留其他点[1]。

可以随时用 create 方法分配或重新分配图像的数据块。如果图像已被分配,其原来的内容
会先被释放。出于对性能的考虑,如果新的尺寸和类型与原来的相同,就不会重新分配内存:

// 重新分配一个新图像
//(仅在大小或类型不同时)
image.create(200,200,CV_8U); 

[1] https://blog.csdn.net/dxrose/article/details/89158387

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值