Готовый перевод OpenCV 2 Computer Vision Application Programming Cookbook / Изучаем OpenCV: Играем с изображениями
Играем с изображениями
- Установить OpenCV библиотеку
- Создать OpenCV проект совместно с Micosoft Visual C++
- Создать OpenCV проект совместно с Qt
- Загрузить, отобразить, и сохранить изображение
- Создать GUI приложение, используя Qt
Введение
Эта часть обучит базовым элементам в OpenCV и покажет, как решать самые простые задачи: чтение, отображение и сохранение изображений. Перед тем как начинать работать с OpenCV, Вам нужно установить эту библиотеку. Это простой процесс, который объясняется в первом части этой главы.
Так же нужна хорошая середа разработки (IDE) для запуска Ваших OpenCV приложений. Мы предлагаем две альтернативы. Первый вариант это использовать Microsoft Visual Studio. Вторым же вариантом является использование инструмента с открытым исходным кодом для разработки С++ проектов, который называется Qt. Здесь будет описано, что нужно будет сделать для того, что бы начать программировать с помощью OpenCV только для двух платформ, но Вы можете использовать любую другую С++ IDE. На самом деле, в этом учебнике, задачи поставлены таким образом, что решение не зависит от определенной операционной системы или среды разработки, так что Вы можете использовать любую IDE. Однако знайте, что Вам нужно использовать скомпилированные версии библиотеки OpenCV подходящей Вашей операционной системе и компилятору. Если Вы видите странное поведение, или если Ваше приложение крошится без видимых причин, это возможно следствие несовместимости.
Установка библиотеки OpenCV
OpenCV - это библиотека с открытым исходным кодом для разработки приложений, использующих компьютерное зрение. Библиотека может использоваться в научных и коммерческих приложениях под лицензией BSD, которая позволяет свободное использование, распространение и редактирование его. Эта инструкция покажет Вам, как установить библиотеку на Ваш компьютер.
Давайте приступим
Когда вы перейдете на официальный сайт OpenCV по адресу http://opencv.willowgarage.com/wiki/, Вы сможете найти последнюю версию библиотеки, онлайн документацию, и много полезных ресурсов о OpenCV.
Как это сделать…
С главной страницы сайта OpenCV, перейдите на страницу скачивания библиотеки и выберите платформу, которая вам нужна (Linux/Unix/Mac или Windows). Здесь Вы сможете скачать пакет OpenCV. Как только вы разархивируете библиотеку в папку с названием версии библиотеки (например, OpenCV2.2), Вы сможете увидеть большое количество папок, среди которых будет папка DOC, в которой будет документация OpenCV. Еще можно найти папку include, которая включает в себя все файлы, которые нужно подключить к проекту, и папку modules, что хранит в себе исходные коды. Так же содержит папку samples, которая содержит много небольших примеров, помогающие разобраться с библиотекой.
Если вы являетесь пользователем Windows и используете Visual Studio, Вы так же имеете возможность скачать установочный пакет, соответствующий вашей IDE и вашей операционной системе. Запуск этой установочной программы не только установит исходную библиотеку, но и скопирует все скомпилированные файлы, необходимые для создания Ваших приложений. В этом случае Вы готовы к тому, что бы начать использовать OpenCV. Если же нет, то Вам необходимо сделать несколько простых шагов.
Для того, что бы использовать OpenCV в другой среде разработки, Вам необходимо скомпилировать библиотеку используя компилятор С++. Для компиляции OpenCV не обходимо использовать инструмент CMake, который можно найти по адресу http://www.cmake.org/. CMake – это инструмент с открытым исходным кодом, разработанный для управления процессами компиляции программных систем, используя платформо-независимые конфигурационные файлы. Вам нужно скачать и установить CMake. Вы можете запустить ее из командной строки, но более простым решением будет использование GUI версию CMake. В этом случае все, что Вам нужно будет сделать, это указать папку с OpenCV. Затем нажать кнопку Configure и выбрать ваш компилятор (здесь мы выбрали Visual Studio 2010), затем нажать кнопку Configure опять, как показано на скриншоте ниже:
Теперь вы готовы для создания make файлов и файлов рабочего, нажав на кнопку Generate. Эти файлы позволяют вам скомпилировать библиотеку. Это последний шаг в процессе установки.
Компиляция библиотеки сделает ее готовой для использования в вашей среде разработки. Если вы выбрали IDE Visual Studio, то все что вам нужно это открыть файл решения, который CMake создал для вас. Затем выполните команду «Построить решение» («Build Solution»). В средах разработки под Unix, вы можете использовать сгенерированные make файлы для запуска вашего компилятора.
Если все прошло хорошо, то теперь у вас есть скомпилированные и готовые к использованию библиотеки OpenCV в соответствующей папке. Эта папка будет содержать, помимо уже упоминаемых нами папок, каталог BIN включающий скомпилированную библиотеку. Вы можете переместить библиотеку в удобное для вас место (например, «c:\OpenCV2.2»). Сейчас вам нужно добавить вашу папку BIN в системные «Переменные среды» («Панель управления» -> «Система» -> «Дополнительные параметры системы» -> «Переменные среды»).
Как это работает...
Используемая версия библиотеки OpenCV 2.2 разделено на модули. Жти модули находятся в папке lib. Это:
- Модуль opencv_core, включающий основные функции библиотеки, в частности основные структуры данных и арифметические функции.
- Модуль opencv_imgproc, включающий основные функции обработки изображений.
- Модуль opencv_highgui, который включает функции чтения и записи изображений и видео, а так же функции, что реализуют интерфейс пользователя.
- Модуль opencv_features2d, включающий функции детекторов точек и дескрипторы.
- Модуль opencv_calib3d, включающий функции калибровки камеры, два вида оценки геометрии, и функции для работы с стерео изображениями.
- Модуль opencv_video, включающий функции оценки движения, отслеживания, и функции и классы для исключения переднего фона.
- Модуль opencv_objdetect, включающий функции определения людей и лиц.
Библиотека так же включает отдельные модули, что содержат функции машинного обучения (opencv_ml), вычислительные геометрические алгоритмы (opencv_flann), содействующий код (opencv_contrib), устаревший код (opencv_legacy), и код, использующий GPU для ускорения расчетов (opencv_gpu).
Все модули имеют header файл, предписанный ему (находится в папке include). Обычный OpenCV C++ код обычно начинается с подключения необходимых модулей. Например:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
Если вы видите, что код начинается с
#include "cv.h"
то, это означает что используется старый стиль, теперь же библиотека переделана в модули.
Более...
Так же вы можете получить последние коды OpenCV с сервера SVN, что находится по адресу:
https://code.ros.org/svn/opencv/trunk/opencv/
Вы увидите, что есть большое количество примеров, что помогут изучить как использовать библиотеку и покажет вам советы разработки.
Создание OpenCV проекта в MS Visual C++
Используя MS Visual C++, вы можете создать OpenCV приложение под Windows. Вы можете создать простое консольное приложение или более сложное с прекрасным пользовательским интерфейсом (GUI). Так как это самое простое решение, мы создадим простое консольное прложение здесь. Мы будет использовать Visual Studio 2010, однако, все действия применимы к другим версиям Visual Studio - меню и опции очень похожи с с другими версиями.
Когда вы запустите Visual Studio в первый раз, вы можете настроить ее так, что бы С++ был вашей стандартной средой. Этот путь, когда вы запускаете IDE, это будет режим Visual C++.
Мы предпологаем, что OpenCV уже установлена у вас в папку C:\OpenCV2.2, как описано в инструкции перед этой частью.
Давайте приступим
При работе с Visual Studio необходимо понимать разницу между решением ("solution") и проектом ("project"). В принципе, решение состоит из нескольких проектов (каждый проект является самостоятельным программным модулем, например, программой или библиотекой). Таким образом проекты вашего решения могут обмениваться файлами и библиотеками. Обычно, вы создаете одну главную папку для вашего решения и проект в одной папке. Это то, что вы будете делать для простых решений. Когда вы станете более знакомы с VS C++, и начнете разрабатывать более сложные приложения, вы начнете делать много проектные решения.
Так же, для компилирования и выполнения ваших Visual C++ проектов, у вас есть две конфигурации: Debug и Release. Режим отладки (Debug) помогает вам создавать и отлаживать ваши приложения. Это более защищенное решение, например, показывающие вам в вашей приложении утечки памяти, или проверку правильности выполнения функций во время работы программы. Тем не менее, в режиме отладки файлы больше занимают места, и дольше создаются. Вот почему, когда ваше приложение готово его необходимо компилировать в режиме релиза (Release). Этот файл можно будет распространять пользователям вашего приложения. Обратите внимание, что может случиться, если у вас код работает отлично в режиме отладки, но есть проблемы в режиме релиза. Вам нужно будет выполнить больше тестов с целью выявления потенциальных источников ошибок.
Большинство современных IDE поддерживают конфигурации отладки и релиза, так что Visual C++ этим не уникальна.
Как это сделать…
Теперь вы готовы для создания вашего первого проекта. Это делается используя пункт меню File|New Project|Project... Здесь вы можете создать различные проекты. Давайте начнем с самого простого варианты, выбрав Win32 Console Application, как показано на следующей скриншоте:
Вам необходимо указать где необходимо создать проект, и под каким названием. Так же есть настройка, что позволяет выбирать - создавать папку для решения или нет. Если выбрать эту настройку, то будет создана папка с названием, которое вы задали, в папке с решением. Если это не будет сделано, то файл решения (разрешение .sln) все равно будет создано, но все файлы будут находиться в одной папке в неупорядоченном виде. Нажмите на ОК и Next, что бы перейти в следующему окну Application Settings. Как видно на следующем скриншоте, предлагается несколько вариантов создания. Мы же создадим пустой проект.
Заметим, что мы также не отметили опцию заголовков до компиляции, которая является особ MS Visual
Studio--специфической особенностью, делающей процесс компиляции более быстрым. Так как мы хотим оставаться внутри стандарта ANSI C++, то мы не будем использовать эту опцию. Если мы нажмём на кнопку "завершить", тогда наш проект создастся. Пока он ещё пустой, но мы скоро добавим к нему главный файл main.
Но сначала, для компилирования и создания ваших OpenCV приложений необходимо "показать" Visual Studio где находится библиотека OpenCV и подключаемые файлы. Лучшим вариантом будет создание Property Sheet (шаблон), что бы было удобнее в будущем создавать проекты.
В Visual C++ 2010 шаблон - это XML файл, который описывает ваши настройки проекта. Теперь необходимо создать новый правым кликом по Debug | Win32 ветке вашего проекта и выбрать Add New Project Property Sheet (как показано на скриншоте ниже):
Новый шаблон бует добавлен после нажатия на Add. Теперь необходимо редактировать его. Простой двойной клик по имени шаблона и выберите VS++ Directories, как показано ниже:
Измените поле Include Directories, отвечающее за каталоги включения дополнительных файлов и добавьте путь к включаемым файлам из вашей библиотеки OpenCV:
Сделайте то же самое с Library Directories. На этот раз вы добавите путь к вашей OpenCV библиотеке файлов:
Важно отметить, что мы использовали явный путь к библиотеке OpenCV в наших свойствах. Как правило, лучше всего является использование переменной среды для обозначения места нахождения библиотеки. Таким образом, если вы переключаетесь на другую версию библиотеки, нужно просто изменить определение этой переменной, чтобы он указывал на новое место хранения. Также, в случае с командным проектом, разные пользователи могли установить библиотеки в разные места. Использование переменной среды позволило бы избежать необходимости редактирования свойств для каждого пользователя.
Следовательно, если вы создадите переменную окружения OPENCV2_DIR с адресом C:\OpenCV2.2, то затем другие OpenCV каталоги будут указаны как $(OPENCV_DIR)\include и $(OPENCV_DIR)\lib в окне свойств.
Следующим шагом является определение файлов библиотеки OpenCV, которые должны быть связаны с вашим кодом для получения рабочего приложения. В зависимости от применения, могут потребоваться различные модули OpenCV. Так как мы хотим использовать это свойство во всех наших проектах, мы просто добавляем модули библиотеки которые необходимы, что бы запустить приложения из этой книги. Перейдите в пункт Input ветки Linker, как показано на следующем скриншоте:
Отредактируйте текстовое поле "Additional Dependencies" добавив следующий список модулей:
Обратите внимание, что мы указали библиотеки, имена которых заканчиваются на букву "D". Эти двоичные файлы служат для режима отладки. Вам нужно будет создать другой (почти идентичный) лист свойств для Release режима. Вы выполните ту же процедуру, но с добавлением его в узел Release|Win32. На этот раз, имена библиотек указаны без добавления "D" в конце.
Теперь мы готовы создать, скомпилировать и запустить наше первое приложение.Мы добавляем новый исходный файл с помощью Solution Explorer, и щелкаем правой кнопкой мыши на узел Source Files(исходных файлов). Вы выбераете Add -> New Item ..., который дает вам возможность задать имя файла (пускай это будет main.cpp):
Вы также можете использовать File-> New File ... меню дает возможность это сделать. Теперь, давайте построим простое приложение, которое будет отображать изображение с именем img.jpg расположенный в каталоге по умолчанию.
После того как вы переписали код на предыдущем рисунке (об этом будет сказано позже), вы можете скомпилировать и запустить его с помощью кнопки Start (зеленая стрелка на панели инструментов в верхней части экрана). Вы увидите изображение отображается в течение пяти секунд. В качестве примера можно посмотреть здесь:
Если это так, то вы уже впервые применили OpenCV! Если программа не запустилась на выполнение, это, вероятно, потому, что он не может найти файл изображения. См. следующий раздел, чтобы узнать, как поставить его в нужном каталоге.
Как это работает...
При нажатии на кнопку Start Debugging (или нажмите F5), ваш проект будет скомпилирован, а затем выполнен. Вы также можете просто скомпилировать проект, выбрав команду Build Solution (F7) в меню Build. При первой компиляции проекта будет создана папка Debug. Онf будет содержать исполняемый файл (с расширением .exe). Вы также можете создавать Release версии, просто выбрав режим Release с помощью выпадающего меню, справа от кнопки с зеленой стрелкой (или с помощью Configuration Manager ... опции в меню Build). В Release так же будет создан каталог, только с названием Release.
При выполнении проекта с помощью кнопки запуска в Visual Studio, каталог по умолчанию всегда будет тот, который содержит файл вашего решения. Однако, если вы решите выполнить ваше приложение за пределами вашей IDE (то есть, из Проводника), дважды щелкнув на вашем исполняемом файле (обычно в каталоге Release), то каталог по умолчанию станет тот, который содержит исполняемый файл. Таким образом, убедитесь, что ваш файл изображения находится в соответствующем каталоге перед выполнением этого приложения.
Так же смотрите
Загрузка, отображение и сохранение изображений инструкции далее в этой главе, которая объясняет какой исходный код OpenCV, мы использовали в этой задаче.
Создание проекта OpenCV с использованием Qt
Qt является полной интегрированной средой разработки (IDE) для C++ приложений, которая первоначально была разработана Trolltech, норвежской компанией программное обеспечение, которой было приобретено в 2008 году Nokia. Данная IDE Предлагается под LPGL лицензией открытого кода, а также под коммерческой (и платной) лицензией на разработку собственных проектов. Она состоит из двух отдельных элементов: кросс-платформенной IDE, называется Qt Creator, и набором библиотек Qt классов и средств разработки. Использование Qt Software Development Kit (SDK) для разработки C++ приложений имеет много преимуществ:
Такая открытая инициатива исходного кода, разрабатывается сообществом Qt, она дает вам доступ в исходный код различных компонентов Qt.
Является кросс-платформенной IDE, а это означает, что вы можете разрабатывать приложения, которые могут работать на
различных операционных систем, таких как Windows, Linux, Mac OS X, и так далее.
Она включает в себя полную и кросс-платформенную библиотеки графического интерфейса, которая следует эффективной объектно-ориентированной и событийно-управляемой модели.
Qt также включает несколько кросс-платформенных библиотек для разработки мультимедиа, графики, баз данных, многопоточность, веб-приложения и многие другие интересные составляющие блоки которые полезны для разработки современных приложений.
Подготавливаемся
Qt можно загрузить с http://qt.nokia.com. Это бесплатно, если вы выберите LPGL лицензию.Вы должны скачать полный SDK. Тем не менее, убедитесь, что выбран пакет Qt библиотек, который подходит для вашей платформы. Очевидно, что так как мы имеем дело с открытым исходным кодом, то всегда можно перекомпилировать библиотеку под платформу по вашему выбору.
Здесь мы используем Qt Creator версии 1.2.1 с Qt версии 4.6.3. Обратите внимание, что во вкладке Projects в рамках Qt Creator, можно управлять различными версиями Qt, что вы можете установить. Это гарантирует, что вы всегда можете компилировать проекты, с соответствующей версией Qt.
Как это сделать...
При запуске Qt, он будет спросит у вас, вы хотите создать новый проект или хотите, открыть недавно используемый. Вы также можете создать новый проект, выбрав в меню File пункт New. Повторив то, что мы сделали в предыдущем инструкции, мы выберем Qt4 консольного приложение, как показано на следующем скриншоте:
Затем нужно указать имя и расположение проекта, как показано здесь:
Следующее окно предложит вам выбрать модули, которые вы хотите включить в ваш проект. Просто выберите один по умолчанию и нажмите Далее, а затем Готово. Будет создано пустое консольное приложение, как показано здесь:
Код, сгенерированный в Qt создается QCoreApplication objects и вызывает его exec() метод. Это требуется только, когда ваше приложение должно иметь обработчик события для обработки взаимодействия пользователя с графическим интерфейсом. В нашем приложении открывать и отображать изображения, например, просто нет необходимости. Мы можем просто заменить сгенерированный код, который мы использовали в предыдущей задаче. Простые открыть и отобразить изображение программа будет выполнять следующим образом:
Для того, чтобы иметь возможность компиляции этой программы, библиотека файлов OpenCV, должен быть указан заголовок расположения файлов. В Qt, эта информация приводится в файле проекта (с расширением .рro), который является простым текстовым файлом с описанием параметров проекта . Вы можете редактировать этот файл проекта в Qt Creator, выбрав соответствующий файл проекта, как показано на следующем скриншоте:
Информация, необходимая для создания приложений OpenCV обеспечивается путем добавления
Следующие строки в конце файла проекта:
INCLUDEPATH += C:\OpenCV2.2\include\
LIBS += -LC:\OpenCV2.2\lib \
-lopencv_core220 \
-lopencv_highgui220 \
-lopencv_imgproc220 \
-lopencv_features2d220 \
-lopencv_calib3d220
Программа в настоящее время готова к компиляции и выполнению. Это осуществляется путем нажатия левой кнопки мыши на зеленой стрелке (или нажатием Ctrl + R). Существует также отладка и режим релиза, которые вы создали, используя встроенные настройки на вкладке Projects.
Как это работает...
Проект Qt описывается в файле проекта. Это текстовый файл, который объявляет список переменных, содержащих необходимую информацию для создания проекта. Этот файл находится в обработке программного инструмента под названием Qt QMake который вызывается при компиляции. Каждая переменная определена в файле проекта, связанна со списком значений. Основными переменными, которые признаны QMake в Qt являются следующие:
TEMPLATE: Определяет тип проекта (приложения, библиотеки, и т.д.).
CONFIG: Определяет различные варианты, что компилятор должен использовать при построении проекта.
HEADERS: списки заголовочных файлов проекта. f SOURCES: списки исходных файлов (.cpp). проекта.
QT объявляет необходимые модули расширения Qt и библиотек. По умолчанию
ядро и GUI модули включены. Если вы хотите исключить одну из них, вы
использовать - = обозначений.
INCLUDEPATH: Определяет заголовочный файл, каталоги которые должны быть найдены. F LIBS: Содержит список файлов библиотеки, которые должны быть связаны с проектом. Вы используете флаг -L для пути к каталогам и флаг -l для библиотеки имен.
Некоторые другие переменные определены, но приведенные выше являются наиболее часто используемые.
Более...
Множество дополнительных возможностей можно использовать в файлах QMake проекта. Например, группы могут быть определены для добавления,объявления, относящиеся к определенной платформе: Win32 {
# declarations for Windows 32 platforms only
}
unix {
# declarations for Unix 32 platforms only
}
Так же можно использовать утилиту pkg-config. Она позволяет выбрать нужный вам компилятор и библиотеки. При установке OpenCV вместе с CMake будет создан файл opencv.pc, в котором описаны параметры компиляции. Мультиплатформенный qmake-проект будет описан примерно так:
unix {
CONFIG += link_pkgconfig
PKGCONFIG += opencv
}
Win32 {
INCLUDEPATH += C:\OpenCV2.2\include\
LIBS += -LC:\OpenCV2.2\lib \
-lopencv_core220 \
-lopencv_highgui220 \
-lopencv_imgproc220 \
-lopencv_features2d220 \
-lopencv_calib3d220
}
Так же смотрите
Также смотрите следующий пецепт: загрузка, отображение и сохранение изображений, объясняющие исходный код OpenCV, который мы используем в этом примере(задаче).
Свяжитесь с веб-сайтом http://qt.nokia.com для получения полной информации о Qt, Qt Creator, и всех модулях расширений Qt.
(с переездом Qt ссылка на сайт должна была измениться)
Загрузка, отображение и сохранение изображений
Эти два примера научат вас создать простой проект с OpenCV, но мы так и не объяснили код OpenCV, который мы использовали. Этот урок покажет вам как использовать наиболее фундаментальные оперторы, которые потребуются для разработки OpenCV приложения. Урок включает загрузку входного изображения из файла, вывод изображения на экран и сохранение выходного изображения на диск.
Подготавливаемся
Используя MS Visual Studio или Qt, создайте новое консольное приложение с функцией main, которую далее мы заполним. Смотрите первые два пункта, что бы сделать это.
Как это сделать...
Первое, что необходимо сделать это объявить переменную, которая будет хранить изображение. В OpenCV 2 за это отвечает класс cv::Mat.
cv::Mat image;
По умолчанию созданное изображение имеет размер 0 на 0 пикселей. Можно вызвать метод size() класса cv::Mat, что-бы получить текущие размеры изображения. Метод вернет структуру, которая будет хранить высоту (height) и ширину (width) изображения:
std::cout << "size: " << image.size().height << " , " << image.size().width << std::endl;
Следующий шаг - это простой вызов функции, которая считает изображения из файла, декодирует его в понятный компьютеру формат, и разместит в памяти:
image = cv::imread("img.jpg");
Теперь можно использовать это изображения. Но, тем не менее, необходимо проверить считалось ли изображение правильно, не возникло ли никаких ошибок при считывании (например, файл не найден, поврежден, или неизвестный формат). Проверка происходит следующим образом:
if (!image.data) {
// если изображение не создано в памяти...
}
Поле data в переменной на самом деле являются указателем на блок памяти, в котором находится изображение. В случае ошибки чтения туда устанавливается 0. Самое простое действие, которое можно сделать с этим изображением - это отобразить его. Для этого необходимо использовать модуль highgui. Прежде всего, необходимо объявить окно, в котором мы хотим отобразить изображение, а потом указать какое изображение мы хотим отобразить в этом окне:
cv::namedWindow("Original Image"); // создание окна
cv::imshow("Original Image", image); // отображение изображения в окне
Теперь можно применить обработчики к этому изображению. OpenCV предлагает много функций обработчиков, и о некоторых из них рассказывается в этой книге. Давайте начнем с простого отображения изображения в горизонтальном отображении. Некоторые трансформации изображений OpenCV могут быть применены на месте, т.е. не прибегая к созданию новой переменной-изображения. Тем не менее, у нас всегда есть возможность создать новую переменную, что бы отобразить изображение, и мы это сделаем:
cv::Mat result;
cv::flip(image,result,1); // позитивное число для горизонтального
// 0 для вертикального,
// отрицательное для обоих
И отобразим результат в отдельном окне:
cv::namedWindow("Output Image");
cv::imshow("Output Image", result);
Так как это консольное окно завершится вместе с функцией main, то добавим специальный метод модуля highgui для ожидания нажатия пользователем какой нибудь клавиши:
cv::waitKey(0);
Теперь можно увидеть входящее и выходящее изображение, которые отображены в двух разных окнах. Так же можно сохранить результат обработки (изображение) на жесткий диск в виде файла. Используем функцию модуля highgui для этого:
cv::imwrite("output.bmp", result);
Расширение файла определяется кодеком, который использовался для сохранения вашего изображения:
Как это работает...
Все классы и функции определенные в API OpenCV на языке С++ находятся в пространстве имен cv. Есть две возможности доступа к ним. Первый - это определить перед главной функций следующее определение:
using namespace cv;
Или, использовать ко всем классам и функциям OpenCV префикс cv::, как в этой книге.
Класс cv::Mat - это структура данных, которая используется для хранения ваших изображений (и других данных матриц). По умолчанию, он имеет нулевой размер, но можно указать размер при вызове конструктура:
cv::Mat ima(240,320,CV_8U,cv::Scalar(100));
В этом случае так же необходимо задать тип каждого элемента матрицы, наше CV_8U в данном случае означает, что каждому пикселю изображения отвечает один байт. Буква U означает беззнаковый. Так же можно объявить числа со знаком используя букву S. Для цветного изображения необходимо использовать три канала (CV_8UC3). Так же можно задать целое число (со знаком или нет) размера 16 и 32 (например, CV_16SC3). Так же есть возможность доступа к 32-х и 64-х битным числам с плавающей точкой (например, CV_32F).
(продолжение) Вы можете протестировать это поведение, объявив несколько дополнительных изображений в примере этого проекта следующим образом:
cv::Mat image2, image3;
image2 = result; // два изображения ссылаются на определенные данные
result.copyTo(image3); // создана новая копия
Теперь, если вы ещё раз перевернёте выходное изображение и выведите два дополнительных изображения, то вы увидите, что изображение image2 также пострадало из-за преобразований (потому что указывает на то же изображение, что и результирущее изображение), в то время как image3 остался без изменений, т.е. содержит копию первоначального изображения. Эта распределённая модель для cv::MAT objects , что означает, что вы можете безопасно писать функции (или методы классов) которые будут возвращать изображение:
cv::Mat function() {
// создано новое изображение
cv::Mat ima(240,320,CV_8U,cv::Scalar(100));
// возвращаем его
return ima;
}
Если мы вызовем эту функцию из нашей главной функции:
// получаем изображение в серых тонах
cv::Mat gray = function();
Переменная оттенка серого теперь будет содержать изображение сделанное этой функцией без дополнительного выделения памяти. Действительно, только поверхностная копия этого изображения будет передано из возвращенного экземпляра cv::Mat серому изображению. Когда локальная переменная ima выходит из области видимости, она освобождает память (развыделяется), но так как связанная с ней ссылка указывает, что на внешние данные изображение ссылается другой экземпляр (который является переменной оттенка серого), то блок его памяти не освобождается.
Как бы то ни было, вы должны быть очень осторожны при выборе классов и не возвращать атрибуты класса изображения. Вот пример опасной реализации с ошибкой:
class Test {
// атрибуты изображения
cv::Mat ima;
public:
// получаем изображение в серых тонах
Test() : ima(240,320,CV_8U,cv::Scalar(100)) {}
// метод возвращает атрибут класса, но это нехорошая идея
cv::Mat method() { return ima; }
};
Здесь, если функция вызывает метод этого класса, он получи поверхностную копию атрибутов изображения. Если потом, это копия будет изменена, то атрибут класса также изменится, что может повлиять на последующее поведение этого класса(и наоборот). Чтобы избежать этих ошибок, вам вместо этого нужно вернуть копию этого атрибута.
И ещё кое-что...
С появлением версии 2 OpenCV был представлен новый интерфейс. До этого использовались си-подобные функции и структуры(и все ещё могут использоваться. В частности изображениями можно управлять с помощью структуры. Эта структуры наследуется от библиотеки IPL(это Intel Image Processing Library), теперь интегрированная с библиотекой IPP( Intel Integrated Performance Primitive library). Если вы используете код или библиотеки, созданные с помощью старого интерфейса Си, то вам должно быть было необходимо управлять этими структурами IplImage. К счастью существует удобный способ преобразовать структуру IplImage в объект cv::Mat.
IplImage* iplImage = cvLoadImage("c:\\img.jpg");
cv::Mat image4(iplImage,false);
Функция cvLoadImage - это функция си-интерфейса для загрузки изображений. Второй параметр конструктор объекта cv::Mat показывает, что данные не будут скопированы (установите его значение true, если вам нужна новая копия, а значение false можно пропустить потому, что но стоит по-умолчанию), тогда и IplImage, и image4 будут разделять между собой одни и те же данные изображения. Вам нужно быть осторожным, если вы не хотите наделать висячих ссылок. По этой причине, безопаснее инкапсулировать указатель IplImage в ссылочный класс считающий указатели, предоставляемый в OpenCV 2:
cv::Ptr<IplImage> iplImage = cvLoadImage("c:\\img.jpg");
Другими словами, если вам нужно разыменовать указатель на структуру IplImage, тогда вам нужно делать это явно:
cvReleaseImage(&iplImage);
Помните, что вам следует избегать использовать устаревшую структуру данных. Всегда используйте cv::Mat напротив.
Создание графического интерфейса пользователя GUI с помощью библиотеки Qt
Qt предоставляет богатую библиотеку, чтобы построить изощрённый графический интерфейс с профессиональным видом. С помощью Qt Creator процесс создания GUI стал простым. Этот рецет покажет вам как построить и создать приложение OpenCV с помощью Qt так, чтобы пользователь мог управлять используя GUI.
Подготавливаемся
Запускаем Qt Creator, который будем используем для создания GUI приложения. Также можно создать GUI приложение без этого инструмента, но использование графической IDE, в которые виджеты можно просто drag'n'drop'ать самый простой способ создать хорошо выглядящий GUI.
Как это сделать...
Выберети в меню Создать новый проект(Create New Project),
и там выберете Qt GUI Application как на следующем скриншоте:
Задайте имя и место расположения вашего проекта. Если вы затем нажмёте кнопку Next, то увидите что модуль QtGUI проверяется. Так как на не нужно больше других модулей, то поэтому вы можете нажать Finish . Таким образом вы создадите новый проект. Кроме того, чтобы использовать файл проекта ( .pro) и файл main.cpp , вы увидите два файла главных окон (mainwindow), определяющих класс, который содержит ваше GUI окно. Вы также найдёте файл у которого расширение .ui, то самое которое описывает UI вывод(layout). На самом деле, если два раза по нему нажмёте правой кнопкой мыши, то увидите текущий интерфейс как представлено здесь:
Также вы можете сюда drag-and-drop'нуть (перетащить) различные виджеты. Положите две кнопки Push, как мы делали в предыдущем премере. Вы можете изменить их размер, и изменить размер окна, чтобы он выглядел хорошо. Вам также следует переименовать кнопки label. Просто нажмите на мышку и вставьте любое имя по вашему выбору.
Добавим теперь сигнальный метод, чтобы управлять событием нажатия на кнопку. Нажмите на правую кнопку мыши по первой кнопке и выберете пункт Go to slot... в контекстном меню. Список возможных сигналов выводится на экран так как показано на следующем скриншоте:
Просто выберете сигнал clicked(). Он управляет событием нажатия кнопки. Когда вы это сделаете, тогда вас перенесёт в файл mainwindow.cpp. Это метод слота, который вызывается при получении сигнала click():
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
}
Чтобы иметь возможность вывести изображение на экран и затем провести какое-то преобразование над ним, нам нужно опредилить переменную-член класса cv::Mat. Это производится в заголовочном файле класса MainWindow. Так выглядит теперь заголовочный файл:
#include <QMainWindow>
#include <QFileDialog>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
cv::Mat image; // переменная с изображением
private slots:
void on_pushButton_clicked();
};
Отметим, что мы также включили заголовочные файлы core.hpp и highgui.hpp. Как мы уже выучили в предыдущем рецепте(практике), мы теперь должны забыть о том, чтобы редактировать файл проекта, чтобы добавить информацию библиотеки OpenCV.
OpenCV код может потом быть добавлен. Эта первая кнопка открывает исходное изображение. Это производится при добавлении следующего кода к связанному с ним методу слота:
void MainWindow::on_pushButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), ".",
tr("Image Files (*.png *.jpg *.jpeg *.bmp)"));
image= cv::imread(fileName.toAscii().data());
cv::namedWindow("Original Image");
cv::imshow("Original Image", image);
}
Вы можете создать новый слот, если нажмёте правой кнопкой мыши по второй кнопке. Этот второй слот произведет некоторые преобразования над выбранным входным изображением. Следующий код просто перевернёт изображение:
void MainWindow::on_pushButton_2_clicked()
{
cv::flip(image,image,1);
cv::namedWindow("Output Image");
cv::imshow("Output Image", image);
}
Теперь вы можете скомпилировать и запустить эту программу и ваш двухкнопочный графический интерфейс GUI позволит вам выбрать изображение и произвести над ним преобразования.
Входные и выходные изображения отображаются на двух окнах, выводящихся поверх экрана(highgui), которые мы определили.
Как это работает...
private slots:
void on_pushButton_clicked();
ui->pushButton_2->setEnabled(false);
if (image.data) {
ui->pushButton_2->setEnabled(true);
}
Более...
void MainWindow::on_pushButton_2_clicked()
{
cv::flip(image,image,1); // обрабатываем изображение
// выбираем цветовой канал
cv::cvtColor(image,image,CV_BGR2RGB);
// Qt изображение
QImage img= QImage((const unsigned char*)(image.data),
image.cols,image.rows,QImage::Format_RGB888);
// отображаем на Qlabel
ui->label->setPixmap(QPixmap::fromImage(img));
// изменяем размеры под размер картинки
ui->label->resize(ui->label->pixmap()->size());
}
Так же смотрите
Внимание! Этот перевод, возможно, ещё не готов.
Его статус: идёт перевод
Переведено на Нотабеноиде
http://notabenoid.org/book/41764/159312
Переводчики: oneassasin, Basya_sof, wuffur, Mellorn
Genfilf
Настройки
Готово:
