编辑
2025-02-03
OpenCvSharp 入门
00
请注意,本文编写于 92 天前,最后修改于 92 天前,其中某些信息可能已经过时。

目录

前提条件
读取图像文件
读取模式
图像显示
检查图像是否读取成功
完整示例
Cv2.Canny(grayImage, edgeImage, 100, 200);
两个阈值的确定方法
总结

OpenCvSharp 是 OpenCV 在 .NET 环境中的封装,通过它我们可以轻松地实现各种图像处理操作。本文将详尽地介绍如何使用 OpenCvSharp 读取图像文件,并展示一些常见的操作。

前提条件

在开始之前,请确保你的开发环境已经配置好,并且项目中已经安装了 OpenCvSharp。可以通过 NuGet 包管理器安装:

Bash
Install-Package OpenCvSharp4 Install-Package OpenCvSharp4.runtime.win

读取图像文件

图像文件读取是图像处理的第一步,OpenCvSharp 提供了 Cv2.ImRead 方法来读取图像文件。以下是一个简单的示例:

C#
using System; using OpenCvSharp; namespace OpenCvSharpExample { class Program { static void Main(string[] args) { // 读取图像 Mat src = Cv2.ImRead("example.jpg", ImreadModes.Color); if (src.Empty()) { Console.WriteLine("无法读取图像!"); return; } // 显示图像 Cv2.ImShow("显示图像", src); Cv2.WaitKey(0); // 释放资源 src.Dispose(); Cv2.DestroyAllWindows(); } } }

在这个示例中,我们读取了一张名为 example.jpg 的图像并显示出来。

读取模式

Cv2.ImRead 方法接受两个参数:文件路径和读取模式。常用的读取模式如下:

  • Unchanged (值为 -1): 该模式表示以完全未修改的方式读取图像。包含原图像的 Alpha 通道(透明通道),如果图像有的话。这意味着图像的通道数和深度将保持不变。
  • Grayscale (值为 0): 该模式将图像读取为灰度图像,忽略原图像的彩色信息。图像的通道数为 1,表示每个像素仅有一个灰度值。
  • Color (值为 1): 该模式读取图像时将忽略 Alpha 通道,并将图像转换为 BGR(蓝、绿、红)格式。图像会有 3 个通道。注意 OpenCV 使用的是 BGR 而不是通常的 RGB 顺序。(默认)
  • AnyDepth (值为 2): 按照图像文件的深度读取图像,但忽略其通道数。例如,16位图像会保持16位深度。如果你想保留图像的原始深度,可以使用这个模式。
  • AnyColor (值为 4): 忽略图像文件的颜色类型。意味着图像将被解码为具有与文件中相同颜色类型的形式,例如16位单通道灰度图像。然而,通常读者不经常使用这个选项,因为它更高级和特殊化。
  • LoadGdal (值为 8): 仅适用于 Gdal 驱动加载的图像,用于特定的地理空间图像处理。普通图像处理使用时基本不需要这个选项。

示例:

C#
// 读取灰度图像 Mat grayImage = Cv2.ImRead("example.jpg", ImreadModes.Grayscale); // 读取原始格式图像 Mat unchangedImage = Cv2.ImRead("example.png", ImreadModes.Unchanged);

图像显示

读取图像后,我们可以使用 Cv2.ImShow 方法在窗口中显示图像。Cv2.WaitKey 用于等待按键事件,使窗口保持打开状态。

C#
Cv2.ImShow("显示图像", src); Cv2.WaitKey(0); // 为 0 表示无限等待,直到按下任意键

检查图像是否读取成功

在读取图像后,检查图像对象是否为空是一个好的实践。可以使用 Mat.Empty 方法来判断:

C#
if (src.Empty()) { Console.WriteLine("无法读取图像!"); return; }

完整示例

以下是一个更完整的示例,演示了读取图像、显示图像、以及做一些简单的处理:

C#
using System; using OpenCvSharp; namespace OpenCvSharpExample { class Program { static void Main(string[] args) { // 读取彩色图像 Mat colorImage = Cv2.ImRead("example.jpg", ImreadModes.Color); if (colorImage.Empty()) { Console.WriteLine("无法读取图像!"); return; } // 转换为灰度图像 Mat grayImage = new Mat(); Cv2.CvtColor(colorImage, grayImage, ColorConversionCodes.BGR2GRAY); // 使用Canny算法进行边缘检测 Mat edgeImage = new Mat(); Cv2.Canny(grayImage, edgeImage, 100, 200); // 显示图像 Cv2.ImShow("彩色图像", colorImage); Cv2.ImShow("灰度图像", grayImage); Cv2.ImShow("边缘检测图像", edgeImage); Cv2.WaitKey(0); // 释放资源 colorImage.Dispose(); grayImage.Dispose(); edgeImage.Dispose(); Cv2.DestroyAllWindows(); } } }

image.png

Cv2.Canny(grayImage, edgeImage, 100, 200);

在这个调用中,参数的意义是:

  1. grayImage:输入图像,通常是一个单通道的灰度图像。Canny 边缘检测是在灰度图像上进行的。
  2. edgeImage:输出图像,检测到的边缘将被标记为白色(255),而其他像素将被标记为黑色(0)。
  3. 100:低阈值(threshold1),用于滞后阈值处理。这是第一个梯度强度阈值,任何边缘的梯度强度低于这个值的像素将被抑制(非边缘)。
  4. 200:高阈值(threshold2),用于滞后阈值处理。这是第二个梯度强度阈值,任何边缘的梯度强度高于这个值的像素将被肯定为边缘。

Canny 边缘检测的工作方式如下:

  • 首先,Canny 算法对图像进行高斯滤波,以平滑图像,减少噪声。
  • 然后,它计算图像梯度,这通常是通过 Sobel 算子来完成的。
  • 接着,它应用非极大值抑制 (Non-maximum Suppression),以精确定位边缘。
  • 最后,它使用双阈值处理来检测和连通边缘。
  • 对每个像素:
    • 如果梯度强度高于 threshold2,该像素被视为是真正的边缘。
    • 如果梯度强度低于 threshold1,该像素会被抑制。
    • 如果梯度强度在 threshold1threshold2 之间,只有当它连接到一个被视为真正边缘的像素时,才被视为边缘。

两个阈值的确定方法

  1. 初始选择
    • 一般建议高阈值取60-150。
    • 低阈值是高阈值的1/2到1/3之间。
  2. 观测调整
    • 观察初次结果,如果太多噪声,逐渐提高阈值。
    • 细节不足,逐渐降低阈值。

在这个示例中,我们做了以下几件事:

  1. 读取图像文件。
  2. 将彩色图像转换为灰度图像。
  3. 对灰度图像进行边缘检测。
  4. 显示彩色图像、灰度图像和边缘检测图像。

总结

通过使用 OpenCvSharp 的 Cv2.ImRead 方法,我们可以轻松读取图像文件,并利用 OpenCvSharp 提供的大量图像处理功能对其进行操作。在本文中,我们详细介绍了如何读取图像、显示图像,并进行了基本的图像处理操作。希望这些内容对你有所帮助,让你能够在 .NET 环境中高效地进行图像处理。

本文作者:rick

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!