20 августа 2015 г.

Некоторые проблемы и их решения при работе с Unreal Engine 4, Visual Studio и OpenCV

Здесь я запишу, чтобы не забыть и, может быть, кому-нибудь помочь, как я решал те или иные проблемы, когда работал с UE 4.8.3 и Visual Studio 2013, подключая OpenCV.
Пусть вещи и тривиальные для тех, кто знает зачем нужны заголовочные файлы и что такое .lib-файлы и как работает LINK, но описывать я буду в формате "Ошибка - Решение", так как так проще искать решение.
Осторожно! Советы могут быть вредными, так как я новичок в C++ и UE4.


Update: Native Camera работает на Android только на некоторых устройствах. В версии OpenCV 3.0 от native camera отказались совсем.

1. Как подключить opencv в проект UE4

Полный гайд здесь - https://wiki.unrealengine.com/Integrating_OpenCV_Into_Unreal_Engine_4. Но тогда я его ещё не видел и шёл своим путём.

На данный момент мне удалось подключить только OpenCV версии 2.4. Версия 3 не работала.
Подключить получилось только через DLL-файлы.


Допустим, вы написали код в вашем UE4 проекте, который использует opencv.
Например, определили переменную
cv::Mat frame;
и использовали вызов
cv::cvtColor(img, img, CV_BGR2Luv);
Первым делом, редактор будет подчеркивать эти строки и писать ошибку
Mat: identifier not found
cvtColor: identifier not found
Это означает, что определения этих структур и функций не найдено. Чтобы решить эту проблему, нужно подключить правильный заголовочный файл (.h, .hpp), где они описаны. В нашем случае это 
opencv2/core/core.hpp
opencv2/highgui/highgui.hpp
Так как используемых библиотек из opencv у нас может быть много, удобнее указать базовый путь, где искать эти файлы и относительно него писать путь в #include. То есть, мы пишем:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
но путь до opencv2 будет определен из путей, которые описаны в конфигурации проекта. Эти файлы должны находится в дистрибутиве opencv примерно по следующему пути:
D:\...opencv...\build\include
Но есть два места, где этот путь стоит указать. Первое - это Properties у самого проекта в VS, там раздел VC++ Directories параметр Include Directories. Второе - это файл конфигурации сборки проекта, который имеет имя в таком формате:
Source/%имя_проекта%/%имя_проекта%.build.cs
Настройки из Properties использует редактор, чтобы помочь с синтаксическими ошибками и не подчеркивать красным пути до include-файлов, а настройки из файла build.cs используются, когда происходит сборка проекта. Поэтому в конструктор build.cs нужно добавить строку
PublicIncludePaths.Add("D:/...opencv.../build/include");


Если после этого попытаться собрать проект, то будет ошибка LINK:
symbol not found
Это означает, что не найдена реализация функций, которые описаны в заголовочных файлах. Их реализация находится в dll-файлах, но линковщику требуются еще и .lib-файлы, которые будут указывать, по какому адресу и в каком dll-файле находится реализация.
OpenCV содержит lib-файлы в директории build/Win64/vs12/lib, а dll в build/Win64/vs12/bin
В конфигурацию сборщика теперь нужно указать пути до конкретных lib-файлов, которые вы используете. Для этого добавьте в конструктор пути в следующем формате:
PublicAdditionalLibraries.Add("D:/...opencv.../build/Win64/vs12/lib/opencv_core2411.lib");
PublicAdditionalLibraries.Add("D:/...opencv.../build/Win64/vs12/lib/opencv_highgui2411.lib");
PublicAdditionalLibraries.Add("D:/...opencv.../build/Win64/vs12/lib/opencv_mgproc2411.lib");
Следует обратить внимание, что имя файлов может отличатся версией. Кроме того, следует разделять Win64 и Win32, а так же debug и release-версии. Удобный способ разделения в зависимости от таргет-платформы описан в гайде по ссылке выше. Я опишу только один случай, так как d-версии (debug) библиотек мне использовать не удалось.


Теперь можно попробовать собрать проект (Build). Одной из проблем может быть просто неудачная сборка без подробных объяснений и конкретных ошибок:
LNK1104: cannot open file
error: Failed to produce item
The command "... .uproject -rocket" exited with code 5. Please verify that you have sufficient rights to run this command.

Выглядит это так:





В моём случае это означало, что я сделал ошибки в файле конфигурации сборки build.cs. Переписав его с самого начала, ошибка исчезла и проект стал собираться.


Если вы запускаете сборку из VS с запуском проекта, то после успешной сборки начнется запуск редактора. При этом может возникнуть краш при загрузке модулей. В моём случае это было на 73% запуска редактора. Это означало, что dll-файлы opencv не были найдены. Сами файлы лежат в D:/...opencv.../build/Win64/vs12/bin. Есть минимум два решения подключения файлов:
1. Добавить в переменную окружения PATH путь до dll файлов opencv
2. Скопировать содержимое bin в папку Binaries вашего проекта, откуда происходит запуск редактора после сборки.
Я выбрал второй.

2. Решение проблемы краша при нажатии кнопки Play в редакторе

Если вы в проекте используете cv::findContours или другие функции OpenCV, которые имеют аргументы вида std::vector<std::vector<cv::Point>>, то скорее всего после запуска проекта он у вас вылетит с Access violation, а в журнале дебага после [External code] будет строка

void FMallocTBB::Free( void* Ptr )
Немного изучив этот вопрос, я пришел к выводу, что сборщик мусора (Garbage Collector), используемый в UE4 не может корректно отследить использование структур, нужных некоторым функциям OpenCV. Для того, чтобы спрятать такие структуры от сборщика мусора я вынес код, их использующий в отдельный новыq проект на Visual Studio и скомпилировал свою dll. Такая dll подключается аналогично библиотекам из OpenCV. То есть, добавляется путь до заголовочного файла вашего проекта и путь к .lib-файлу в build.cs, а dll копируется в Binaries проекта UE4.
При написании своей dll я пользовался руководством Walkthrough: Creating and Using a Dynamic Link Library (C++).


3 комментария:

  1. Раздражает что нельзя подключить VS2015 (((
    Я только начал изучать UE4 и плюсы, перехожу с пыхи(10 лет опыта)

    ОтветитьУдалить
  2. Hey, can you tell how exactly you included the lib in the build.cs and where you copied the dlls?

    ОтветитьУдалить
    Ответы
    1. http://blog.getid.org/2015/08/markersdetector-unreal-engine.html here I have described how to use my DLL in UE4. You can download ready project with build.cs and dll https://yadi.sk/d/y5euHnkEiuGHV

      If you need OpenCV only, you should look at this guide https://wiki.unrealengine.com/Integrating_OpenCV_Into_Unreal_Engine_4

      If you have another question, you are welcome.

      Удалить