Данная статья посвящена проблеме распознавания образов применительно к архитектурным чертежам, и описанию разработанной мною технологии распознавания и векторизации архитектурных чертежей и последующим построением трехмерной модели помещения при помощи программных средств Autodesk 3DS MAX. Актуальность этой темы связана с тем, что в настоящее время очень полезна максимальная автоматизация процесса разработки готового продукта, которым в данном случае является компьютерная 3-х мерная модель какого либо объекта, например фасада здания либо помещения изнутри. Итак, начнем, ниже будет описана работа плагина написанного на MAX Script, который распознает простые чертежи здания ( вид сверху и развертка стен), и строит по ним модель здания. Алгоритм реализован в виде последовательно выполняющихся блоков, выполнение которых запускает пользователем нажатием кнопок в окне утилиты. Рассмотрим работу утилиты, чтобы установить ее необходимо зайти в раздел Utilities главной панели инструментов 3DS MAX, выбрать пункт MAXScript и, нажав кнопку Run Script, запустить файл ModelCreator.ms. В раскрывающемся списке Utilities появится наша утилита. Выбрав в списке пункт Model Creator, появиться свиток утилиты. Интерфейс программы создавался при помощи Visual MAXScript и выполнен в виде блоков, отвечающих за те или иные действия лгоритма.
Первый блок «загрузка данных» выполняет загрузку в программу начальных данных, того что получает утилита на входе. В первом блоке расположены следующие кнопки: «Select top drawing» - загрузка чертежа «вид сверху» нашего дома. «Select walls drawing» загрузка чертежа «развертка стен». «Create Scene» - Создание сцены (для наглядности выполнения алгоритма программы). Во втором блоке «Создание модели» расположены кнопки, запускающие алгоритмы распознавания загруженных чертежей, нахождения вершин, построения сплайнов стен, готовой трехмерной модели дома. В блоке находятся следующие кнопки: «Create Spline top» - создание сплайна «вид сверху» «Create Spline wall» - создание сплайна «развертка стен» «Create 3D model» - создание трехмерной модели «Cut Windows» - вырезание окон Снизу расположена кнопка «Render scene» - запускает визуализацию полученной модели. «Progress bar» - показывает состояние выполнения той или иной операции. «Delete All» очищает сцену от всех объектов.
Использование программы
Для начала работы алгоритма распознавания, программе необходимо получить начальные данные, ими являются чертежи здания. Для этого предоставлены кнопки «Select top drawing» и «Select walls drawing». Нажатие этих кнопок открывает диалог выбора файла, пользователь выбирает файлы чертежа и программа получает объекты в виде битовой карты, с которой в последствие будет работать. (чертежи и код плагина находятся в приложении)
Чертежи представлены в виде изображения в формате bmp, и имеют размер 800 на 400 пикселей. Элементы здания изображаются на чертеже черными линиями шириной в 1 пиксель.
"Вид сверху"
"Развертка стен"
На чертеже «Развертка стен» показываются все стены здания, спроецированные в одну плоскость, т.е. идущие друг за другом по часовой стрелке, прямоугольниками внутри стен показаны окна и двери. Выбрав чертежи, пользователь, нажав «Create Scene» создает так называемую сцену, в которой размещаются две плоскости, на которые нанесены изображения здания, это сделано для наглядности работы программы. Далее следует блок запуска алгоритма просчета. Кнопки «Create Spline top» и «Create Spline wall» запускают распознавание стен, окон и дверей, и строят сплайны, понятные программе 3DS MAX, то есть производится перевод начальных растровых изображений в векторное представление. На основе полученных сплайнов, в последствие будет построена трехмерная модель нашего здания. Сплайны располагаются над плоскостями. На «Progress bar» иллюстрируется состояние процесса выполнения данной операции. Краткое описание алгоритма, по которому плагин строит сплайн, представлено ниже.
Построенные сплайны
На завершающем этапе использования программы, пользователь, нажав «Create 3D model» и «Cut Windows», получает готовую трехмерную модель здания, и может использовать ее в дальнейшей обработке, будь то разработка фасада здания или дизайна интерьера.
Построенный объект
Описание работы алгоритма программы Программа, получая на входе растровые изображения, обработав их, должна на выходе построить трехмерную модель, рассмотрим последовательно ход работы алгоритма. Формат bmp (от слов Bit MaP - битовая карта) , или, проще говоря, битовый массив - представляет из себя несжатое (в основном) изображение. В нем изображение описывается как массив точек, у которых есть координаты (начинаются с нуля) и цвет. Загружая bmp файлы в программу, мы можем с помощью функций, предоставляющихся библиотекой MAXScritp, получить данные о той или иной точке. Нажимая кнопки «Select top drawing» и «Select walls drawing» выполняются строки top_image = getBitmapOpenFileName () и walls_image = getBitmapOpenFileName (). функция getBitmapOpenFileName () открывает диалог выбора файла и возвращает пусть к нему, записывая его в глобальные переменные top_image и walls_image, флаги top_change и walls_change принимают значение true, что означает, что чертежи выбраны. Получив адреса bmp файлов, нажимая кнопку «Create Scene», пройдя проверку на то, что файлы выбраны (top_change и walls_change равно true), создаются две плоскости, и к ним применяется материал, в диффузный канал которого записывается выбранные изображения. meditMaterials[1].diffuseMap = Bitmaptexture fileName:top_image meditMaterials[2].diffuseMap = Bitmaptexture fileName:walls_image На данном этапе программа получила все необходимые для работы данные, и можно приступать к выполнению алгоритма распознавания чертежей. Нажав кнопку «Create Spline top» утилита начинает процесс создания сплайна, рассмотрим подробно его работу. В начале нам необходимо создать матрицу размерностью 800 на 400, равной ширине и высоте загружаемых чертежей. Однако язык MAXScript не позволяет создавать матрицы такого большого размера. Было выбрано следующее решение этой проблемы: изображение как бы разбивается на квадраты размерностью 200 на 200, и создается «виртуальная» матрица размером 800 на 400 состоящая из 8-ми обычных матриц. В MAXScript матрицы создаются конструктором bigmatrix и объявляются следующим образом: global matrix_1 = bigmatrix 200 200 global matrix_2 = bigmatrix 200 200 … global matrix_8 = bigmatrix 200 200 Таким образом, получены 8 матриц с именами matrix_1, matrix_2 … matrix_8, по умолчания заполненных нулями, из которых в последствие будет создана «виртуальная» матрица размером 800 на 400. Реализовано это будет функцией addToMatrix, которая анализируя координаты ячейки, записывает их в ту или иную созданную нами до этого матрицу 200 на 200. Функция addToMatrix описана следующим образом: function addToMatrix x y val = ( if x <= 200 and y <= 200 then (matrix_1 [x][y] = val) else if x <= 200 and y > 200 then (matrix_2 [x][y-200] = val) else if x <= 400 and y <=200 then (matrix_3 [x-200][y] = val) else if x<= 400 and y > 200 then (matrix_4 [x-200][y-200] = val) else if x<= 600 and y <= 200 then (matrix_5 [x-400][y] = val) else if x<= 600 and y > 200 then (matrix_6 [x-400][y-200] = val) else if x<= 800 and y <= 200 then (matrix_7 [x-600][y] = val) else matrix_8 [x-600][y-200] = val ) Аргументами функции являются переменные x, y и val которые передают номер столбца и строки создаваемой «виртуальной» матрицы, и значение val, которое будет записано в ячейку x y. Извлечение же необходимого нам элемента будет осуществляться функцией getFromMatrix. Функция описана следующим образом: function getFromMatrix x y = ( if x <= 200 and y <= 200 then return matrix_1 [x][y] else if x <= 200 and y > 200 then return matrix_2 [x][y-200] else if x <= 400 and y <=200 then return matrix_3 [x-200][y] else if x<= 400 and y > 200 then return matrix_4 [x-200][y-200] else if x<= 600 and y <= 200 then return matrix_5 [x-400][y] else if x<= 600 and y > 200 then return matrix_6 [x-400][y-200] else if x<= 800 and y <= 200 then return matrix_7 [x-600][y] else return matrix_8 [x-600][y-200] ) Функция, получая координаты ячейки, анализируя их, возвращает элемент, находящийся в ней. Далее алгоритм переходит к сканированию загруженного изображения. Сканирование осуществляется проходом по всем точкам битовой карты и извлечением из нее цвета точки, занося в созданную «виртуальную матрицу» значение 1, если цвет точки черный или близкий к черному. То есть, получаем матрицу размером равным размеру загруженных чертежей, в ячейках, соответствующих координатам точек изображения, стоит 1 если точка черная, иначе 0.
Фрагмент матрицы, и соответствующий ему фрагмент чертежа
После проделанных операций, мы получили представление чертежа в виде матрицы, заполненной нулями и единицами, к ячейкам которым можно обратиться с помощью описанной ранее функции getFromMatrix. Далее алгоритм приступает к построению сплайна, то есть переводу растрового изображения представленных на чертеже элементов в векторные объекты, из которых впоследствии, возможно будет построить трехмерную модель. В начале, сканируя матрицу, необходимо найти координаты первой вершины будущего сплайна, они соответствуют первой единице в матрице. Отыскав ее, и двигаясь потом от нее по «направлению стен», по часовой стрелке, и устанавливая вершины на изменениях направления движения, построить сплайн, описывающий структуру стен здания, его окон и дверей. Сплайн в MAXScript создается с помощью конструктора SplineShape global Shape01= SplineShape pos:[0,0,70] global Shape02= SplineShape pos:[0,-400,70] данные строки создают пустые объекты, так называемые формы, Shape , которые внутри себя будут содержать сами сплайны, которые добавим в форму позже. Координаты создаваемых форм [0,0,70] и [0,-400,70] соответственно. Ссылки на объект Shape присваиваются переменным Shape01и Shape02. Сплайн из формы Shape01 будет сплайном контура здания, а по сплайнам из Shape02 – выстраиваться объем здания, то есть вычисляться его высота, находится окна и двери, а размещаться на здании. Сначала необходимо построить сплайн, который будет соответствовать контуру нашего здания. Используя стандартный алгоритм обхода матрицы, найдя первую единицу в матрице, добавляем в форму Shape01первый сплайн конструктором addNewSpline . И добавляем патом уже в него первую вершину. Строка numSpline = addNewSpline Shape01 добавляет сплайн в форму Shape01 и в переменную numSpline записывается его порядковый номер. Строка addKnot Shape01 numSpline #corner #line [k-400,-l+200,70] добавляет в сплайн с номером numSpline вершину с координатами k-400 и ,-l+200, где k и l номер ячейки в матрице, соответствующей вершине сплайна, сдвиг -400 и +200 делается для более удобного размещения объекта в сцене. Координаты вершины будут соответствовать номеру столбца и строки в матрице. В контуре здания (Shape01) будет всего один сплайн, потому что одной линией можно описать периметр здания. В форме Shape02, будет намного больше сплайнов, их количество будет соответствовать всем элементам в чертеже «развертка стен». Найдя первую вершину, необходимо найти следующие, то есть обойти здание вокруг по часовой стрелке, и найти координаты вершин углов здания, чтобы соединив их получить векторное представление нарисованного на чертеже контура здания. Для этого необходима функция, определяющая направление движения по матрице: function direction n p = ( if (getFromMatrix (n+1) p) == 1 then return right else if (getFromMatrix n (p+1)) == 1 then return down else if (getFromMatrix (n-1) p) == 1 then return left else if (getFromMatrix n (p-1)) == 1 then return top else return noDirection ) Получая координаты точки, от которой следует узнать направление движения, функция поверяет с какой стороны находится «продолжение стены» и возвращает данное направление в виде переменных right, left, down и top. Эти переменные на самом деле равны цифрам 1, 2, 3, 4, но для наглядности используются именно слова. Имея координаты первой вершины и направление дальнейшего движения, можно двигаться по матрице и искать следующие вершины, добавляя их в созданный ранее сплайн. Находиться же они будут в том месте, где направление движения изменяется, то есть на углах здания на чертеже.
Место, где будет находиться вершина сплайна.
Обойдя по часовой весь контур здания в матрице и добавив на углах вершины в сплайн, замыкаем его командой сlose Shape01 numSpline Здесь Shape01 это объект «форма», numSpline – ссылка на сплайн внутри нее. В итоге мы получили векторное представление контура здания.
Снизу – растровый чертеж, сверху – векторный сплайн.
Необходимо добавить, что проходя контуру здания в матрице, пройденные единицы заменялись нулями, чтобы двигаться только вперед по направлению движения стен, иначе для последующих точек функция, определяющая направление, могла направить нас в обратную сторону, назад. Также, заменив пройденные единицы нулями, из матрицы удалялся построенный в итоге сплайн, и можно было запускать алгоритм повторно, чтобы найти окна и двери, которые находиться внутри внешнего сплайна на втором чертеже «развертка стен».При создании векторного представления этого чертежа, проход по матрице осуществлялся столько раз, сколько было различимых объектов на рисунке стен (окна, двери, углы стен, контур всего здания в проекции на одну плоскость) Лишь построив все сплайны, цикл останавливался, и векторное представление стен было построено.
Сплайн для чертежа "развертка стен"
 Конец первой части...  Вторая часть: http://arvo.ua/index.php?event=blog&show_blog=42

2
0
3273
ТОП БЛОГЕРЫ

Город: Симферополь

Город: Симферополь