当前位置: 首页 > news >正文

六、OpenCV中的图像读写

文章目录

    • 一、基本用法
    • 二、示例代码
    • 三、只针对 Alpha 通道的读写示例
    • 四、两张图像的融合(叠加合成)

一、基本用法

OpenCV 里的图像读写操作是最常用的功能之一,主要依赖 imread 和 imwrite 这两个函数(以及少量配套函数)。

1.读取图像 imread

cv::Mat image = cv::imread(const std::string& filename, int flags = IMREAD_COLOR);

参数:

  • filename:图像文件路径,可以是 PNG、JPEG、BMP、TIFF 等常见格式。
  • flags:读取模式,常用选项:
    • IMREAD_COLOR(默认):以彩色方式读取,返回 3 通道 BGR。
    • IMREAD_GRAYSCALE:以灰度图方式读取,返回单通道。
    • IMREAD_UNCHANGED:原样读取(包括 Alpha 通道)。
    • IMREAD_ANYDEPTH:读入原始位深(例如 16 位图像不会被强制转成 8 位)。
    • IMREAD_ANYCOLOR:不管图像什么格式,都尽量转成彩色。

示例:

cv::Mat color = cv::imread("image.png");                      // 彩色
cv::Mat gray = cv::imread("image.png", cv::IMREAD_GRAYSCALE); // 灰度
cv::Mat withAlpha = cv::imread("image.png", cv::IMREAD_UNCHANGED); // 包含 Alpha

2.保存图像 imwrite

bool success = cv::imwrite(const std::string& filename, const cv::Mat& image, const std::vector<int>& params = {});

参数:

  • filename:保存路径,文件扩展名决定编码格式(如 .jpg、.png、.tiff)。
  • image:要保存的 Mat。
  • params:编码参数,不同格式有不同参数。
    • JPEG:IMWRITE_JPEG_QUALITY(默认 95,范围 0–100)。
    • PNG:IMWRITE_PNG_COMPRESSION(0–9,数值越大压缩越强,文件小但耗时更长)。
    • TIFF:支持多页存储(可以传 vector<Mat>)。
    • WebP:IMWRITE_WEBP_QUALITY(0–100)。

示例:

cv::imwrite("gray.jpg", gray);  // 保存为 JPEG(有损)std::vector<int> params;
params.push_back(cv::IMWRITE_PNG_COMPRESSION);
params.push_back(9);  // 最强压缩
cv::imwrite("alpha.png", withAlpha, params);

3.判断读写是否成功

  • imread 如果失败(文件不存在、路径错误、格式不支持),会返回一个 空 Mat(mat.empty() == true)。
  • imwrite 返回 true/false,保存失败时返回 false 或抛异常。

4.显示图像(配合 imshow)
通常读写图像后会想看效果,可以用:

cv::imshow("window", image);
cv::waitKey(0); // 等待键盘输入,否则窗口一闪而过

5.多页读写(TIFF/多帧图像)
读取多页:

std::vector<cv::Mat> pages;
cv::imreadmulti("test.tiff", pages, cv::IMREAD_ANYCOLOR);

保存多页:

std::vector<cv::Mat> imgs = {mat1, mat2, mat3};
cv::imwrite("test.tiff", imgs);

二、示例代码

