首页 > 解决方案 > 在 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]);
    }
}

标签: c#image-processingemgucvoperationtrigonometry

解决方案


我认为在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 顺序错误。


推荐阅读