OpenCV、EmguCV和OpenCvSharp访问图像耗时测评(附源码)
背景介绍
EmguCV和OpenCvSharp都是OpenCV在.Net下的封装,常常会听到有人说EmguCV或OpenCvSharp同样的函数比OpenCV函数运行速度慢,到底是不是真的?博主暂时也没有去一一验证,本文主要对比下三者用指针方法读取像素的速度、耗时情况。
对比实验说明
提供2张图片做测试,分辨率分别是3000 x 3835 和 600 x 676:

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

【1】OpenCV测试
代码如下:
// 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测试
代码如下:
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测试
代码如下:
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
=======================================================================================
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。(●'◡'●)
因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/19140202
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
浙公网安备 33010602011771号