Ответ 1
Вы уверены, что эта оживленная библиотека даже экспортирует привязки python? Я не вижу ссылки на него в исходном коде - он даже не импортирует файлы заголовков python. Это, безусловно, объяснит, почему у вас не было большого успеха до сих пор - вы не можете просто скомпилировать простой код на С++ и ожидать, что python будет взаимодействовать с ним.
Я думаю, что ваш второй пример distutils наиболее близок к исправлению - он, очевидно, компилирует вещи и переходит на этап компоновщика, но затем вы сталкиваетесь с этой ошибкой. Эта ошибка просто означает, что она не может найти функцию с именем initbrisk, которая, как я предполагаю, будет функцией init для верхнего уровня для модуля. Опять же, это говорит о том, что вы пытаетесь скомпилировать модуль python из кода, который не предназначен для него.
Если вы хотите обернуть код С++ в оболочку python, вы можете посмотреть официальную документацию по написанию расширений c/С++. В качестве альтернативы вы могли бы заглянуть в boost:: python, SIP или shiboken, которые пытаются (или полностью) автоматизировать процесс создания расширений python из кода С++.
EDIT: Поскольку вы, похоже, приложили немало усилий для решения проблемы самостоятельно и опубликовали хороший вопрос, я решил дать более подробный ответ о том, как это сделать.
Краткое руководство по облову библиотек С++ Использование boost:: python
Лично я когда-либо использовал boost:: python для таких вещей, поэтому я попытаюсь дать вам хорошее резюме о том, как это сделать. Я предполагаю, что вы используете Visual С++ 2010. Я также предполагаю, что у вас установлена 32-битная версия python, так как я полагаю, что библиотеки boost pro предоставляют только 32-битные файлы.
Установка boost
Сначала вам нужно будет захватить копию библиотеки boost. Самый простой способ сделать это - загрузить установщик из сайта pro pro. Они должны установить все файлы заголовков и двоичные файлы, необходимые для использования библиотеки boost С++ в Windows. Обратите внимание на то, где вы устанавливаете эти файлы, по мере необходимости в дальнейшем - лучше всего установить путь без пробела в нем. Для удобства я собираюсь предположить, что вы поместили эти файлы в C:\boost, но вы можете заменить это на тот путь, который вы фактически использовали.
В качестве альтернативы вы можете следить за этими инструкциями, чтобы увеличить форсирование из исходного кода. Я не уверен на 100%, но это может быть так, что вам нужно сделать это, чтобы получить версию boost:: python, совместимую с установленной версией python.
Настройка проекта визуальной студии
Далее вы хотите настроить визуальный проект студии для brisk.pyd. Если вы откроете визуальную студию, перейдите в New → Project, затем найдите вариант для Win32 Project. Настройте свое местоположение и т.д. И нажмите "ОК". В появившемся окне выберите тип проекта DLL, а затем отметьте флажок пустой проект.
Теперь, когда вы создали свой проект, вам нужно настроить пути include и library, чтобы вы могли использовать python, boost:: python и файл brisk.lib.
В Visual Studio Solution Explorer щелкните правой кнопкой мыши на своем проекте и выберите свойства из появившегося меню. Это должно открыть страницы свойств для вашего проекта. Перейдите в раздел Linker → General и найдите раздел дополнительных библиотек. Вам нужно будет заполнить это с помощью путей к файлам .lib
для boost, python и вашего brisk_static.lib
. Обычно их можно найти в подкаталогах lib
(или libs
)
где бы вы ни устанавливали библиотеки. Пути разделены точкой с запятой. Я добавил скриншот моих настроек ниже:
Затем вам нужно будет получить визуальную студию для ссылки на .lib файлы. Эти разделы можно найти в поле Дополнительные зависимости раздела Linker → Input свойств. Опять же, это список с разделителями с запятой. Вам нужно добавить библиотеки для python (в моем случае это python27.lib
, но это будет зависеть от версии) и brisk_static.lib
. Они не требуют полного пути, как вы добавили, что на предыдущем этапе. Снова, вот скриншот:
Вам также может потребоваться добавить файл библиотеки boost_python, но я думаю, что boost использует некоторую магию заголовка, чтобы избавить вас от неприятностей. Если я ошибаюсь, посмотрите, как вы увеличиваете путь библиотеки для файла с именем boost_python-vc100-mt.lib
и добавляете его.
Наконец, вам нужно настроить пути включения, чтобы ваш проект включал соответствующие файлы заголовков С++. Чтобы получить соответствующие параметры в свойствах проекта, вам нужно добавить файл .cpp в свой проект. Щелкните правой кнопкой мыши папку исходных файлов в вашем проводнике решений, а затем перейдите к добавлению нового элемента. Выберите файл С++ (.cpp) и назовите его main.cpp(или что-то еще, что вам нужно).
Затем вернитесь к своим свойствам проекта и перейдите к C/С++ → General. В каталоге дополнительных библиотек вам нужно добавить пути включения для быстрого, python и boost. Опять же, точки с запятой для разделителей, и снова вот скриншот:
Я подозреваю, что вам, возможно, потребуется обновить эти параметры, включив библиотеки opencv2 и agast, но я оставлю это как задачу для вас выяснить - это должен быть тот же процесс.
Обтекание существующих классов С++ с помощью boost:: python.
Теперь идет немного более сложный бит - на самом деле пишу С++, чтобы обернуть вашу оживленную библиотеку в boost python. Вы можете найти учебник для этого здесь, но я постараюсь и по нему немного поработать.
Это будет происходить в файле main.cpp
, который вы создали ранее. Во-первых, добавьте соответствующие инструкции include, которые вам понадобятся в верхней части файла:
#include <brisk/brisk.h>
#include <Python.h>
#include <boost/python.hpp>
Затем вам нужно будет объявить ваш модуль python. Я предполагаю, что вы хотите, чтобы это называлось оживленным, поэтому вы делаете что-то вроде этого:
BOOST_PYTHON_MODULE(brisk)
{
}
Это должно означать boost:: python для создания модуля python с именем brisk
.
Далее это всего лишь случай прохождения всех классов и структур, которые вы хотите обернуть, и объявления с ними классов python. Отклонения классов должны содержаться в brisk.h. Вы должны обернуть только публичных членов класса, а не защищенных или закрытых членов. В качестве краткого примера я сделал пару структур:
BOOST_PYTHON_MODULE(brisk)
{
using namespace boost::python;
class_< cv::BriskPatternPoint >( "BriskPatternPoint" )
.def_readwrite("x", &cv::BriskPatternPoint::x)
.def_readwrite("y", &cv::BriskPatternPoint::y)
.def_readwrite("sigma", &cv::BriskPatternPoint::sigma);
class< cv::BriskScaleSpace >( "BriskScaleSpace", init< uint8_t >() )
.def( "constructPyramid", &cv::BriskScaleSpace::constructPyramid );
}
Здесь я завернул структуру cv:: BriskPatternPoint и класс cv:: BriskScaleSpace. Несколько быстрых объяснений:
class_< cv::BriskPatternPoint >( "BriskPatternPoint" )
сообщает boost:: python объявлять класс, используя класс cv::BriskPatternPoint
С++, и выставлять его как BriskPatternPoint
в python.
.def_readwrite("y", &cv::BriskPatternPoint::y)
добавляет читаемое и записываемое свойство в класс BriskPatternPoint
. Свойство имеет имя y и будет отображаться в поле BriskPatternPoint::y
С++.
class< cv::BriskScaleSpace >( "BriskScaleSpace", init< uint8_t >() )
объявляет другой класс, на этот раз BriskScaleSpace
, но также предоставляет конструктор, который принимает uint8_t (unsigned byte - который должен просто сопоставлять целое число в python, но я был бы осторожен, чтобы не пройти один более 255 байт - я не знаю, что произойдет в этой ситуации)
Следующая строка .def
просто объявляет функцию-boost:: python должна (я думаю) иметь возможность автоматически определять типы аргументов функций, поэтому вам не нужно их предоставлять.
Возможно, стоит отметить, что я на самом деле не скомпилировал ни один из этих примеров - они могут вообще не работать.
В любом случае, чтобы полностью работать в python, это должен быть случай, когда вы выполняете аналогичные для каждой структуры, класса, свойства и функции, которые вы хотите получить с помощью python - это потенциально довольно трудоемкая задача!
Если вы хотите увидеть другой пример этого в действии, я сделал здесь, чтобы обернуть этот класс
Создание и использование расширения
Visual Studio должна позаботиться о создании расширения, а затем использовать его как раз для того, чтобы взять .DLL и переименовать его в .pyd(вы можете заставить VS сделать это за вас, но я оставлю это до вы).
Затем вам просто нужно скопировать файл python куда-нибудь по вашему пути python (например, site-packages
), импортировать его и использовать!
import brisk
patternPoint = brisk.BriskPatternPoint()
....
Во всяком случае, я провел час или около того, написав это, поэтому я остановлюсь здесь. Извиняюсь, если я что-то оставил, или если что-то неясно, но я делаю это в основном из памяти. Надеюсь, это помогло вам. Если вам нужно что-нибудь разъясненное, просто оставьте комментарий или задайте другой вопрос.