探索OpenCvSharp:用C#和Winform构建图像处理世界

OpencvSharp资料,采用C#加Winform编写,包含接近50个Demo,直接运行即可。 例程包含:模板匹配、边缘识别、人脸识别,灰度变化、标定等。

最近在图像处理领域折腾,发现了一个超棒的资源------基于OpenCvSharp,用C# 加Winform编写且包含近50个可直接运行Demo的项目,简直是图像处理爱好者和开发者的福音。今天就来跟大家唠唠这里面的精彩内容。

丰富多样的例程

模板匹配

模板匹配在图像识别里是个常用技术,比如在一张大图里找某个小图标在哪。在这个项目里,实现模板匹配的代码大概长这样:

csharp 复制代码
using OpenCvSharp;

class TemplateMatching
{
    public static void MatchTemplateExample()
    {
        Mat sourceImage = Cv2.ImRead("source.jpg");
        Mat templateImage = Cv2.ImRead("template.jpg");

        Mat result = new Mat();
        Cv2.MatchTemplate(sourceImage, templateImage, result, TemplateMatchModes.CCoeffNormed);

        Core.MinMaxLoc(result, out _, out double maxVal, out _, out Point maxLoc);

        double threshold = 0.8;
        if (maxVal >= threshold)
        {
            int width = templateImage.Width;
            int height = templateImage.Height;
            Rect rect = new Rect(maxLoc, new Size(width, height));
            Cv2.Rectangle(sourceImage, rect, Scalar.Red, 2);
        }

        Cv2.ImShow("Matched Image", sourceImage);
        Cv2.WaitKey(0);
        Cv2.DestroyAllWindows();
    }
}

代码分析:首先,通过Cv2.ImRead读取源图像和模板图像。然后用Cv2.MatchTemplate函数进行模板匹配,这里用的匹配模式是TemplateMatchModes.CCoeffNormed ,它会返回一个匹配结果的矩阵。接着用Core.MinMaxLoc找到矩阵里的最大值,也就是最佳匹配位置。设置一个阈值,如果最大值大于阈值,就认为匹配成功,在源图像上画出匹配区域的矩形框,最后显示图像。

边缘识别

边缘识别能提取图像中物体的轮廓,对于图像分析很关键。下面是简单的边缘识别代码:

csharp 复制代码
using OpenCvSharp;

class EdgeDetection
{
    public static void CannyEdgeDetection()
    {
        Mat image = Cv2.ImRead("input.jpg", ImreadModes.Grayscale);

        Mat edges = new Mat();
        Cv2.Canny(image, edges, 50, 150);

        Cv2.ImShow("Edges", edges);
        Cv2.WaitKey(0);
        Cv2.DestroyAllWindows();
    }
}

代码分析:先把图像以灰度模式读进来,因为Canny边缘检测算法在灰度图上效果更好。Cv2.Canny函数接收图像、输出边缘图像、以及两个阈值,较低阈值用于边缘连接,较高阈值用于检测明显的边缘。最后显示检测到的边缘图像。

人脸识别

人脸识别一直是个热门话题。在这个项目里,利用OpenCvSharp也能轻松实现简单的人脸识别:

csharp 复制代码
using OpenCvSharp;
using OpenCvSharp.Dnn;

class FaceRecognition
{
    public static void FaceRecognitionExample()
    {
        string modelFile = "res10_300x300_ssd_iter_140000_fp16.caffemodel";
        string configFile = "deploy.prototxt";
        Net net = DnnDnn.Net.ReadNetFromCaffe(configFile, modelFile);

        Mat image = Cv2.ImRead("group_photo.jpg");
        Mat blob = DnnBlob.FromImage(image, 1.0, new Size(300, 300), new Scalar(104.0, 177.0, 123.0), false, false);

        net.SetInput(blob);
        Mat detections = net.Forward();

        for (int i = 0; i < detections.Rows; i++)
        {
            float confidence = detections.At<float>(i, 2);
            if (confidence > 0.5)
            {
                int x1 = (int)(detections.At<float>(i, 3) * image.Width);
                int y1 = (int)(detections.At<float>(i, 4) * image.Height);
                int x2 = (int)(detections.At<float>(i, 5) * image.Width);
                int y2 = (int)(detections.At<float>(i, 6) * image.Height);

                Rect rect = new Rect(x1, y1, x2 - x1, y2 - y1);
                Cv2.Rectangle(image, rect, Scalar.Green, 2);
            }
        }

        Cv2.ImShow("Face Detection", image);
        Cv2.WaitKey(0);
        Cv2.DestroyAllWindows();
    }
}

