OpenCV、EmguCV和OpenCvSharp访问图像耗时测评(附源码)

背景介绍

EmguCV和OpenCvSharp都是OpenCV在.Net下的封装,常常会听到有人说EmguCV或OpenCvSharp同样的函数比OpenCV函数运行速度慢,到底是不是真的?博主暂时也没有去一一验证,本文主要对比下三者用指针方法读取像素的速度、耗时情况。

对比实验说明

提供2张图片做测试,分辨率分别是3000 x 3835 和 600 x 676:

分别使用OpenCV、EmguCV和OpenCvSharp指针方法来读取修改像素值,并计算所用时间。

测试图与结果图:

【1】OpenCV测试

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Read_Modify_Piexl_Value.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
 
#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
 
using namespace std;
using namespace cv;
 
Mat readPixelNormal(Mat img, Mat thres)
{
  for (int i = 0; i < thres.rows; i++)
  {
    for (int j = 0; j < thres.cols; j++)
    {
      if (thres.at<uchar>(i, j) == 255)
          img.at<Vec3b>(i, j) = Vec3b(197, 247, 254); //BGR彩色图像素值改变
    }
  }
  return img;
}
 
Mat readPixelFast(Mat img, Mat thres)
{
  for (int i = 0; i < thres.rows; i++)
  {
    uchar *ptr = thres.ptr<uchar>(i);
    uchar *ptrColor = img.ptr<uchar>(i);
    for (int j = 0; j < thres.cols; j++)
    {
      if (ptr[j] == 255)
      {
        ptrColor[j * 3] = 197;
        ptrColor[j * 3 + 1] = 247;
        ptrColor[j * 3 + 2] = 254;
      }
    }
  }
  return img;
}
 
int main()
{
  Mat img = imread("S.png");
  Mat gray, thres;
  cvtColor(img, gray, COLOR_BGR2GRAY);
  threshold(gray, thres, 0, 255, THRESH_BINARY | THRESH_OTSU);
  double start = static_cast<double>(getTickCount());
  //Mat result = readPixelNormal(img, thres);
  Mat result = readPixelFast(img, thres);
  double end = static_cast<double>(getTickCount());
  double useTime = ((double)end - start) / getTickFrequency() * 1000;
  cout << "use-time = " << useTime << "ms" << endl;
  imwrite("res.png", result);
  return 0;
}

测试结果:

3000 x 3835 图像耗时 12ms左右

600 x 676 图像耗时 0.7ms左右

【2】EmguCV测试

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
 
namespace Read_Modify_Pixel
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat img = CvInvoke.Imread("S.png");
            Mat gray = new Mat();
            Mat thres = new Mat();
            CvInvoke.CvtColor(img, gray, ColorConversion.Bgr2Gray);
            CvInvoke.Threshold(gray, thres, 0, 255, ThresholdType.Binary | ThresholdType.Otsu);
 
            DateTime startTime = DateTime.Now;
 
            unsafe
            {
                for (int i = 0; i < img.Rows; i++)
                {
                    IntPtr ptr = thres.DataPointer;
                    IntPtr ptrColor = img.DataPointer;
                    byte* data = (byte*)ptr.ToPointer();
                    byte* dataColor = (byte*)ptrColor.ToPointer();
                    for (int j = 0; j < img.Cols; j++)
                    {
                        if (data[i * img.Cols + j] == 255)
                        {
                            int index = (img.Step * i) + (j * 3);
                            dataColor[index] = 197;
                            dataColor[index + 1] = 247;
                            dataColor[index + 2] = 254;
                        }
                    }
                }
            }
           
            DateTime stopTime = DateTime.Now;
            TimeSpan useTime = stopTime - startTime;
            Console.WriteLine("useTime: {0}ms", useTime.TotalMilliseconds);
            CvInvoke.Imwrite("res.png", img);
        }
    }
}

测试结果:

3000 x 3835 图像耗时 950ms左右

600 x 676 图像耗时 44ms左右

【3】OpenCvSharp测试

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using OpenCvSharp;
 
 
namespace Read_Pixel_Value
{
    class Program
    {
        //指针方法修改像素值
        static void Main(string[] args)
        {
            Mat img = Cv2.ImRead("S.png");
            Mat gray = new Mat();
            Mat thres = new Mat();
            Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY);
            Cv2.Threshold(gray, thres, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
            DateTime startTime = DateTime.Now;
 
            //指针方法修改像素值
            unsafe
            {
                for (int i = 0; i < thres.Rows; i++)
                {
                    IntPtr ptr = thres.Ptr(i);
                    IntPtr ptrColor = img.Ptr(i);
                    for (int j = 0; j < thres.Cols; j++)
                    {
                        byte* data = (byte*)ptr.ToPointer();
                        byte* dataColor = (byte*)ptrColor.ToPointer();
                        if (data[j] == 255)
                        {
                            dataColor[j * 3] = 197;
                            dataColor[j * 3 + 1] = 247;
                            dataColor[j * 3 + 2] = 254;
                        }
                    }
                }
            }
 
 
            DateTime stopTime = DateTime.Now;
            TimeSpan useTime = stopTime - startTime;
            Console.WriteLine("useTime: {0}ms", useTime.TotalMilliseconds);
 
            Cv2.ImWrite("res.png", img);
            Console.WriteLine("Done!");
        }
    }
}

测试结果:

3000 x 3835 图像耗时 340ms左右

600 x 676 图像耗时 18ms左右

测试结果

