1.图像的加载与保存

文章目录


前言

本专栏专注于使用WPF框架结合OpenCvSharp4.Windows(版本4.11.0.20250507)实现高效的图像处理功能。

Nuget包版本特性: OpenCvSharp4.Windows 4.11.0.20250507 包含稳定的API接口与优化后的底层性能。

技术栈说明

  • WPF:通过现代化的UI设计和数据绑定机制,构建交互友好的图像处理应用程序。
  • OpenCvSharp4.Windows:基于OpenCV的.NET封装库,提供丰富的图像处理算法与高性能计算支持。

适用场景

  • 实时图像处理与滤镜应用
  • 计算机视觉任务(如边缘检测、特征提取)
  • 教学与工业级图像分析工具开发

一、入门

1.读取文件格式

选择适当的图像格式对性能至关重要。无损格式如 PNG 适合需要保留细节的场景,有损格式如 JPEG 适合存储空间有限的场景。对于需要快速加载的场景,可以考虑使用二进制格式或内存映射文件。OpenCVSharp 提供了 ImRead 函数用于加载图像,下面是加载两种不同格式的相关代码。

csharp 复制代码
// 加载 PNG(无损)
Mat img1 = Cv2.ImRead("image.png", ImreadModes.Color);

// 加载 JPEG(有损)
Mat img2 = Cv2.ImRead("image.jpg", ImreadModes.Color);

2.图像加载方法

OpenCVSharp还支持多种格式(BMP、JPEG、PNG、TIFF 等)。加载时可以指定不同的模式,如灰度、彩色或包含 Alpha 通道。

ImreadModes 通道模式说明

  • Grayscale:加载图像为单通道灰度模式。
  • Color:加载图像为三通道(BGR)彩色模式。
  • Unchanged:保留原始图像的通道数(如四通道包含 Alpha 通道)。
csharp 复制代码
// 加载为灰度图像
Mat grayImg = Cv2.ImRead("image.jpg", ImreadModes.Grayscale);

// 加载为彩色图像
Mat colorImg = Cv2.ImRead("image.jpg", ImreadModes.Color);

// 加载包含 Alpha 通道的图像
Mat alphaImg = Cv2.ImRead("image.png", ImreadModes.Unchanged);

3.图像属性访问

加载后的图像对象包含多种属性,可以获取图像的宽度、高度、通道数等信息。这些信息对于后续处理非常重要。

csharp 复制代码
int width = colorImg.Width;
int height = colorImg.Height;
int channels = colorImg.Channels();

4.图像保存方法

ImWrite 函数用于保存图像,支持多种格式。保存时可以指定特定参数,如 JPEG 质量或 PNG 压缩级别。

csharp 复制代码
// 基本保存
Cv2.ImWrite("output.jpg", colorImg);

// 带参数保存
Cv2.ImWrite("output.png", alphaImg, new int[] { (int)ImwriteFlags.PngCompression, 9 });

二、高级

1.批量处理图像

当需要处理多个图像时,使用批量加载和保存可以显著提高效率。通过循环或并行处理实现批量操作。

csharp 复制代码
string[] imagePaths = Directory.GetFiles("input_folder", "*.jpg");
foreach (string path in imagePaths)
{
    Mat img = Cv2.ImRead(path);
    // 保存图像
    Cv2.ImWrite("output_folder/" + Path.GetFileName(path), img);
}

2.图像编码与解码

除了文件操作,OpenCVSharp 还支持内存中的图像编码与解码。ImEncode 和 ImDecode 函数可以用于网络传输或数据库存储场景。

csharp 复制代码
// 编码为内存缓冲区
byte[] buffer;
Cv2.ImEncode(".jpg", colorImg, out buffer);

// 从内存缓冲区解码
Mat decodedImg = Cv2.ImDecode(buffer, ImreadModes.Color);

3.异步加载与保存

使用异步方法可以避免阻塞主线程,提升应用程序的响应速度。适用于需要处理大量图像或大尺寸图像的场景。

csharp 复制代码
async Task<Mat> LoadImageAsync(string path)
{
    return await Task.Run(() => Cv2.ImRead(path));
}

async Task SaveImageAsync(string path, Mat img)
{
    await Task.Run(() => Cv2.ImWrite(path, img));
}

4.调整图像尺寸

加载时降低分辨率可以减少内存占用和处理时间。通过设置加载参数或后期调整尺寸实现。

