c# - 在 c# 中使用 Emgu 为图像中的每个像素应用 ArcCos 的最快方法是什么
问题描述
早上好,
我在 Emgu 的图像上使用了很多操作,比如 Pow、Add、Sub、Mul。这些操作在两个操作的图像之间逐个元素地工作。但是,我看到 Emgu 库中不包含 cos、acos、sin 和 asin,我需要最快的方法来进行 acos 操作。
尽管如此,我已经有以下方法可以做到这一点,我不知道它是否是最快的。
// The original image
Image<Bgr, float> image = new Image<Bgr, float>(@"C:\image.jpg");
// Get the image width and height
int imageWidth = image.Width;
int imageHeight = image.Height;
// The ArcCos operated image
Image<Bgr, float> imageAcos = new Image<Bgr, float>(imageWidth, imageHeight);
// Start operating the image
for (int y = 0; y < imageHeight; y++)
{
for(int x = 0; x < imageWidth; x++)
{
// The Blue frame
imageAcos.Data[y, x, 0] = (float) Math.Acos((double) image.Data[y, x, 0]);
// The Green frame
imageAcos.Data[y, x, 1] = (float) Math.Acos((double) image.Data[y, x, 1]);
// The Red frame
imageAcos.Data[y, x, 2] = (float) Math.Acos((double) image.Data[y, x, 2]);
}
}
解决方案
我认为在Image<,>
不使用不安全代码和指针的情况下,这几乎是最快的。一个快速的加速方法是并行运行外部循环,如下所示:
Parallel.For(0, imageHeight, y =>
{
for (int x = 0; x < imageWidth; x++)
{
// The Blue frame
imageAcos.Data[y, x, 0] = Method(image.Data[y, x, 0]);
// The Green frame
imageAcos.Data[y, x, 1] = Method(image.Data[y, x, 1]);
// The Red frame
imageAcos.Data[y, x, 2] = Method(image.Data[y, x, 2]);
}
});
这是否会导致加速取决于图像大小,因此请务必使用您的图像进行测试。它将利用您可能不想要的所有 CPU 内核。
一种更简单/更紧凑的方法是使用内置的 Convert 方法。
Image<Bgr, float> imageAcos = image.Convert(p => (float)Math.Acos((double)p));
这不能像 for 循环那样并行化,但应该与您当前的实现一样快。
顺便说一句,我很确定您在 Data[] 中的 x 和 y 顺序错误。
推荐阅读
- javascript - 运行规范时包未激活
- java - Java中的PowerShell ConvertFrom-SecureString?
- google-chrome - 从属性中获取特定字符串
- actions-on-google - 为 Google Assistant 使用关键字 ASK
- java - 计算字符串上的匹配字符
- javascript - axios.post().then() 没有将解析的数据传递给回调函数
- java - 如何在 swagger yaml 中为 Swagger dode 生成提供通用返回类型?
- javascript - 使用精灵表动画时的Javascript画布幻灯片
- arrays - 如何在显示值之前使用 vlookup 公式查看两个值
- mysql - 我想找到一个在 5 分钟内尝试 3 次登录的用户。在 mysql 5.7 中