前言
开局一张图,内容全靠编。
在深入学习OpenCV的使用时,首先要了解一些概念和方法。
1.使用OpenCV 的类和函数的方法
在 OpenCV 的 C++ API 中,所有类和函数都在命名空间 cv 内定义。访问它们的方法共有两种。
第一种:在定义 main 函数前使用如下声明:
using namespace cv;
第二种:根据命名空间规范给所有 OpenCV 的类和函数加上前缀 cv::。
推荐使用第二种方法,便于初学者识别。
2.在读入图像的同时进行色彩转换
装载图像时转换为灰度图像,这样生成的图像由无符号字节(unsigned byte,C++中为 unsigned char)构成,在 OpenCV中用 CV_8U 表示。
// 读入一个图像文件并将其转换为灰度图像
image= cv::imread("test.bmp", CV::IMREAD_GRAYSCALE);
读入时转换成三通道彩色图像。即使图像是作为灰度图像保存的,有时仍需要在读入时把它转换成三通道彩色图像。在这样生成的图像中,每个像素有 3 字节,OpenCV 中用 CV_8UC3 表示。如果输入的图像文件是灰度图像,这三个通道的值就是相同的。
// 读取图像,并将其转换为三通道彩色图像
image= cv::imread("test.bmp", CV::IMREAD_COLOR);
注意:当用 imread 打开路径指定不完整的图像时,imread 会自动采用默认目录。
3.检查图像的通道数
std::cout << "This image has " << image.channels() << " channel(s)";
4.显示图像
cv::imshow("Original Image", image);
5.鼠标事件响应
在图像上点击,控制台就会显示对应像素的值(这里假定它是灰度图像)
函数声明:
void onMouse(int event, int x, int y, int flags, void* param);
调用方法:
cv::setMouseCallback("Original Image", onMouse,
reinterpret_cast<void*>(&image));
函数定义:
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;
}
}
6.图像上绘图和写入文本
基本的形状绘制函数有circle、ellipse、line 和 rectangle。
例:使用 circle 和 putText
cv::circle(image, // 目标图像
cv::Point(255, 240), // 中心点坐标
65, // 半径
0, // 颜色(这里用黑色)
3); // 厚度
cv::putText(image, // 目标图像
"This is a wolf.", // 文本
cv::Point(120, 350), // 文本位置
cv::FONT_HERSHEY_PLAIN, // 字体类型
2.0, // 字体大小
255, // 字体颜色(这里用蓝色)
2); // 文本厚度
测试结果:
注意:只有在包含顶层模块头文件 opencv2/imgproc.hpp 的前提下,这些例子才能正常运行
附:
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
void onMouse(int event, int x, int y, int flags, void* param);
int main()
{
cv::Mat image; // 创建一个空图像
std::cout << "This image is " << image.rows << " x "
<< image.cols << std::endl;
image = cv::imread("test.bmp"); // 读取输入图像
//image = cv::imread("test.bmp", cv::IMREAD_GRAYSCALE);
//image = cv::imread("output.bmp", cv::IMREAD_COLOR);
if (image.empty()) { // 错误处理
// 未创建图像……
// 可能显示一个错误消息
// 并退出程序
std::cout << "no image!\n";
}
else
{
//检查图像的通道数
std::cout << "This image has " << image.channels() << " channel(s)";
// 定义窗口(可选)
cv::circle(image, // 目标图像
cv::Point(255, 240), // 中心点坐标
65, // 半径
0, // 颜色(这里用黑色)
3); // 厚度
cv::putText(image, // 目标图像
"This is a wolf.", // 文本
cv::Point(120, 350), // 文本位置
cv::FONT_HERSHEY_PLAIN, // 字体类型
2.0, // 字体大小
255, // 字体颜色(这里用蓝色)
2); // 文本厚度
cv::namedWindow("Original Image");
// 显示图像
cv::imshow("Original Image", image);
cv::setMouseCallback("Original Image", onMouse,
reinterpret_cast<void*>(&image));
cv::waitKey(0); // 0 表示永远地等待按键
// 键入的正数表示等待的毫秒数
cv::Mat result; // 创建另一个空的图像
cv::flip(image, result, 1); // 正数表示水平
// 0 表示垂直
// 负数表示水平和垂直
cv::namedWindow("Output Image"); // 输出窗口
cv::imshow("Output Image", result);
cv::waitKey(0); // 0 表示永远地等待按键
// 键入的正数表示等待的毫秒数
cv::imwrite("output.bmp", result); // 保存结果
std::cout << "This image is " << image.rows << " x "
<< image.cols << std::endl;
}
system("pause");
return 0;
}
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;
}
}