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;
}
相关推荐
lijianhua_971220 小时前
国内某顶级大学内部用的ai自动生成论文的提示词
人工智能
EDPJ20 小时前
当图像与文本 “各说各话” —— CLIP 中的模态鸿沟与对象偏向
深度学习·计算机视觉
蔡俊锋20 小时前
用AI实现乐高式大型可插拔系统的技术方案
人工智能·ai工程·ai原子能力·ai乐高工程
自然语20 小时前
人工智能之数字生命 认知架构白皮书 第7章
人工智能·架构
大熊背20 小时前
利用ISP离线模式进行分块LSC校正的方法
人工智能·算法·机器学习
eastyuxiao20 小时前
如何在不同的机器上运行多个OpenClaw实例?
人工智能·git·架构·github·php
诸葛务农21 小时前
AGI 主要技术路径及核心技术:归一融合及未来之路5
大数据·人工智能
光影少年21 小时前
AI Agent智能体开发
人工智能·aigc·ai编程
charlee4421 小时前
最小二乘问题详解17:SFM仿真数据生成
c++·计算机视觉·sfm·数字摄影测量·无人机航测
ai生成式引擎优化技术21 小时前
TSPR-WEB-LLM-HIC (TWLH四元结构)AI生成式引擎(GEO)技术白皮书
人工智能