Страницы

Поиск по вопросам

четверг, 5 декабря 2019 г.

Поиск светлых зон на изображении

#изображения #поиск #нейронные_сети


Имеется выборка, в которой 50-200к изображений (раскадровка с видео).
Суть задачи сводится к поиску таких изображений на которых светлая область находится
вертикально или занимает больше 30% площади изображения. Само видео -- съемка грозы
ночью. После раскадровки нужно перенести в отдельную папку все изображения, на которых
есть молнии. Мне в голову приходит только две идеи:


Использовать нейросети (но я не уметь их писать) даже если OpenCV. 
Простой проход в цикле попиксельно по изображению, поиск и подсчет
    кол-ва ярких точек и нужное изображение то, где количество пикселей
    к примеру 30..35% от ширины * высоту.


Подскажите, как правильно это было бы реализовать.
Знаю языки C#/Java/JavaScript/Python. 
    


Ответы

Ответ 1



Итак, если подходить к решению Вашей задачи со стороны нейронных сетей, то, как уже правильно заметил в своем ответе @MaxU, Вам бы понадобилась огромная размеченная выборка с картинками в духе Молния/НеМолния. По сему я считаю, что Вы правильно задумались о попиксельном анализе изображения. Если оценивать изображение по содержанию светлых пикселей - то получите очень неточный результат. Например изображение шахматной доски будет распознано как изображение содержащее молнию... Тут я позволю себе не согласиться с @MaxU, ибо очень сомнительно, что во время съемки материала мимо камеры щеголял шахматист, закрывая камеру своей доской. Думаю, стоит подробнее акцентировать внимание на том, что Ваша задача сводится к тому, чтобы из картинок рода пейзаж / пейзаж с молнией выбрать таки последний, а не к тому, чтобы из набора случайных картинок (в лице тех же шахматных досок) безошибочно выбрать те, где есть молния. Это важное замечание, ибо если мы делаем корм для домашних животных, мы должны учитывать, как на него реагируют и собаки, и кошки. А вот если мы делаем корм исключительно для собак, то ориентироваться на вкус кошек будет как-то глупо (уж простите мне мои аналогии) Каким цветом отображается молния на фотокарточках? Практически идеально белым. Так что яркость пикселей, отражающих молнию, будет стремиться к 1 (или 100%). Это мы и будем использовать. К слову, я уж не знаю, что у Вас там за молнии такие, которые 30% фото занимают, ибо у меня минимальный процент сравнялся с 1.5%) Ладно, от слов к делу. Нам надо выбрать картинки, у которых число пикселей с яркостью >= 0.75 (>= 75%) также >= 0.015 (>= 15%) от всего изображения. Код у меня вышел следующий: using System; using System.IO; using KE.Drawing; using System.Linq; using System.Drawing; namespace LightingDetect { class Program { #region Var private static string InputPath { get; } = $"{Environment.CurrentDirectory}\\Input\\"; // Общая директория, откуда будем брать картинки на анализ private static string OutputLighting { get; } = $"{Environment.CurrentDirectory}\\Output\\Lighting\\"; // Выходная директория для картинок с молниями private static string OutputNoLighting { get; } = $"{Environment.CurrentDirectory}\\Output\\NoLighting\\"; // Выходная директория для картинок без молний #endregion #region Main private static void Main(string[] args) { int lightings = 0; int total = 0; // Убедимся в наличии директорий if (!Directory.Exists(InputPath)) Directory.CreateDirectory(InputPath); if (!Directory.Exists(OutputLighting)) Directory.CreateDirectory(OutputLighting); if (!Directory.Exists(OutputNoLighting)) Directory.CreateDirectory(OutputNoLighting); // Начнем анализ каждой картинки в указанной директории foreach (string imgPath in Directory.GetFiles(InputPath)) { if (HasLighting(imgPath, 0.75f, 1.5)) { File.Move(imgPath, $"{OutputLighting}{imgPath.Split('\\').Last()}"); ++lightings; } else File.Move(imgPath, $"{OutputNoLighting}{imgPath.Split('\\').Last()}"); ++total; } Console.WriteLine("Обработано файлов: {0}\nОбнаружено молний: {1}", total, lightings); Console.ReadKey(); } #endregion #region Functions private static bool HasLighting(string ImagePath, float MinLuminosity, double Percentage) { try { Percentage /= 100; using (Image img = Image.FromFile(ImagePath)) return ((LockedBitmap)img) .Select(x => (HSLColor)x) // Будем читать пиксели в формате HSL, ибо там учитывается яркость пикселя .Count(color => color.Luminosity >= MinLuminosity) / (double)(img.Width * img.Height) >= Percentage; // Сверим условие } catch { return false; } } #endregion } } Увы, я тут для быстрой обработки изображений злоупотребляю своей самописной библиотекой, так что представлю Вам код метода HasLighting с использованием обычного Bitmap (предупреждение: Bitmap.GetPixel() и Bitmap.SetPixel() - чертовски медленные вещи, так что с учетом размеров Вашей выборки советую забыться крепким и сладким сном на время работы программы): private static bool HasLighting(string ImagePath, float MinLuminosity, double Percentage) { try { Percentage /= 100; int count = 0; using (Bitmap img = (Bitmap)Image.FromFile(ImagePath)) { for (int y = 0; y < img.Height; y++) for (int x = 0; x < img.Width; x++) // Запускаем цикл по всем пикселям изображения { Color color = img.GetPixel(x, y); float luminosity = (Math.Max(Math.Max(color.R, color.G), color.B) + Math.Min(Math.Min(color.R, color.G), color.B)) / 510.0f; // Рассчитываем яркость if (luminosity >= MinLuminosity) // Сверяем ++count; } return count / (double)(img.Width * img.Height) >= Percentage; } } catch { return false; } } Поигравшись со значениями MinLuminosity и Percentage, я нашел идеальные значения для моей выборки, так что в итоге на моих скромных входных данных, состоящих из 15 абсолютно разных картинок из Google, было показано стопроцентное попадание. Так как у Вас все картинки из одной серии, думаю, Вам будет легко подобрать идеальные для Вас значения Вообще, такой подход аналогичен переводу изображения в бинарное. Так что если вместо логической обработки мы заменим цвета, что не прошли порог MinLuminosity, на черный, а другие - на белый, то получим нечто такое для изображения с молнией: И что-то такое для изображения без молнии: Как-то так. Надеюсь, мой подход хоть как-то помог в разрешении Вашей задачи. А так - хотелось бы все таки увидеть часть Вашей выборки. Тогда, думаю, я мог бы помочь чуть более конкретно) Удачи Вам! Если что - спрашивайте, будем думать дальше)

Ответ 2



НС вам поможет только если вы сможете ее правильно обучить. Соответственно для обучения нужен солидный (обычно десятки тысяч изображений) набор заведомо размеченных картинок (в вашем случае две папки/категории с изображениями - там где присутствует молния и там где ее нет). Если оценивать изображение по содержанию светлых пикселей - то получите очень неточный результат. Например изображение шахматной доски будет распознано как изображение содержащее молнию... PS Вот похожий вопрос на англоязычной версии сайта, который закрыли как слишком общий...

Комментариев нет:

Отправить комментарий