以下是 OpenCV 中图像读取和显示功能的参数解析和说明
1. 图像读取 (imread)
基本用法
cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
// 读取图像文件
Mat image = imread("test.jpg");
// 检查是否读取成功
if (image.empty()) {
std::cout << "无法读取图像文件!" << std::endl;
return -1;
}
std::cout << "图像尺寸: " << image.cols << " x " << image.rows << std::endl;
std::cout << "通道数: " << image.channels() << std::endl;
std::cout << "数据类型: " << image.type() << std::endl;
return 0;
}
读取模式参数 (ImreadModes)
cpp
// 强制转换为灰度图
Mat gray = imread("test.jpg", IMREAD_GRAYSCALE);
// 保持原样(包括alpha通道)
Mat unchanged = imread("test.png", IMREAD_UNCHANGED);
// 彩色图(默认)
Mat color = imread("test.jpg", IMREAD_COLOR);
// 以任意深度读取
Mat any_depth = imread("test.tif", IMREAD_ANYDEPTH);
// 常用读取模式组合
Mat any_color_depth = imread("test.tif", IMREAD_ANYCOLOR | IMREAD_ANYDEPTH);
完整读取模式列表:
• IMREAD_UNCHANGED = -1 // 保留原样
• IMREAD_GRAYSCALE = 0 // 强制转为灰度
• IMREAD_COLOR = 1 // 转为彩色(BGR)
• IMREAD_ANYDEPTH = 2 // 保持原深度
• IMREAD_ANYCOLOR = 4 // 保持原色彩
• IMREAD_LOAD_GDAL = 8 // 使用GDAL驱动
• IMREAD_REDUCED_GRAYSCALE_2 = 16 // 灰度+缩小2倍
• IMREAD_REDUCED_COLOR_2 = 17 // 彩色+缩小2倍
• IMREAD_REDUCED_GRAYSCALE_4 = 32 // 灰度+缩小4倍
• IMREAD_REDUCED_COLOR_4 = 33 // 彩色+缩小4倍
• IMREAD_REDUCED_GRAYSCALE_8 = 64 // 灰度+缩小8倍
• IMREAD_REDUCED_COLOR_8 = 65 // 彩色+缩小8倍
• IMREAD_IGNORE_ORIENTATION = 128 // 忽略EXIF方向
文件格式支持
OpenCV 支持多种图像格式:
• 常见格式:JPEG, PNG, BMP, TIFF, WebP
• 特殊格式:DICOM, PGM, PPM, PBM, SR, RAS
• RAW格式:支持部分相机RAW文件
cpp
// 检查支持的格式
std::vector<cv::String> formats;
cv::imreadmulti("test.tiff", formats); // 多页TIFF
错误处理最佳实践
cpp
Mat readImageSafe(const std::string& filename, int flags = IMREAD_COLOR) {
Mat img = imread(filename, flags);
if (img.empty()) {
// 尝试用绝对路径
std::string abs_path = cv::samples::findFile(filename);
img = imread(abs_path, flags);
if (img.empty()) {
std::cerr << "错误: 无法读取图像 '" << filename << "'" << std::endl;
// 创建空图像或抛出异常
throw std::runtime_error("图像读取失败");
}
}
return img;
}
2. 图像显示 (imshow)
基本显示
cpp
// 创建窗口并显示图像
namedWindow("显示窗口", WINDOW_AUTOSIZE);
imshow("显示窗口", image);
// 等待按键
waitKey(0); // 0表示无限等待
destroyWindow("显示窗口"); // 关闭单个窗口
destroyAllWindows(); // 关闭所有窗口
窗口属性设置
cpp
// 创建可调整大小的窗口
namedWindow("可调整窗口", WINDOW_NORMAL);
resizeWindow("可调整窗口", 800, 600);
// 创建全屏窗口
namedWindow("全屏窗口", WINDOW_FULLSCREEN);
// 或使用
namedWindow("全屏窗口", WINDOW_GUI_EXPANDED);
setWindowProperty("全屏窗口", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
// 设置窗口位置
moveWindow("显示窗口", 100, 100);
窗口标志参数:
• WINDOW_NORMAL:可调整大小
• WINDOW_AUTOSIZE:自动适应图像大小
• WINDOW_OPENGL:支持OpenGL
• WINDOW_FULLSCREEN:全屏
• WINDOW_FREERATIO:自由比例
• WINDOW_KEEPRATIO:保持比例
• WINDOW_GUI_NORMAL:基本GUI
• WINDOW_GUI_EXPANDED:增强GUI
多图像显示
cpp
// 水平拼接显示
Mat combined;
hconcat(image1, image2, combined);
imshow("双图对比", combined);
// 垂直拼接显示
vconcat(image1, image2, combined);
// 网格显示(需要自定义函数)
void showImagesGrid(const std::vector<Mat>& images, int cols, const std::string& winname) {
int rows = (images.size() + cols - 1) / cols;
Size cell_size = images[0].size();
Mat grid(cell_size.height * rows, cell_size.width * cols, images[0].type());
for (int i = 0; i < images.size(); i++) {
int row = i / cols, col = i % cols;
Mat cell = grid(Rect(col * cell_size.width, row * cell_size.height,
cell_size.width, cell_size.height));
images[i].copyTo(cell);
}
namedWindow(winname, WINDOW_NORMAL);
imshow(winname, grid);
}
图像信息覆盖,将图像基础信息覆盖在图像层上
cpp
// 在图像上绘制信息
Mat display_img = image.clone();
std::string info = "尺寸: " + std::to_string(image.cols) + "x" + std::to_string(image.rows);
putText(display_img, info, Point(10, 30), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0,255,0), 2);
imshow("带信息图像", display_img);
鼠标交互,这里只演示获取交互点的BGR值,实战可以发散思维。比如获取点击的两点以此两点的坐标做矩形并在原图里截取出来,以达到鼠标点击截取图片分析的交互效果
cpp
// 鼠标回调函数
void mouseCallback(int event, int x, int y, int flags, void* userdata) {
if (event == EVENT_LBUTTONDOWN) {
std::cout << "点击位置: (" << x << ", " << y << ")" << std::endl;
Mat* img = static_cast<Mat*>(userdata);
Vec3b pixel = img->at<Vec3b>(y, x);
std::cout << "BGR值: (" << (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ")" << std::endl;
}
}
// 设置鼠标回调
namedWindow("交互窗口", WINDOW_AUTOSIZE);
setMouseCallback("交互窗口", mouseCallback, &image);
imshow("交互窗口", image);
waitKey(0);
键盘交互
cpp
int key = waitKey(0);
switch (key) {
case 27: // ESC键
std::cout << "退出程序" << std::endl;
break;
case 's': // s键保存
imwrite("saved_image.jpg", image);
std::cout << "图像已保存" << std::endl;
break;
case 'q': // q键退出
return 0;
default:
std::cout << "按键: " << key << std::endl;
}