Как быстро перебрать все пиксели большого количества изображений? Есть 150-200 изображений с расширением 10 000х10 000 пикселей. Из них надо построить что-то наподобие фотоплана. Я решил сложить этот фотоплан из пикселей, поэтому надо из всех изображений достать все пиксели не черного цвета. Пробовал много поточно реализовывать через класс Parallel, большого ускорения в времени обработки нету, что можно сделать?Вызов:var progress = new Progress(s => richTextBox1.AppendText(s + Environment.NewLine)); string way = string.Format(@fbD.SelectedPath); string searchPattern = string.Format(@"*.tif"); string[] Names = System.IO.Directory.GetFiles(way, searchPattern); //int count = 0; DateTime start = DateTime.Now; textBox2.Text += "FilesCount = " + Names.Length + Environment.NewLine; await Task.Factory.StartNew( () => Worker.Read(progress,Names), TaskCreationOptions.None); DateTime end = DateTime.Now; MessageBox.Show(string.Format(" Time work[ {0}:{1} ]", (end - start).Minutes, (end - start).Seconds));Реализация:{ //Parallel.For(0, Names.Length, i =>
for(int i =0;i { byte[, ,] Im = Form1.BitmapToByteRgb(new Bitmap(Names[j])); progress.Report(j.ToString()); }); } else { Parallel.ForEach(Enumerable.Range(i, Names.Length), j =>
{ byte[, ,] Im = Form1.BitmapToByteRgb(new Bitmap(Names[j])); progress.Report(j.ToString()); }); } } } static unsafe public byte[, ,] BitmapToByteRgb(Bitmap bmp) { int width = bmp.Width, height = bmp.Height; byte[, ,] res = new byte[3, height, width]; BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { byte* curpos; for (int h = 0; h < height; h++) { curpos = ((byte*)bd.Scan0) + h * bd.Stride; for (int w = 0; w < width; w++) { res[2, h, w] = *(curpos++); res[1, h, w] = *(curpos++); res[0, h, w] = *(curpos++); } } } finally { bmp.UnlockBits(bd); } return res; }
Для ускорения обработки большого количества изображений и извлечения всех пикселей не черного цвета можно использовать параллельное выполнение задач. Однако ваш код имеет неэффективную структуру из-за использования вложенных циклов for и Parallel.ForEach.
Вместо этого, рекомендуется следующий подход:
Используйте библиотеку System.Threading.Tasks.Parallel для параллельного выполнения обработки изображений.Используйте буфер для накопления пикселей не черного цвета.Обработайте изображения по блокам, вместо работы с каждым изображением отдельно.
Пример кода:
static void ReadImages(string[] imagePaths) { List<byte[, ,]> pixelsList = new List<byte[, ,]>(); Parallel.For(0, imagePaths.Length, i => { using (var bmp = new Bitmap(imagePaths[i])) { byte[, ,] pixels = BitmapToByteRgb(bmp, i, imagePaths[i]); lock (pixelsList) { pixelsList.Add(pixels); } } }); // Далее обработайте список пикселей pixelsList }
Измененный метод BitmapToByteRgb:
static unsafe public byte[, ,] BitmapToByteRgb(Bitmap bmp, int imageIndex, string imagePath) { int width = bmp.Width, height = bmp.Height; byte[, ,] res = new byte[3, height, width]; BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { byte* curpos; for (int h = 0; h < height; h++) { curpos = ((byte*)bd.Scan0) + h * bd.Stride; for (int w = 0; w < width; w++) { byte blue = *(curpos++); byte green = *(curpos++); byte red = *(curpos++); if (red != 0 || green != 0 || blue != 0) // Проверка на черный цвет { res[2, h, w] = blue; res[1, h, w] = green; res[0, h, w] = red; } } } } finally { bmp.UnlockBits(bd); } return res; }
Этот код позволит вам эффективно обрабатывать большое количество изображений и собирать все пиксели не черного цвета. Важно помнить, что обработка такого объема данных может потребовать значительного времени.
Для ускорения обработки большого количества изображений и извлечения всех пикселей не черного цвета можно использовать параллельное выполнение задач. Однако ваш код имеет неэффективную структуру из-за использования вложенных циклов for и Parallel.ForEach.
Вместо этого, рекомендуется следующий подход:
Используйте библиотеку System.Threading.Tasks.Parallel для параллельного выполнения обработки изображений.Используйте буфер для накопления пикселей не черного цвета.Обработайте изображения по блокам, вместо работы с каждым изображением отдельно.Пример кода:
static void ReadImages(string[] imagePaths){
List<byte[, ,]> pixelsList = new List<byte[, ,]>();
Parallel.For(0, imagePaths.Length, i =>
{
using (var bmp = new Bitmap(imagePaths[i]))
{
byte[, ,] pixels = BitmapToByteRgb(bmp, i, imagePaths[i]);
lock (pixelsList)
{
pixelsList.Add(pixels);
}
}
});
// Далее обработайте список пикселей pixelsList
}
Измененный метод BitmapToByteRgb:
static unsafe public byte[, ,] BitmapToByteRgb(Bitmap bmp, int imageIndex, string imagePath){
int width = bmp.Width,
height = bmp.Height;
byte[, ,] res = new byte[3, height, width];
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
try
{
byte* curpos;
for (int h = 0; h < height; h++)
{
curpos = ((byte*)bd.Scan0) + h * bd.Stride;
for (int w = 0; w < width; w++)
{
byte blue = *(curpos++);
byte green = *(curpos++);
byte red = *(curpos++);
if (red != 0 || green != 0 || blue != 0) // Проверка на черный цвет
{
res[2, h, w] = blue;
res[1, h, w] = green;
res[0, h, w] = red;
}
}
}
}
finally
{
bmp.UnlockBits(bd);
}
return res;
}
Этот код позволит вам эффективно обрабатывать большое количество изображений и собирать все пиксели не черного цвета. Важно помнить, что обработка такого объема данных может потребовать значительного времени.