1.图片读取与显示
就像计算机程序的基本数据处理过程一样:输入,处理,输出。
图片处理的过程也是一样:读取图片,处理图片,输出图片。
以下程序示例,实现这些最基本的操作:(增加了对原始图片和结果图片的展示)
#include <iostream>
#include <opencv2/opencv.hpp>
int main(int argc, char* argv[]) {
// 检查命令行参数
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <input_image> <output_image>" << std::endl;
return -1;
}
// [1] 读取输入图像 imread 完成对文件的读取,图片数据的解码,存放为 Mat 对象 这三个功能
cv::Mat inputImage = cv::imread(argv[1]);
if (inputImage.empty()) {
std::cerr << "Error: Could not load image " << argv[1] << std::endl;
return -1;
}
// [2] 显示原始图片
cv::namedWindow("Input Image", cv::WINDOW_NORMAL);
// 被显示的图片会经过一定的预处理,CV_16U和CV_32S 的像素值类型会被除以256.浮点型像素也会将 在 0.0 - 1.0之间的数据显示,小于 0 的显示黑色,大于1显示为白色。
cv::imshow("Input Image", inputImage);
// [3] 处理文档图像
cv::Mat result;
// 翻转图片 0 垂直翻转 1 水平翻转 -1 水平垂直翻转
cv::flip(inputImage, result, 1);
// [4] 显示处理结果
cv::namedWindow("Output Image", cv::WINDOW_NORMAL);
cv::imshow("Output Image", result);
// [5] 保存结果 imwrite 完成对文件的写入,图片数据的编码,保存为文件
if (!cv::imwrite(argv[2], result)) {
std::cerr << "Error: Could not save image to " << argv[2] << std::endl;
return -1;
}
std::cout << "Input image: " << argv[1] << std::endl;
std::cout << "Output image: " << argv[2] << std::endl;
// 等待窗口事件,而不是直接退出程序
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
2.highgui 鼠标事件回调与简单处理函数
2.1 highgui 鼠标事件回调
可以向对应窗口注册对应事件的回调函数,来对实现对应的交互事件逻辑。
以鼠标事件为例,先实现一个鼠标事件回调函数,然后将其设置为指定窗口的事件回调函数。
/**
* @brief 鼠标回调函数,处理鼠标事件
* @param event 鼠标事件类型,如点击、移动等
* @param x 鼠标点击位置的x坐标
* @param y 鼠标点击位置的y坐标
* @param flags 鼠标事件相关的标志位 cv::MouseEventFlags常量之一。
* @param userdata 用户自定义数据指针
*/
void mouseCallback(int event, int x, int y, int flags, void* userdata) {
}
...
别的代码
...
// 显示原始图片
cv::namedWindow("Input Image", cv::WINDOW_NORMAL);
// 设置鼠标回调函数
cv::setMouseCallback("Input Image", mouseCallback, reinterpret_cast<void*>(&inputImage));
2.2 简单处理函数
opencv提供了一些简单的方法,可以完成对图像的简单处理:
- cv::flip(原始图片, 结果图片, 1) 翻转图片 0 垂直翻转 1 水平翻转 -1 水平垂直翻转 可以用原始图片对象,直接作为结果图片的传入。
- 另外还有一些向图片上绘制文字图形的函数,可以在示例代码中查看使用方法。
完整示例代码:
#include <iostream>
#include <opencv2/opencv.hpp>
#include "src/document_processor.h"
// 获取当前时间字符串
std::string getCurrentTime() {
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
return buf;
}
/**
* @brief 鼠标回调函数,处理鼠标事件
* @param event 鼠标事件类型,如点击、移动等
* @param x 鼠标点击位置的x坐标
* @param y 鼠标点击位置的y坐标
* @param flags 鼠标事件相关的标志位 cv::MouseEventFlags常量之一。
* @param userdata 用户自定义数据指针
*
* 当用户左键点击时,输出点击位置坐标到控制台
*/
void mouseCallback(int event, int x, int y, int flags, void* userdata) {
cv::Mat* image = reinterpret_cast<cv::Mat*>(userdata);
if(image == nullptr || image->empty()) return;
if (event == cv::EVENT_LBUTTONDOWN) {
//写几个字
cv::putText(*image, "Time:" + getCurrentTime(), cv::Point(x, y), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0), 2);
//画几个图形
cv::circle(*image, cv::Point(x, y), 5, cv::Scalar(0, 0, 255), -1);
cv::rectangle(*image, cv::Point(x - 5, y - 5), cv::Point(x + 5, y + 5), cv::Scalar(0, 255, 0), -1);
cv::line(*image, cv::Point(x - 5, y - 5), cv::Point(x + 5, y + 5), cv::Scalar(255, 0, 0), 2);
std::cout << "Mouse clicked at (" << x << ", " << y << ") flags:" << flags
<< " Pixel Value:" << static_cast<int>(image->at<uchar>(cv::Point(x,y))) << std::endl;
//重绘,刷新显示
cv::imshow("Input Image", *image);
}
}
int main(int argc, char* argv[]) {
// 检查命令行参数
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <input_image> <output_image>" << std::endl;
return -1;
}
// 读取输入图像 imread 完成对文件的读取,图片数据的解码,存放为 Mat 对象 这三个功能
cv::Mat inputImage = cv::imread(argv[1]);
if (inputImage.empty()) {
std::cerr << "Error: Could not load image " << argv[1] << std::endl;
return -1;
}
//获取图片行数和列数
std::cout << "Image rows: " << inputImage.rows << ", columns: " << inputImage.cols << std::endl;
// 显示原始图片
cv::namedWindow("Input Image", cv::WINDOW_NORMAL);
// 设置鼠标回调函数
cv::setMouseCallback("Input Image", mouseCallback, reinterpret_cast<void*>(&inputImage));
// 被显示的图片会经过一定的预处理,CV_16U和CV_32S 的像素值类型会被除以256.浮点型像素也会将 在 0.0 - 1.0之间的数据显示,小于 0 的显示黑色,大于1显示为白色。
cv::imshow("Input Image", inputImage);
// 处理文档图像
cv::Mat result;
// 翻转图片 0 垂直翻转 1 水平翻转 -1 水平垂直翻转
cv::flip(inputImage, result, 1);
// 显示处理结果
cv::namedWindow("Output Image", cv::WINDOW_NORMAL);
cv::imshow("Output Image", result);
// 保存结果 imwrite 完成对文件的写入,图片数据的编码,保存为文件
if (!cv::imwrite(argv[2], result)) {
std::cerr << "Error: Could not save image to " << argv[2] << std::endl;
return -1;
}
std::cout << "Document processing completed successfully!" << std::endl;
std::cout << "Input image: " << argv[1] << std::endl;
std::cout << "Output image: " << argv[2] << std::endl;
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
结果:在鼠标点击位置处,会显示当前时间,并绘制几个图形和文字

1046

被折叠的 条评论
为什么被折叠?



