Основная задача: мне необходимо в реальном времени (или около того) сложение двух Grayscale FullHD 8bit изображений (которые будут использованы как R и G каналы) с камеры (60fps, производитель Imaging Source) в одно FullHD 24bit изображение (R,G,coef*G). Необходимо все полученные изображения отображать на экране (в виде realtime трансляции). Язык разработки - c#. Ограничение на coef: 0 < coef < 1.
Заступорился на создании самой функции быстрого сложения. Необходима "очень быстрая" отработка. Подразумеваю "<=0.01с на получение результирующего изображения".
Попытка формулировки вопроса: Какой специфический алгоритм обработки нужно использовать, чтобы решить подобную задачу, а именно проблему скорости? Через указатели я добился отработки примерно в 0.05с, что все еще долго.Буду рад полезным ссылкам (примеры, обучалки и прочее). Функция, которой произвожу обработку:
private unsafe Bitmap Create_RGB_BMP_FastUnsafe(Bitmap pBMP1, Bitmap pBMP2, bool GreenFirst)
{
int width = 1920;
int height = 1080;
int WH = width * height;
var pRes = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
BitmapData bd_red, bd_green, bd_res;
if (GreenFirst)
{
bd_green = pBMP1.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
bd_red = pBMP2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
bd_res = pRes.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);//greenfirst=true;
}
else
{
bd_red = pBMP1.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
bd_green = pBMP2.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
bd_res = pRes.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);//greenfirst=false;
}
try
{
int stride1 = bd_red.Stride;
int sk;
byte* curpos_red = (byte*)bd_red.Scan0;
byte* curpos_green = (byte*)bd_green.Scan0;
byte* _currentPX = (byte*)bd_res.Scan0;
for (sk = 0; sk < WH; sk++)
{
*_currentPX = (byte)(*(curpos_green) * 0.1); ++_currentPX;
*_currentPX = *(curpos_green++); ++_currentPX;
*_currentPX = *(curpos_red++); ++_currentPX;
}
}
finally
{
pBMP1.UnlockBits(bd_red);
pBMP2.UnlockBits(bd_green);
pRes.UnlockBits(bd_res);
}
return pRes;
}
P.S.: Кое-что из того, что я уже прочитал, перед тем, как спросить у вас, профессионалы)...
Что замедляет работу кода (что-то может быть не очень актуально, т.к. я не знаю точно, какой код генерирует шарп):
Необязательное здесь использование вещественной арифметики. Можно масштабировать коэффициент и после целочисленного умножения на него делить на 256 (возможно, нужно приводить к int для корректного умножения и потом к байту)
cf256 = (int) 256 * coeff
*_currentPX = (*(curpos_green) * сf256 >> 8); ++_currentPX;
Прыжки по памяти в три разных места - от этого полностью не избавиться, но в развертывание циклов может в какой-то мере помочь (возможно, кодогенератор сам умеет это делать, как некоторые плюсовые компиляторы в режиме суровой оптимизации)
Задача числомолотильная отлично подходит для MMX/SSE2/AVX2 блоков процессора. При этом несколько пикселов (сколько выходных пикселов влезет в 8/16/32 байта регистра SIMD) обрабатываются одновременно - при лобовом использовании можно ожидать ускорения раза в 4 (для SSE2). Можно ли это использовать в шарпе? Генерируется ли код для SIMD обработки?
(При использовании SIMD отказываться от float арифметики не обязательно)
Собственно, перечисленное реализовано опытными людьми в OpenCV, поэтому при возможности стоит эту библиотеку использовать.
Есть еще вариант, если это будет единственная вычислительно тяжелая задача - написать функцию на C/C++ с использованием SIMD инструкций (интринсики или вообще компилятор обеспечит автоматическую векторизацию) и вызывать её из C# (вероятно, нужно будет делать DLL).
И напоследок - если обработка 60 кадров в секунду нужна только для отображения - не разумно ли ограничиться обработкой и выводом 30 кадров?
Сборка персонального компьютера от Artline: умный выбор для современных пользователей