完整的 OpenCV 图像读写示例代码,涵盖了常见场景:读取、灰度化、保存 PNG、保存多页 TIFF。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main()
{// 1. 读取彩色图像Mat color = imread("input.jpg", IMREAD_COLOR);if (color.empty()) {cerr << "无法读取图像,请检查路径!" << endl;return -1;}imshow("原图", color);// 2. 转换为灰度图Mat gray;cvtColor(color, gray, COLOR_BGR2GRAY);imshow("灰度图", gray);// 3. 保存为 PNG(带压缩参数)vector<int> png_params;png_params.push_back(IMWRITE_PNG_COMPRESSION);png_params.push_back(9); // 0 = 无压缩,9 = 最大压缩if (!imwrite("output.png", color, png_params)) {cerr << "保存 PNG 失败!" << endl;} else {cout << "保存 output.png 成功!" << endl;}// 4. 保存为 JPEG(设置质量)vector<int> jpg_params;jpg_params.push_back(IMWRITE_JPEG_QUALITY);jpg_params.push_back(95); // 默认质量 95if (!imwrite("output.jpg", gray, jpg_params)) {cerr << "保存 JPEG 失败!" << endl;} else {cout << "保存 output.jpg 成功!" << endl;}// 5. 保存多页 TIFF(原图 + 灰度图)vector<Mat> imgs;imgs.push_back(color);imgs.push_back(gray);if (!imwrite("output.tiff", imgs)) {cerr << "保存 TIFF 失败!" << endl;} else {cout << "保存多页 output.tiff 成功!" << endl;}// 6. 读取多页 TIFFvector<Mat> pages;if (imreadmulti("output.tiff", pages, IMREAD_ANYCOLOR)) {cout << "读取 TIFF 成功,页数: " << pages.size() << endl;for (size_t i = 0; i < pages.size(); i++) {imshow("Page " + to_string(i), pages[i]);}} else {cerr << "读取 TIFF 失败!" << endl;}waitKey(0);return 0;
}

三、只针对 Alpha 通道的读写示例

图像的Alpha 通道的作用?
在图像处理中,Alpha 通道就是透明度通道(Opacity/Transparency Channel),它在 RGB 颜色通道之外,额外增加了一层,用来描述每个像素的“透明程度”。

通道概念

  • 普通彩色图像:3 通道 → R(红)、G(绿)、B(蓝)
  • 带 Alpha 的彩色图像:4 通道 → R、G、B + A(透明度)

Alpha 通道的取值

  • 8 位图像中,范围是 0 ~ 255
  • 0 表示完全透明
  • 255 表示完全不透明
  • 中间值表示半透明(常用于渐变、阴影、反射等效果)

Alpha 通道的作用
透明背景:

  • 允许图像在叠加时背景透过去。
  • 例如:PNG 图标放在网页上时,背景透明,不会出现难看的白底或黑底。

图像合成(混合)

  • 在图像 A 上叠加图像 B,利用 Alpha 通道进行“加权混合”。
  • OpenCV 中可用 addWeighted 或 cv::Mat 的逐像素运算。

混合公式(常用 Alpha Blending):

C=α⋅F+(1−α)⋅B
  • C:最终像素
  • F:前景像素
  • B:背景像素
  • α:前景的 Alpha 值(0~1 之间)

图像遮罩(Mask)

  • Alpha 通道可以当作“掩码”,决定哪些区域可见,哪些区域不可见。
  • 常用于抠图、虚化、贴图。

示例代码:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main()
{// 1. 读取带 Alpha 通道的 PNGMat img = imread("input.png", IMREAD_UNCHANGED);if (img.empty()) {cerr << "无法读取 input.png,请检查路径!" << endl;return -1;}// 确认是否有 4 通道if (img.channels() != 4) {cerr << "图像没有 Alpha 通道!" << endl;return -1;}cout << "读取到 " << img.cols << "x" << img.rows << " 的图像,通道数: " << img.channels() << endl;// 2. 分离 BGR 和 Alphavector<Mat> channels;split(img, channels);  // channels[0]=B, [1]=G, [2]=R, [3]=AMat b = channels[0], g = channels[1], r = channels[2], alpha = channels[3];// 显示 Alpha 通道imshow("Alpha 通道", alpha);// 3. 对 Alpha 通道做处理(示例:取反)Mat alpha_inv;bitwise_not(alpha, alpha_inv);  // 透明变不透明,反之亦然imshow("Alpha 取反", alpha_inv);// 4. 合并 BGR 和新 Alphachannels[3] = alpha_inv;Mat output;merge(channels, output);// 5. 保存 PNG(带 Alpha)vector<int> params;params.push_back(IMWRITE_PNG_COMPRESSION);params.push_back(9);if (!imwrite("output.png", output, params)) {cerr << "保存 output.png 失败!" << endl;} else {cout << "保存带 Alpha 通道的 output.png 成功!" << endl;}waitKey(0);return 0;
}