csharp 复制代码
// 加载时降低分辨率
Mat img = Cv2.ImRead("image.jpg", ImreadModes.ReducedColor2);

// 后期调整尺寸
Mat resized = new Mat();
Cv2.Resize(img, resized, new Size(img.Width / 2, img.Height / 2));

5.使用内存缓存

频繁加载相同图像时,使用内存缓存可以避免重复的磁盘读取操作。通过字典或专用缓存库实现。

csharp 复制代码
Dictionary<string, Mat> imageCache = new Dictionary<string, Mat>();

Mat GetCachedImage(string path)
{
    if (!imageCache.ContainsKey(path))
    {
        imageCache[path] = Cv2.ImRead(path);
    }
    return imageCache[path];
}

6.优化保存参数

调整保存参数可以在文件大小和质量之间取得平衡。JPEG 的质量参数和 PNG 的压缩级别可以自定义。

csharp 复制代码
// 保存 JPEG 并设置质量(1-100)
Cv2.ImWrite("output.jpg", img, new int[] { (int)ImwriteFlags.JpegQuality, 90 });

// 保存 PNG 并设置压缩级别(0-9)
Cv2.ImWrite("output.png", img, new int[] { (int)ImwriteFlags.PngCompression, 6 });

7.错误处理与验证

添加适当的错误处理可以避免因文件问题导致的程序崩溃。检查文件是否存在、格式是否正确以及操作是否成功。

csharp 复制代码
try
{
    if (File.Exists("image.jpg"))
    {
        Mat img = Cv2.ImRead("image.jpg");
        if (!img.Empty())
        {
            bool success = Cv2.ImWrite("output.jpg", img);
            if (!success) Console.WriteLine("保存失败");
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine($"错误: {ex.Message}");
}

8.多线程处理

对于多核系统,使用多线程可以加速图像处理任务。通过 Parallel.ForEach 或 Task 实现并行处理。

csharp 复制代码
Parallel.ForEach(imagePaths, path =>
{
    Mat img = Cv2.ImRead(path);
    // 处理图像
    Cv2.ImWrite("output_folder/" + Path.GetFileName(path), img);
});

9.硬件加速

利用硬件加速可以提高图像处理速度。检查并启用 OpenCV 的硬件优化选项,如 OpenCL 或 CUDA。

csharp 复制代码
// 启用 OpenCL 加速
Cv2.SetUseOpenCL(true);

10.格式转换

在不同格式间转换是常见操作。OpenCVSharp 提供了多种颜色空间转换函数,如 RGB 转灰度或 HSV。

csharp 复制代码
Mat hsvImg = new Mat();
Cv2.CvtColor(colorImg, hsvImg, ColorConversionCodes.BGR2HSV);

11.异常处理

OpenCV 操作可能因各种原因失败,如图文件损坏、权限不足等。合理的异常处理可以增强程序健壮性。

csharp 复制代码
try
{
    Mat img = Cv2.ImRead("nonexistent.jpg");
    if (img.Empty()) throw new Exception("图像加载失败");
}
catch (Exception ex)
{
    Console.WriteLine($"操作失败: {ex.Message}");
}
相关推荐
yang_B6212 小时前
C# ISerializable 允许对象控制自己的序列化/反序列化过程
java·开发语言·c#
智算菩萨2 小时前
OpenCV几何图形绘制工具全栈开发:从中文路径支持到交互式GUI的完整实战(附源码)
开发语言·图像处理·人工智能·python·opencv·计算机视觉
海盗12342 小时前
ScottPlot在WPF的基本使用和中文乱码问题
c#·.net·wpf
胡楚昊2 小时前
BUUCTF RE 看心情写(2)
开发语言·c#
第二只羽毛3 小时前
第四章 串
大数据·数据结构·c#
智算菩萨3 小时前
OpenCV+Python3.13图像读写实战:从文件加载到内存操作的全流程详解(附源码)
开发语言·图像处理·python·opencv·yolo
ejjdhdjdjdjdjjsl3 小时前
三角形缺陷检测,划痕检测和毛刺检测
c#
我是唐青枫3 小时前
C#.NET System.Threading.Lock 深入解析:新一代 lock、底层语义与使用边界
c#·.net
又是忙碌的一天3 小时前
从像素到形状:我用 OpenCV + YOLO 实现的单一特征识别实践
人工智能·opencv·yolo