Какой самый быстрый способ применить ArcCos для каждого пикселя в изображении, используя Emgu в C # - PullRequest
0 голосов
/ 30 апреля 2019

Доброе утро,

Я использую множество операций с изображениями с Emgu, такие как Pow, Add, Sub, Mul. Эти операции работают элемент за элементом между двумя управляемыми изображениями. Однако я вижу, что cos, acos, sin и asin не включены в библиотеку Emgu, и мне нужен самый быстрый способ выполнения операции 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]);
    }
}

1 Ответ

0 голосов
/ 02 мая 2019

С 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]);
            }
        });

Зависит ли это от ускорения, зависит от размера изображения, поэтому обязательно проверьте это с изображениями.,И он будет использовать все ваши ядра ЦП, которые вам могут не понадобиться.

Более простой / компактный способ сделать это - использовать встроенный метод Convert.

Image<Bgr, float> imageAcos = image.Convert(p => (float)Math.Acos((double)p));

Это не можетраспараллеливается как for-loop, но должен быть примерно таким же быстрым, как ваша текущая реализация.

Кстати, я вполне уверен, что ваши x и y в неправильном порядке в Data [].

...