代码分析:这里用到了深度学习模型,先读取模型文件和配置文件创建网络。把图像转成Blob数据格式输入网络,网络会输出检测结果。遍历检测结果,根据置信度判断是否为有效人脸,如果是就画出人脸的矩形框。

灰度变化

灰度变化能简化图像信息,便于后续处理。

csharp 复制代码
using OpenCvSharp;

class GrayscaleConversion
{
    public static void ConvertToGrayscale()
    {
        Mat colorImage = Cv2.ImRead("color_image.jpg");
        Mat grayImage = new Mat();

        Cv2.CvtColor(colorImage, grayImage, ColorConversionCodes.BGR2GRAY);

        Cv2.ImShow("Color Image", colorImage);
        Cv2.ImShow("Grayscale Image", grayImage);
        Cv2.WaitKey(0);
        Cv2.DestroyAllWindows();
    }
}

代码分析:读取彩色图像后,用Cv2.CvtColor函数把彩色图像转成灰度图像,这里指定了从BGR颜色空间转成灰度的代码ColorConversionCodes.BGR2GRAY,最后分别显示彩色图像和灰度图像。

标定

标定在机器视觉里用于确定相机的参数,以便更准确地测量和识别。虽然代码相对复杂些,但这个项目里也有详细实现。

csharp 复制代码
// 这里只给出简单框架,实际标定代码更复杂
using OpenCvSharp;
using OpenCvSharp.Calib3d;

class CameraCalibration
{
    public static void CalibrateCamera()
    {
        // 准备棋盘格角点数据
        Size patternSize = new Size(9, 6);
        Point3f[] objectPoints = new Point3f[patternSize.Width * patternSize.Height];
        for (int i = 0; i < patternSize.Height; i++)
        {
            for (int j = 0; j < patternSize.Width; j++)
            {
                objectPoints[i * patternSize.Width + j] = new Point3f(j, i, 0);
            }
        }

        // 存储所有图像的角点
        List<Point3f[]> objectPointsList = new List<Point3f[]>();
        List<Point2f[]> imagePointsList = new List<Point2f[]>();

        // 读取图像并寻找角点
        for (int i = 0; i < numImages; i++)
        {
            Mat image = Cv2.ImRead($"image_{i}.jpg");
            Mat gray = new Mat();
            Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);

            bool found = Cv2.FindChessboardCorners(gray, patternSize, out Point2f[] corners, ChessboardFlags.AdaptiveThresh | ChessboardFlags.NormalizeImage);
            if (found)
            {
                Cv2.CornerSubPix(gray, corners, new Size(11, 11), new Size(-1, -1), new TermCriteria(TermCriteriaTypes.Eps + TermCriteriaTypes.MaxIter, 30, 0.1));
                objectPointsList.Add(objectPoints);
                imagePointsList.Add(corners);
            }
        }

        // 标定相机
        Mat cameraMatrix = Mat.Zeros(3, 3, MatType.CV_64F);
        Mat distCoeffs = Mat.Zeros(5, 1, MatType.CV_64F);
        Calib3d.CalibrateCamera(objectPointsList, imagePointsList, gray.Size(), cameraMatrix, distCoeffs, out _, out _, CalibrationFlags.None);
    }
}

代码分析:首先定义棋盘格的尺寸,生成棋盘格角点的三维坐标。循环读取图像,把彩色图像转成灰度图后找棋盘格角点,如果找到就优化角点位置并存储。最后用这些角点数据进行相机标定,得到相机矩阵和畸变系数。

这个基于OpenCvSharp,C# 加Winform的项目,通过这一个个精彩的Demo,为我们打开了图像处理的大门,无论是新手学习还是老手拓展思路,都非常有价值,强烈推荐大家下载来亲自运行体验一番!

相关推荐
greatofdream7 天前
LLVM安装使用
笔记·mlir
Shining059620 天前
前沿模型系列(五)《多模态智能及其应用》
人工智能·架构·大模型·mlir·infinitensor·hivm·前沿模型
喜欢打篮球的普通人23 天前
MLIR快速入门
neo4j·mlir
Shining059623 天前
AI 编译器系列(七)《(MLIR)AscendNPU IR 编译堆栈》
人工智能·架构·mlir·infinitensor·hivm·ascendnpu ir
读书读傻了哟3 个月前
MLIR编译安装
mlir·llvm
氵文大师4 个月前
MLIR 中最常用的方言
mlir
联系QQ:688238864 个月前
风电并网玩转指南:15节点混合发电系统实战
mlir
清钟沁桐5 个月前
mlir 编译器学习笔记之六 -- 经典实现
笔记·学习·mlir
清钟沁桐5 个月前
mlir 编译器学习笔记之四 -- 调度
笔记·学习·mlir