gpt4 book ai didi

c# - Unity3D 的 OpenCV dll 调用导致 FPS 下降

转载 作者:行者123 更新时间:2023-12-01 23:10:16 26 4
gpt4 key购买 nike

我想在 Unity3D 中识别 ArUco 标记并将游戏对象附加到其位置。我知道资源商店中有一些软件包,但当其他人让它工作时,我正在寻找一个免费的现有解决方案或自己尝试一下。

ArucoUnity检测工作非常顺利,但 Unity 在访问 rvecs、tvecs 的数据时崩溃。当 C++ 方法 au_cv_Vec3d_get(CppPtr, i, CppPtr); 时,Vec3d 类中的 Get(int i) 中某处发生错误被称为

OpenCv plus Unity此实现似乎并不完整,因为不存在 EstimatePoseSingleMarker 或类似的函数来获取 rvecstvecs。最后一次更新是 2019 年 1 月。

由于 Unity (C#) 提供了访问非托管代码的可能性,我遵循 this很棒的教程,并且出于恳求,我能够将 cv::VideoCaputre 流转发到 Unity。发生的唯一问题是 FPS 下降到 35-40 左右,而通常情况下我的帧数约为 90-100。

C# 代码:

void Update()
{
MatToTexture2D();
image.texture = tex;
}

void MatToTexture2D()
{
OpenCVInterop.GetRawImageBytes(pixelPtr);
//Update the Texture2D with array updated in C++
tex.SetPixels32(pixel32);
tex.Apply();
}

C++ 代码:

extern "C" void __declspec(dllexport) __stdcall  GetRawImageBytes(unsigned char* data)
{
_capture >> _currentFrame;

cv::Mat resizedMat(camHeight, camWidth, _currentFrame.type());
cv::resize(_currentFrame, resizedMat, resizedMat.size(), cv::INTER_CUBIC);

//Convert from RGB to ARGB
cv::Mat argb_img;
cv::cvtColor(resizedMat, argb_img, cv::COLOR_BGR2BGRA);
std::vector<cv::Mat> bgra;
cv::split(argb_img, bgra);
std::swap(bgra[0], bgra[3]);
std::swap(bgra[1], bgra[2]);
std::memcpy(data, argb_img.data, argb_img.total() * argb_img.elemSize());
}

原因似乎是第一行_capture >> _currentFrame;,但由于其他项目必须执行相同的操作(至少我猜是这样),我想知道是否还有其他原因。如果我无法解决这个问题,我就必须寻找替代方法。

最佳答案

仅添加/构建 Mars' answer :

对于线程问题,我实际上会使用线程保存 ConcurrentStack<Color32[]> 。堆栈是“后进|先出”,因此返回的第一项始终是线程添加的最后一个图像数据。

  • 该线程使用 Push(pixel32)添加带有图像数据的新条目
  • Update您仅使用最新条目( TryPop )来更新纹理。
  • 其余的您可以忽略( Clear )。

所以类似

// the OpenCV thread will add(push) entries
// the Unity main thread will work on the entries
private ConcurrentStack<Color32[]> stack = new ConcurrentStack<Color32[]>();

public RawImage image;
public Texture2D tex;

private Thread thread;

void Start()
{
// Wherever you get your tex from
tex = new Texture2D(...);

// it should be enough to do this only once
// the texture stays the same, you only update its content
image.texture = tex;
}

// do things in OnEnable so everytime the object gets enabled start the thread
void OnEnable()
{
stack.Clear();

if(thread != null)
{
thread.Abort();
}

thread = new Thread(MatToTexture2D);
thread.Start();
}

void Update()
{
// here in the main thread work the stack
if (stack.TryPop(out var pixels32))
{
// Only use SetPixels and Apply when really needed
tex.SetPixels32(pixels32);
tex.Apply();
}

// Erase older data
stack.Clear();
}

// Make sure to terminate the thread everytime this object gets disabled
private void OnDisable()
{
if(thread == null) return;

thread.Abort();
thread = null;
}

// Runs in a thread!
void MatToTexture2D()
{
while(true)
{
try
{
// Do what you already have
OpenCVInterop.GetRawImageBytes(pixelPtr);

// However you convert the pixelPtr into Color32
Color32[] pixel32 = GetColorArrayFromPtr(pixelPtr);

// Now add this data to the stack
stack.Push(pixel32);
}
catch (ThreadAbortException ex)
{
// This exception is thrown when calling Abort on the thread
// -> ignore the exception since it is produced on purpose
}
}
}

关于c# - Unity3D 的 OpenCV dll 调用导致 FPS 下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58925316/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com