OpenCV计算机视觉编程笔记(一)
第一章
- 基本操作
定义头文件
#include <opencv2/core.hpp> //图像数据结构的核心文件
#include <opencv2/highgui.hpp> //包含了所有图形接口函数
定义表示图像的变量
cv::Mat image; // 创建一个空图像
读取图像
image= cv::imread("puppy.bmp"); // 读取输入图像
// 读入一个图像文件并将其转换为灰度图像
image= cv::imread("puppy.bmp", CV::IMREAD_GRAYSCALE);
// 读取图像,并将其转换为三通道彩色图像(虽然是灰度图像但依然是三通道表示)
image= cv::imread("puppy.bmp", CV::IMREAD_COLOR);
显示图像
// 定义窗口(可选)
cv::namedWindow("Original Image");
// 显示图像
cv::imshow("Original Image", image);
保存图像
cv::imwrite("output.bmp", result); // 保存结果
2.鼠标回调函数的使用(实现鼠标左键单击时在命令控制台输出点击位置的像素值-暂时针对灰度图)
(1)鼠标回调函数的原型
void onMouse(
int event, //事件类型
int x, int y, //鼠标位置
int flags, //事件发生时按下鼠标哪个键
void* param); //设置回调函数时指定的参数
(2)定义鼠标的回调函数
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:
std::cout << "at("<<x<<","<<y<<")value is: "
<< static_cast<int>
im->at<uchar>(cv::Point(x,y)))
<<std::endl;
break;
}
}
(3)在Main函数中设置鼠标的回调函数
cv::setMouseCallback(
"Image",//捕获鼠标事件的窗口
onMouse, //鼠标回调函数名
reinterpret_cast<void*>(&image)); //传图像对象的指针
- 在图像上绘图
图形绘制函数有 circle,ellipse,line,rectangle
例:使用Circle函数的例子
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); // 文本厚度
- 深入了解cv::Mat
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
// 测试函数,它创建一幅图像
cv::Mat function() {
// 创建图像
cv::Mat ima(500,500,CV_8U,50);
// 返回图像
return ima;
}
int main() {
// 创建一个 240 行×320 列的新图像
cv::Mat image1(240,320,CV_8U,100);
cv::imshow("Image", image1); // 显示图像
cv::waitKey(0); // 等待按键
// 重新分配一个新图像
image1.create(200,200,CV_8U);
image1= 200;
cv::imshow("Image", image1); // 显示图像
cv::waitKey(0); // 等待按键
// 创建一个红色的图像
// 通道次序为 BGR
cv::Mat image2(240,320,CV_8UC3,cv::Scalar(0,0,255));
// 或者
// cv::Mat image2(cv::Size(320,240),CV_8UC3);
// image2= cv::Scalar(0,0,255);
cv::imshow("Image", image2); // 显示图像
cv::waitKey(0); // 等待按键
// 读入一幅图像
cv::Mat image3= cv::imread("puppy.bmp");
// 所有这些图像都指向同一个数据块
cv::Mat image4(image3); image1= image3;
// 这些图像是源图像的副本图像
image3.copyTo(image2); cv::Mat image5= image3.clone();
// 转换图像进行测试
cv::flip(image3,image3,1);
// 检查哪些图像在处理过程中受到了影响
cv::imshow("Image 3", image3);
cv::imshow("Image 1", image1);
cv::imshow("Image 2", image2);
cv::imshow("Image 4", image4);
cv::imshow("Image 5", image5);
cv::waitKey(0); // 等待按键
// 从函数中获取一个灰度图像
cv::Mat gray= function();
cv::imshow("Image", gray); // 显示图像
cv::waitKey(0); // 等待按键
// 作为灰度图像读入
image1= cv::imread("puppy.bmp", CV_LOAD_IMAGE_GRAYSCALE); image1.convertTo(image2,CV_32F,1/255.0,0.0);
cv::imshow("Image", image2); // 显示图像
cv::waitKey(0); // 等待按键
return 0;
}
cv::Mat 有两个必不可少的组成部分:一个头部和一个数据块。头部包含了矩阵的所有相关 信息(大小、通道数量、数据类型等),数据块包含了图像中所有像素的值。
当在两幅图 像之间赋值时,图像数据(即像素)并不会被复制,此时两幅图像都指向同一个内存块。
- 定义感兴趣区域(定义子区域,并将这个区域当作普通图像进行操作)
(1)定义ROI,定义之后,就能把ROI当作一个普通的cv::Mat实例进行操作
// 在图像的右下角定义一个 ROI
cv::Mat imageROI(image, cv::Rect(image.cols-logo.cols, //ROI坐标
image.rows-logo.rows,
logo.cols,logo.rows)); // ROI 大小
// 插入标志
logo.copyTo(imageROI);