前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV、EmguCV和OpenCvSharp指针访问图像像素值耗时测评(附源码)

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

作者头像
Color Space
发布2022-09-26 10:15:30
1.9K0
发布2022-09-26 10:15:30
举报

背景介绍

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

对比实验说明

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

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

测试图与结果图:

【1】OpenCV测试

代码如下:

代码语言:javascript
复制
// 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
复制
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
复制
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—

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV与AI深度学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 测试结果
    • —THE END—
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档