四、两张图像的融合(叠加合成)

基本原理(Alpha 混合公式)
对于前景图 F 和背景图 B,融合后的图像 C 的像素计算公式是:

C=α⋅F+(1−α)⋅B

α:融合比例(0.0 ~ 1.0)

  • 1.0 → 完全显示前景
  • 0.0 → 完全显示背景
  • 0.5 → 前景和背景各占一半

OpenCV 提供了现成的函数 cv::addWeighted:

void addWeighted(InputArray src1, double alpha,InputArray src2, double beta,double gamma, OutputArray dst);
  • src1、src2:输入图像(大小和类型需一致)
  • alpha、beta:权重(一般 alpha + beta = 1)
  • gamma:加到结果上的常数偏移量(通常为 0)
  • dst:输出图像

示例代码:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;int main()
{// 1. 读取两张图片Mat img1 = imread("opencv_demo_1.png");Mat img2 = imread("opencv_demo_2.png");if (img1.empty() || img2.empty()) {cerr << "无法读取图像!" << endl;return -1;}// 2. 调整大小(确保两张图尺寸相同)resize(img2, img2, img1.size());// 3. 融合Mat blended;double alpha = 0.8;  // 前景权重double beta = 1.0 - alpha; // 背景权重addWeighted(img1, alpha, img2, beta, 0.0, blended);// 4. 显示和保存imshow("图像1", img1);imshow("图像2", img2);imshow("融合结果", blended);imwrite("blended.jpg", blended);waitKey(0);return 0;
}
http://www.dtcms.com/a/403010.html

相关文章:

  • 设计案例的网站pc开奖网站建设
  • 10月底实习准备-Mysql(按面试频率准备)
  • Flink Watermark机制解析
  • Windows系统Web UI自动化测试学习系列2--环境搭建--Python-PyCharm-Selenium
  • 实战:基于HarmonyOS 5构建分布式聊天通讯应用
  • 承德网站建设公司网页设计模板设计
  • HCIP-IoT/H52-111 真题详解(章节C),接入技术和网络设计 /Part1
  • 灵画-AI绘画小程序
  • 从拆盒到共创:手办盲盒抽赏小程序的多元体验与文化联结
  • 做网站必须学php吗现在感染症状有哪些
  • 如何在电脑上备份Redmi
  • 云计算实验1——CentOS中hadoop的安装
  • 使用 Captura 和 FFmpeg 配置免费高效的录屏环境
  • FFmpeg安装(Windows)
  • 电子商务网站建设与管理英文网站开发方式演进
  • Jenkins运维之路(共享库集成流水线发布)
  • 论文精读:mmDrive: Fine-grained Fatigue Driving Detection Using mmWave Radar
  • 网站多媒体加载卡顿?视频压缩 + 音频优化,加载速度提升 75% 的实操方法
  • 关于Modbus CRC16生成算法的一些理解
  • Springboot整合Netty的启动方式(二)
  • 17.15 ChatPPT深度拆解:GLM-4多模态引擎如何实现23.6%成本优势碾压竞品?
  • 计算机系毕设代做网站自已建网站卖东西要多少钱
  • Nginx反向代理与缓存功能
  • clickhouse-backup备份
  • JavaWeb--day10--SpringBootWeb案例(二)
  • 专业网站建设找哪家好厦门帮忙建设网站
  • 化工材料 技术支持 东莞网站建设域名分析网站
  • 避坑指南:Java 中字段的命名 “陷阱”—success和isSuccess
  • 从 ZooKeeper 到 ELK:分布式中间件与日志分析系统全解析
  • 专业视频修复软件,简单操作效果好