Я работаю на сайте недвижимости, и я хотел бы написать программу, которая может определить (классифицировать), если изображение представляет собой план этажа или логотип компании.
Поскольку я пишу в php, я предпочел бы решение php, но любое решение c ++ или opencv будет прекрасно.
Пример плана этажа:
alt text http://img.ruphp.com/php/68614.jpg
alt text http://img.ruphp.com/php/44199.jpg
Пример логотипа:
alt text http://img.ruphp.com/php/95205.jpg
Как всегда, для этого есть встроенная функция PHP . Просто шутка. знак равно
Все планы этажей, которые я видел, они довольно монохроматичны, я думаю, вы можете играть с количеством цветов и насыщенности цвета, чтобы иметь довольно хорошее предположение, что изображение – это логотип или план этажа.
Например: is the image has less than 2 or 3 colors is a floor plan.
Например: if the sum / average of the saturation is less than X it's a floor plan.
Черно-белые (и другие аналогичные цвета, которые используются в планах этажей) имеют насыщенность, равную нулю или очень близкую к нулю, в то время как логотипы имеют тенденцию быть более визуально привлекательными, поэтому используют более насыщенные цвета.
Вот простая функция для вычисления насыщенности цвета Hex RGB:
function Saturation($color) { $color = array_map('hexdec', str_split($color, 2)); if (max($color) > 0) { return (max($color) - min($color)) / max($color); } return 0; } var_dump(Saturation('000000')); // black 0.0000000000000000 var_dump(Saturation('FFFFFF')); // white 0.0000000000000000 var_dump(Saturation('818185')); // grey 0.0300751879699249 var_dump(Saturation('5B9058')); // green 0.3888888888888889 var_dump(Saturation('DE1C5F')); // pink 0.8738738738738738 var_dump(Saturation('FE7A15')); // orange 0.9173228346456692 var_dump(Saturation('FF0000')); // red 1.0000000000000000 var_dump(Saturation('80FF80')); // --- 0.4980392156862745 var_dump(Saturation('000080')); // --- 1.0000000000000000
Используя imagecolorat () и imagecolorsforindex (), вы можете реализовать простую функцию, которая проходит через все пиксели изображения и суммирует / вычисляет среднее значение насыщенности. Если изображение имеет уровень насыщенности выше настраиваемого порога, который вы определяете, вы можете предположить, что изображение является логотипом.
Нельзя забывать, что изображения с более высоким разрешением обычно имеют большую насыщенность (большее количество пикселей), поэтому для этого алгоритма, а также ради производительности вашего сервера было бы разумно изменить размер всех изображения для общего разрешения (скажем, 100×100 или 50×50), чтобы классифицировать их, и после их классификации вы можете использовать оригинальные (без изменения размера) изображения.
Я сделал простой тест с изображениями, которые вы предоставили, вот код, который я использовал:
$images = array('./44199.jpg', './68614.jpg', './95205.jpg', './logo.png', './logo.gif'); foreach ($images as $image) { $sat = 0; $image = ImageCreateFromString(file_get_contents($image)); for ($x = 0; $x < ImageSX($image); $x++) { for ($y = 0; $y < ImageSY($image); $y++) { $color = ImageColorsForIndex($image, ImageColorAt($image, $x, $y)); if (is_array($color) === true) { $sat += Saturation(dechex($color['red']) . dechex($color['green']) . dechex($color['blue'])); } } } echo ($sat / (ImageSX($image) * ImageSY($image))); echo '<hr />'; }
И вот результаты:
green floor plant: 0.0151028053 black floor plant: 0.0000278867 black and white logo: 0.1245559912 stackoverflow logo: 0.0399864136 google logo: 0.1259357324
Используя только эти примеры, я бы сказал, что изображение представляет собой завод по производству пола, если средняя насыщенность меньше 0,03 или 0,035, вы можете немного подстроить его, добавив дополнительные примеры.
Это может быть проще всего передать людям на аутсорсинг.
Если у вас есть бюджет, рассмотрите Механический тур Амазонки . См. Википедию для общего описания .
В качестве альтернативы, вы можете сделать аутсорсинг самостоятельно. Напишите скрипт PHP для отображения одного из ваших изображений и попросите пользователя отсортировать его как «логотип» нашего «плана». После того, как вы запустите это на веб-сервере, отправьте по электронной почте весь свой офис и попросите всех отсортировать 20 изображений в качестве личной поддержки.
Еще лучше, сделайте это конкурс – человек, который сортирует большинство изображений, выиграет ipod!
Возможно, просто попросите всех, кого вы знаете, пиццу и пиво, настройте кучу ноутбуков и попросите всех провести несколько минут сортировки.
Существуют программные способы выполнения вашей задачи, но если это одноразовое мероприятие с менее чем несколькими тысячами изображений и бюджетом не менее нескольких сотен долларов, чем я думаю, что ваша жизнь может быть проще с использованием людей.
Одной из первых вещей, которые приходит на ум, является тот факт, что планы этажей, как правило, имеют значительно больше линий, ориентированных на 90 градусов, чем любой нормальный логотип.
Быстрый первый проход будет состоять в том, чтобы запустить обнаружение края Canny на изображении и проголосовать по углам, используя преобразование Hough и определение линии Theta в стиле Theta. Если вы видите очень сильное соответствие для Theta = (0, 90, 180, 270), суммированное по rho, вы можете классифицировать изображение как план этажа.
Другим вариантом было бы перейти к краю изображения после шага Canny, чтобы только подсчитывать голоса из длинных непрерывных сегментов линии, удаляя шум.
Я очень сомневаюсь, что любой такой инструмент уже существует, и создание чего-то точного было бы нетривиальным. Если вам нужна сортировка набора существующих изображений (например, у вас есть несортированный каталог), тогда вы можете написать инструмент «достаточно хорошо» и вручную обработать ошибки. Если вам нужно сделать это динамически с новыми изображениями, это, вероятно, неправильный подход.
Если бы я попытался сделать это для первого случая, я бы, вероятно, искал что-то тривиально другое, которое я могу использовать в качестве прокси. Планы этажей обычно намного больше, чем логотипы (размер файла или размер изображения)? Планы этажей имеют меньше цветов, чем логотип? Если я могу получить 75% -ную точность, используя что-то тривиальное, это, вероятно, путь.
Подобные вещи – распознавание шаблонов в изображениях – имеет тенденцию быть ужасно дорогими с точки зрения времени, ужасно ненадежными и постоянно нуждаются в обновлении и исправлении, чтобы соответствовать новым случаям.
Могу ли я спросить, зачем вам это нужно? Нет ли смысла в рабочем процессе вашего сайта, где его можно определить вручную, является ли изображение логотипом или планом этажа? Не было бы проще написать приложение, которое позволяет пользователям определять, что есть на момент загрузки? Почему вначале есть смешанный набор данных?
Несмотря на то, что это требует вмешательства вручную, вы можете проверить размер изображения.
Маленьким (как с точки зрения MB, так и размерами) изображение, вероятно, будет логотипом.
Большой (как по МБ, так и по размеру) изображение, скорее всего, будет плановым планом.
Однако это будет только измерение вероятности и ни в коем случае не является надежным.
Тип изображения также является индикатором, но меньше одного. Логотипы, скорее всего, будут JPG, PNG или GIF, планы этажей, возможно, будут TIFF или другой формат без потерь – но это не гарантия.
Простая простая попытка, с которой я сначала попытался бы использовать SVM, чтобы узнать ключевые точки SIFT, полученные из образцов. Но прежде чем вы сможете это сделать, вам нужно пометить небольшое подмножество изображений, давая ему либо -1 (план этажа), либо 1 (логотип). если изображение имеет больше ключевых точек, классифицированных как план этажа, то это должен быть план, если у него больше ключевых точек, классифицированных как логотип, то это должен быть логотип. В Computer Vision это называется подходом с мешком, а также одним из самых простых методов. Более сложные методы, вероятно, приведут к лучшим результатам, но это хорошее начало.
Как говорили другие, такое распознавание изображений обычно ужасно сложно. Забудьте PHP.
Однако, просматривая ваши образцы, я вижу критерии, которые МОГУТ работать очень хорошо, и было бы довольно легко реализовать, если бы это произошло:
Запустите изображение с помощью хорошего OCR, посмотрите, какие строки выскочат. Если вы найдете кучу слов, описывающих номера или такие функции …
Я бы повернул изображение на 90 градусов и снова попытался поймать вертикальные метки.
Изменить: Поскольку вы говорите, что попробовали, и это не сработает, возможно, вам нужно сначала очистить беспорядок. Нарежьте изображение на основе пробелов. Запустите OCR против каждого суб-изображения, если он запутался, пытаясь разобрать строки. Вы можете проверить это вручную, используя редактор изображений, чтобы отрезать его.
Используйте насыщенность цвета и размер изображения (оба предлагаются отдельно в предыдущих ответах). Используйте большой образец классифицированных человеком фигур и посмотрите, как они закладываются в двумерном пространстве (насыщенность по размеру), а затем решают, где поставить границу. Граница не должна быть прямой, но не делайте слишком много завихрений, пытаясь сделать все точки подходящими, или вы будете «замаскировать» образец за счет новых данных. Лучше найти относительно простую границу, которая подходит для большинства образцов, и она должна соответствовать большинству данных.
Вы должны терпеть определенную ошибку. Безвредное решение этого невозможно. Что, если я выберу план в качестве логотипа моей компании? (это не шутка, это просто смешно)