OpenCV 读取和显示图像功能详解

以下是 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;
}
相关推荐
cxr8282 小时前
全栈规模化虚拟企业:下一代商业物种的系统演进与架构重构
人工智能·重构·架构·智能体·ai智能体·openclaw
SeatuneWrite2 小时前
**手机专业写剧本软件哪家可靠2025推荐,适配多场景创作与
人工智能·python·智能手机
带娃的IT创业者2 小时前
Attention 如何成为全局工作空间?——Miller 定律的深度学习诠释
人工智能·深度学习·神经网络·脑机接口·ai智能体·nct·硅基生命
minhuan2 小时前
大模型应用:从手动调参到智能寻优:PSO 驱动的大模型参数自动化优化.94
人工智能·机器学习·粒子群优化算法·pso算法·大模型应用
belldeep2 小时前
python:如何将豆包AI中历史对话 备份到本地 backup目录下?
人工智能·python·ai·自动化·backup·豆包
njsgcs2 小时前
astrbot部署几个注意点
人工智能
hughnz2 小时前
基于实时数据的卡钻风险计算方法
人工智能·机器学习·数据分析
zhangshuang-peta2 小时前
模型上下文协议(MCP)与MCP网关:概念、架构及案例研究
人工智能·ai agent·mcp·peta
沃达德软件2 小时前
视频监控数据分析技术
人工智能·深度学习·目标检测·计算机视觉·数据挖掘·数据分析·视觉检测