Commit e239e4bc authored by Baptiste Esteban's avatar Baptiste Esteban
Browse files

Continue python doc

parent ac0af663
Pipeline #27349 passed with stages
in 14 minutes and 16 seconds
Extend the ``pylena`` module
============================
Writing an extension module
===========================
When writing algorithms using the Pylene C++ library, it is possible to expand them in Python. Bellow is a detailed example of how to do it.
1. First, write a conanfile as bellow (it is minimal). It is important to set the pylene ``fPIC`` and ``python`` option to True. Else, the ``pylena_numpy`` library will not be available.
Step 1: Setup the project
--------------------------
.. code-block:: text
[generators]
cmake_find_package
cmake
[requires]
pylene/head@lrde/stable
pylene/head@lrde/unstable
pybind11/2.6.2
[options]
pylene:fPIC=True
pylene:python=True
2. Then, write a CMakeLists.txt. To use the pylena_numpy library, you should use the target ``Pylene::pylena_numpy``.
.. code-block:: cmake
cmake_minimum_required(VERSION 3.8.2)
project(pylena_ext)
cmake_minimum_required(VERSION 3.14)
project(pylene_extension)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} ${CMAKE_BINARY_DIR}")
if (EXISTS "${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo.cmake")
include("${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo.cmake")
conan_set_rpath()
endif()
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_BINARY_DIR}" "${CONAN_BUILD_DIRS_PYBIND11}")
find_package(Pylene REQUIRED)
find_package(pybind11 REQUIRED) # Using system pybind11 or conan one (in this case add it in the conanfile.txt)
pybind11_add_module(pylena_ext module.cpp)
target_link_libraries(pylena-ext PRIVATE Pylene::Pylene Pylene::pylena_numpy)
include(pybind11Install)
pybind11_add_module(pylene_extension)
target_sources(pylene_extension PRIVATE pylene_extension.cpp)
target_link_libraries(pylene_extension PUBLIC Pylene::Pylene-numpy)
3. Finally, bellow is an example of source code.
Step 2: Writing an extension
----------------------------
.. code-block:: cpp
#include <pln/core/image_cast.hpp> // Should be included in each Compile Unit
#include <pln/core/image_cast.hpp>
#include <mln/core/image/ndimage.hpp>
#include <mln/core/range/foreach.hpp>
mln::ndbuffer_image iota(/* arguments */)
{
mln::ndbuffer_image result;
/* Process iota */
#include <pybind11/pybind11.h>
return result;
}
#include <stdexcept>
PYBIND11_MODULE(pylena_ext, m)
void iota(mln::ndbuffer_image arg_img)
{
m.doc() = "This is an extension of the pylena module";
m.def("iota", &iota, "Return an image filled using the iota function");
auto img = arg_img.cast_to<std::uint8_t, 2>();
if (!img)
throw std::invalid_argument("iota: input image should be a 2D uint8 image");
std::uint8_t i = 0;
mln_foreach(auto p, img->domain())
{
(*img)(p) = i;
i = i == 255 ? 0 : i + 1;
}
}
This will give a python module named ``pylena-ext``.
PYBIND11_MODULE(pylene_extension, m)
{
pln::init_pylena_numpy(m);
m.def("iota", &iota);
}
>>> from pylena_ext import iota
>>> img = iota(...)
>>> type(img)
numpy.ndarray
Step 3: Using the extension
---------------------------
>>> from pylene_extension import iota
>>> import numpy as np
>>> img = np.zeros((10, 10)).astype(np.float64)
>>> iota(img)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: iota: input image should be a 2D uint8 image
>>> img = img.astype(np.uint8)
>>> iota(img)
>>> img
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]], dtype=uint8)
\ No newline at end of file
......@@ -6,13 +6,13 @@ The Pylene library makes possible to expose its features in Python. To this aim,
* The ``Pylene-numpy`` library, which converts Pylene images into Numpy arrays.
* The ``pylena`` module, which binds some Pylene algorithms in Python.
For instance, the ``pylena`` module is under development and is currently empty. However, it is possible to create
Currently, the ``pylena`` module is under development and is empty. However, it is possible to create
a Python module using `Pybind11 <https://pybind11.readthedocs.io>`_ and the ``Pylene-numpy`` library. This is described in the next section.
Installation
^^^^^^^^^^^^
Before continuing, it is advised to read this section about the Pylene installation.
Before continuing, it is advised to read :ref:doc:`this section</tutorial/installation>` about the Pylene installation.
This subsection describe how to get the ``Pylene-numpy`` library. Two methods are explained :
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment