Как состояние сайта emgu, в основном есть две стратегии:
Безопасный (медленный) способ
Предположим, вы работаете над Image<Bgr, Byte>
.Вы можете получить пиксель в y-й строке и x-м столбце, вызвав
Bgr color = img[y, x];
Установка пикселя в y-й строке и x-м столбце также проста
img[y,x] = color;
Быстрый способ
Значения пикселей изображения хранятся в свойстве Data, трехмерном массиве.Итак, это правда, но не говорит, как это сделать в реальном сценарии.Итак, давайте посмотрим некоторый рабочий код, а затем обсудим производительность и оптимизацию:
Image<Bgr, Byte> original = newImage<Bgr, byte>(1024, 768);
Stopwatch evaluator = newStopwatch();
int repetitions = 20;
Bgr color = newBgr(100, 40, 243);
evaluator.Start();
for (int run = 0; run < repetitions; run++)
{
for (int j = 0; j < original.Cols; j++)
{
for (int i = 0; i < original.Rows; i++)
{
original[i, j] = color;
}
}
}
evaluator.Stop();
Console.WriteLine("Average execution time for {0} iteration \n using column per row access: {1}ms\n", repetitions, evaluator.ElapsedMilliseconds / repetitions);
Итак, это среднее время работы, которое у вас есть после 20 запусков с использованием безопасного медленного способа установки пикселя изображения. На моей машине это занимает 1021ms ...
Таким образом, 1021 миллисекунды как среднее время цикла и установки количества пикселей, равного 1024 * 768.Мы могли бы сделать немного лучше, зацикливаясь на строку за строкой
Итак, давайте немного изменим код нашего кода и воспользуемся более быстрым способом, используя непосредственно свойство Image.Data:
evaluator.Reset();
evaluator.Start();
for (int run = 0; run < repetitions; run++)
{
for (int i = 0; i < original.Rows; i++)
{
for (int j = 0; j < original.Cols; j++)
{
original.Data[i, j, 0] = 100;
original.Data[i, j, 1] = 40;
original.Data[i, j, 2] = 243;
}
}
}
evaluator.Stop();
Console.WriteLine("Average execution time for {0} iterations \n using Data property: {1}ms\n", repetitions, evaluator.ElapsedMilliseconds / repetitions);
На моей машине это занимает 519мс .Таким образом, мы получили прирост производительности на 50%.Время выполнения было уменьшено в два раза.
Поэтому, внимательно следя за кодом, помня о том, что мы используем C #, мы можем внести незначительное изменение, которое снова резко повысит производительность установки пикселей изображения... мы не должны использовать свойство c # внутри цикла !!!
evaluator.Reset();
evaluator.Start();
byte[,,] data = original.Data;
for (int run = repetitions - 1; run >= 0; run--)
{
for (int i = original.Rows - 1; i >= 0; i--)
{
for (int j = original.Cols - 1; j >= 0; j--)
{
data[i, j, 0] = 100;
data[i, j, 1] = 40;
data[i, j, 2] = 243;
}
}
}
evaluator.Stop();
С этим последним фрагментом кода вы получите огромное повышение производительности (73ms) из-за правильного использования языка C #.