由上面测试结果汇总成下表,明显看出C++ OpenCV指针方法访问像素值最快,其次是OpenCvSharp,最慢的则是EmguCV,以上结果仅供参考。

—THE END—

 

 

出处:https://cloud.tencent.com/developer/article/2121762

=======================================================================================

文心一言:opencvsharp还是emgucv

在选择使用OpenCvSharp还是EmguCV时,我们需要综合考虑多个因素,包括基本概念、功能差异、性能表现、社区支持和文档完善度,以及具体的应用场景和需求。以下是对这两个库的分点比较和建议:

1. 基本概念及特点

  • OpenCvSharp‌:OpenCvSharp是OpenCV的C#封装库,提供了利用C#语言进行图像处理和计算机视觉的能力。它继承了OpenCV的强大功能,并提供了简洁而直观的C# API,使得开发者能够快速上手并灵活应用各种图像处理算法。
  • EmguCV‌:EmguCV同样是OpenCV的C#封装库,旨在为C#开发者提供高性能的计算机视觉和图像处理功能。它支持OpenCV几乎所有的功能和算法,并提供了一系列界面控件接口。

2. 功能差异

  • OpenCvSharp‌:更加接近于原始的OpenCV,提供了丰富的图像处理和计算机视觉功能。它支持跨平台,不仅可以在Windows上运行,还支持Linux和Mac OS等多个操作系统。
  • EmguCV‌:除了提供计算机视觉函数接口外,还提供了一系列界面控件接口,方便开发者进行GUI开发。然而,它目前主要支持OpenCV 1的书写风格,可能在某些新特性上有所滞后。

3. 性能表现

  • 根据一些性能对比评测,OpenCvSharp在读取图像像素值等操作时通常表现出较高的性能,尤其是在高分辨率图像处理上。这得益于它优化过的算法和数据结构。
  • EmguCV的性能虽然也不错,但在某些情况下可能略逊于OpenCvSharp,尤其是在需要高效访问和修改图像像素值的场景下。

4. 社区支持和文档完善度

  • OpenCvSharp‌:由于OpenCvSharp是基于OpenCV的封装,因此可以享受到OpenCV庞大的社区支持和丰富的文档资源。此外,OpenCvSharp也有自己的社区和文档,虽然规模可能相对较小,但仍在不断完善中。
  • EmguCV‌:EmguCV同样拥有一定的社区支持和文档资源,但由于其相对独立的发展路径,可能在某些方面与OpenCV的官方文档存在差异。

5. 应用场景和需求

  • 个人使用‌:如果是个人项目或学习使用,EmguCV和OpenCvSharp都是不错的选择。可以根据个人偏好和对某个库的熟悉程度进行选择。
  • 商业应用‌:对于商业产品来说,需要考虑库的协议友好性、成本以及长期维护等因素。OpenCvSharp的基本版本协议较为友好,对商业应用更为有利;而EmguCV则需要支付一定的开发费用。

结论

综上所述,如果你的项目是一个商业产品,且希望使用一个协议友好、性能出色且文档完善的图像处理库,那么OpenCvSharp可能是一个更好的选择。如果你对界面开发有较多需求,或者更倾向于使用EmguCV提供的某些特定功能,那么EmguCV也是一个值得考虑的选项。不过,需要注意的是,随着OpenCV的不断发展和更新,OpenCvSharp可能会更快地跟进这些新特性,从而提供更为全面的功能支持。

以下是一个使用OpenCvSharp进行简单图像处理的代码示例,展示了如何在C#中加载图像、添加文字并显示:

using OpenCvSharp;
using System.Windows;
using System.Windows.Controls;
using Window = System.Windows.Window;

namespace OpencvWork
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // 创建一个新的Mat对象,指定大小、类型和初始颜色
            using Mat mat = new Mat(200, 200, MatType.CV_8UC3, Scalar.Gray);
            // 在图像上添加文字
            mat.PutText("Welcome, go out", new Point(60, 90), HersheyFonts.Italic, 0.3, Scalar.Black);
            // 将Mat对象转换为BitmapSource,以便在WPF中显示
            var img = new Image();
            img.Source = mat.ToBitmapSource();
            // 将图像设置为窗口的内容
            this.Content = img;
        }
    }
}

这段代码展示了OpenCvSharp在WPF应用中的基本用法,包括创建图像、添加文字和显示图像。希望这些信息能帮助你做出更合适的选择。

 

 

出处:https://yr7ywq.smartapps.baidu.com/?_chatQuery=opencvsharp%E8%BF%98%E6%98%AFemgucv&searchid=a3cb5d3802336bb6&_chatParams=%7B%22agent_id%22%3A%22c816%22%2C%22content_build_id%22%3A%22f9e3d3e%22%2C%22from%22%3A%22q2c%22%2C%22token%22%3A%22UGlGZHdpN0lzYXNVbS9Gb1JoeVNNWXRmOGI3Q0R2VFNVZlJSWlMzOW9SSldwTlVFcVdDL2U3b3ZsTzhOL0F0R0hxbkJFakFCaEJrdy9GSFRTdEZCblhoUk5sT0E0ZVZkb2FaUlZaYTBMYmlGalFnYy9FVlNaRkhJbE4rbFQ1NE4%3D%22%2C%22chat_no_login%22%3Atrue%7D&_swebScene=3711000610001000

=======================================================================================

posted on 2025-10-14 10:48  jack_Meng  阅读(80)  评论(0)    收藏  举报

导航