Webカメラから画像を取り込んで Cv2.Mat に変換するときに、最も早い方法を探したい。というわけでいくつか方法を考えてみた。

[1] OpenCvSharp.CvCapture クラスで Iplimageを取得してCv2.CvArrToMat メソッドで Mat に変換する
[2] OpenCvSharp.CPlusPlus.FrameSource クラスで直接 Mat を吐き出させる

試しにテスト用のコードを書いてみた。
このコードでは
[1] が Cv1Capture()
[2] が Cv2Capture()
にあたる。

再利用性がとても低かったり、そもそもこれで比較になるのかという疑問点はあるけれど、とりあえずこんな感じで。

using System;
using System.Text;
using System.Diagnostics;
using System.IO;
using OpenCvSharp;
using OpenCvSharp.CPlusPlus;
namespace CaptureTest
{
class Program
{
static void Main(string[] args)
{
// Webカメラから画像を取り込んでMatに変換する時に、どの方法が早いかをテスト
Cv1Capture(10);
Cv2Capture(10);
}
public static void Cv1Capture(int count, string fileName = "Cv1Capture.txt")
{
using (var writer = new StreamWriter(fileName, true, Encoding.GetEncoding("utf-8")))
{
for (int i = 0; i < count; i++)
{
var sw = new Stopwatch();
sw.Start();
var capture = Cv.CreateCameraCapture(0);
for (int k = 0; k < 100; k++)
{
var frame = capture.QueryFrame();
Cv2.ImShow("Capture", Cv2.CvArrToMat(frame));
Cv.WaitKey(5);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
writer.WriteLine(sw.ElapsedMilliseconds.ToString());
}
}
}
public static void Cv2Capture(int count, string fileName = "Cv2Capture.txt")
{
using (var writer = new StreamWriter(fileName, true, Encoding.GetEncoding("utf-8")))
{
var frame = new Mat();
for (int i = 0; i < count; i++)
{
var sw = new Stopwatch();
sw.Start();
var capture = Cv2.CreateFrameSource_Camera(0);
for (int k = 0; k < 100; k++)
{
capture.NextFrame(frame);
Cv2.ImShow("Capture", frame);
Cv.WaitKey(5);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
writer.WriteLine(sw.ElapsedMilliseconds.ToString());
}
}
}
}
}
view raw CaptureTest.cs hosted with ❤ by GitHub

結果

[1]
8296
8544
8078
8063
8063
8089
8061
8063
8077

[2]
8063
8076
8063
8063
8079
8073
8063
8077
8061

結論

[1]も[2]も結果はほとんど変わらない。ということで、これからはその時その時で使い勝手がよさそうな方を適当に使っていくことにします。