open source pkg v1
This commit is contained in:
419
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/numpy_image.h
vendored
Normal file
419
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/numpy_image.h
vendored
Normal file
@@ -0,0 +1,419 @@
|
||||
// Copyright (C) 2014 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_PYTHON_NuMPY_IMAGE_Hh_
|
||||
#define DLIB_PYTHON_NuMPY_IMAGE_Hh_
|
||||
|
||||
#include <dlib/algs.h>
|
||||
#include <dlib/error.h>
|
||||
#include <dlib/matrix.h>
|
||||
#include <dlib/pixel.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <dlib/image_transforms/assign_image.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename pixel_type
|
||||
>
|
||||
bool is_image (
|
||||
const py::array& img
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
- returns true if and only if the given python numpy array can reasonably be
|
||||
interpreted as an image containing pixel_type pixels.
|
||||
!*/
|
||||
{
|
||||
using basic_pixel_type = typename pixel_traits<pixel_type>::basic_pixel_type;
|
||||
const size_t expected_channels = pixel_traits<pixel_type>::num;
|
||||
|
||||
const bool has_correct_number_of_dims = (img.ndim()==2 && expected_channels==1) ||
|
||||
(img.ndim()==3 && img.shape(2)==expected_channels);
|
||||
|
||||
return img.dtype().kind() == py::dtype::of<basic_pixel_type>().kind() &&
|
||||
img.itemsize() == sizeof(basic_pixel_type) &&
|
||||
has_correct_number_of_dims;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename pixel_type
|
||||
>
|
||||
void assert_correct_num_channels_in_image (
|
||||
const py::array& img
|
||||
)
|
||||
{
|
||||
const size_t expected_channels = pixel_traits<pixel_type>::num;
|
||||
if (expected_channels == 1)
|
||||
{
|
||||
if (!(img.ndim() == 2 || (img.ndim()==3&&img.shape(2)==1)))
|
||||
throw dlib::error("Expected a 2D numpy array, but instead got one with " + std::to_string(img.ndim()) + " dimensions.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (img.ndim() != 3)
|
||||
{
|
||||
throw dlib::error("Expected a numpy array with 3 dimensions, but instead got one with " + std::to_string(img.ndim()) + " dimensions.");
|
||||
}
|
||||
else if (img.shape(2) != expected_channels)
|
||||
{
|
||||
if (pixel_traits<pixel_type>::rgb)
|
||||
throw dlib::error("Expected a RGB image with " + std::to_string(expected_channels) + " channels but got an image with " + std::to_string(img.shape(2)) + " channels.");
|
||||
else
|
||||
throw dlib::error("Expected an image with " + std::to_string(expected_channels) + " channels but got an image with " + std::to_string(img.shape(2)) + " channels.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename pixel_type
|
||||
>
|
||||
void assert_is_image (
|
||||
const py::array& obj
|
||||
)
|
||||
{
|
||||
if (!is_image<pixel_type>(obj))
|
||||
{
|
||||
assert_correct_num_channels_in_image<pixel_type>(obj);
|
||||
|
||||
using basic_pixel_type = typename pixel_traits<pixel_type>::basic_pixel_type;
|
||||
const char expected_type = py::dtype::of<basic_pixel_type>().kind();
|
||||
const char got_type = obj.dtype().kind();
|
||||
|
||||
const size_t expected_size = sizeof(basic_pixel_type);
|
||||
const size_t got_size = obj.itemsize();
|
||||
|
||||
auto toname = [](char type, size_t size) {
|
||||
if (type == 'i' && size == 1) return "int8";
|
||||
else if (type == 'i' && size == 2) return "int16";
|
||||
else if (type == 'i' && size == 4) return "int32";
|
||||
else if (type == 'i' && size == 8) return "int64";
|
||||
else if (type == 'u' && size == 1) return "uint8";
|
||||
else if (type == 'u' && size == 2) return "uint16";
|
||||
else if (type == 'u' && size == 4) return "uint32";
|
||||
else if (type == 'u' && size == 8) return "uint64";
|
||||
else if (type == 'f' && size == 4) return "float32";
|
||||
else if (type == 'd' && size == 8) return "float64";
|
||||
else DLIB_CASSERT(false, "unknown type");
|
||||
};
|
||||
|
||||
throw dlib::error("Expected numpy array with elements of type " + std::string(toname(expected_type,expected_size)) + " but got " + toname(got_type, got_size) + ".");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename pixel_type
|
||||
>
|
||||
class numpy_image : public py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON pixel_type
|
||||
- is a dlib pixel type, this just means that dlib::pixel_traits<pixel_type>
|
||||
is defined.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is an image object that implements dlib's generic image interface and
|
||||
is backed by a numpy array. It therefore is easily interchanged with
|
||||
python since there is no copying. It is functionally just a pybind11
|
||||
array_t object with the additional routines needed to conform to dlib's
|
||||
generic image API. It also includes appropriate runtime checks to make
|
||||
sure that the numpy array is always typed and sized appropriately relative
|
||||
to the supplied pixel_type.
|
||||
!*/
|
||||
public:
|
||||
|
||||
numpy_image() = default;
|
||||
|
||||
numpy_image(
|
||||
const py::array& img
|
||||
) : py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>(img)
|
||||
{
|
||||
assert_is_image<pixel_type>(img);
|
||||
}
|
||||
|
||||
numpy_image (
|
||||
const py::object& img
|
||||
)
|
||||
{
|
||||
py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style> arr = img.cast<py::array>();
|
||||
assert_is_image<pixel_type>(arr);
|
||||
py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>::operator=(arr);
|
||||
}
|
||||
|
||||
numpy_image(
|
||||
const numpy_image& img
|
||||
) : py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>(img)
|
||||
{
|
||||
}
|
||||
|
||||
numpy_image& operator= (
|
||||
const py::object& rhs
|
||||
)
|
||||
{
|
||||
py::array arr = rhs.cast<py::array>();
|
||||
assert_is_image<pixel_type>(arr);
|
||||
py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>::operator=(arr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
numpy_image& operator= (
|
||||
const py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>& rhs
|
||||
)
|
||||
{
|
||||
assert_is_image<pixel_type>(rhs);
|
||||
py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>::operator=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
numpy_image& operator= (
|
||||
const numpy_image& rhs
|
||||
)
|
||||
{
|
||||
py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style>::operator=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
numpy_image (
|
||||
matrix<pixel_type>&& rhs
|
||||
)
|
||||
{
|
||||
*this = convert_to_numpy(std::move(rhs));
|
||||
}
|
||||
|
||||
numpy_image& operator= (
|
||||
matrix<pixel_type>&& rhs
|
||||
)
|
||||
{
|
||||
*this = convert_to_numpy(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set_size(size_t rows, size_t cols)
|
||||
{
|
||||
using basic_pixel_type = typename pixel_traits<pixel_type>::basic_pixel_type;
|
||||
constexpr size_t channels = pixel_traits<pixel_type>::num;
|
||||
if (channels != 1)
|
||||
*this = py::array_t<basic_pixel_type, py::array::c_style>({rows, cols, channels});
|
||||
else
|
||||
*this = py::array_t<basic_pixel_type, py::array::c_style>({rows, cols});
|
||||
}
|
||||
|
||||
private:
|
||||
static py::array_t<typename pixel_traits<pixel_type>::basic_pixel_type, py::array::c_style> convert_to_numpy(matrix<pixel_type>&& img)
|
||||
{
|
||||
using basic_pixel_type = typename pixel_traits<pixel_type>::basic_pixel_type;
|
||||
const size_t dtype_size = sizeof(basic_pixel_type);
|
||||
const auto rows = static_cast<const size_t>(num_rows(img));
|
||||
const auto cols = static_cast<const size_t>(num_columns(img));
|
||||
const size_t channels = pixel_traits<pixel_type>::num;
|
||||
const size_t image_size = dtype_size * rows * cols * channels;
|
||||
|
||||
std::unique_ptr<pixel_type[]> arr_ptr = img.steal_memory();
|
||||
basic_pixel_type* arr = (basic_pixel_type *) arr_ptr.release();
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
return pybind11::template array_t<basic_pixel_type, py::array::c_style>(
|
||||
{rows, cols}, // shape
|
||||
{dtype_size*cols, dtype_size}, // strides
|
||||
arr, // pointer
|
||||
pybind11::capsule{ arr, [](void *arr_p) { delete[] reinterpret_cast<basic_pixel_type*>(arr_p); } }
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pybind11::template array_t<basic_pixel_type, py::array::c_style>(
|
||||
{rows, cols, channels}, // shape
|
||||
{dtype_size * cols * channels, dtype_size * channels, dtype_size}, // strides
|
||||
arr, // pointer
|
||||
pybind11::capsule{ arr, [](void *arr_p) { delete[] reinterpret_cast<basic_pixel_type*>(arr_p); } }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename pixel_type>
|
||||
void assign_image (
|
||||
numpy_image<pixel_type>& dest,
|
||||
const py::array& src
|
||||
)
|
||||
{
|
||||
if (is_image<pixel_type>(src)) dest = src;
|
||||
else if (is_image<uint8_t>(src)) assign_image(dest, numpy_image<uint8_t>(src));
|
||||
else if (is_image<uint16_t>(src)) assign_image(dest, numpy_image<uint16_t>(src));
|
||||
else if (is_image<uint32_t>(src)) assign_image(dest, numpy_image<uint32_t>(src));
|
||||
else if (is_image<uint64_t>(src)) assign_image(dest, numpy_image<uint64_t>(src));
|
||||
else if (is_image<int8_t>(src)) assign_image(dest, numpy_image<int8_t>(src));
|
||||
else if (is_image<int16_t>(src)) assign_image(dest, numpy_image<int16_t>(src));
|
||||
else if (is_image<int32_t>(src)) assign_image(dest, numpy_image<int32_t>(src));
|
||||
else if (is_image<int64_t>(src)) assign_image(dest, numpy_image<int64_t>(src));
|
||||
else if (is_image<float>(src)) assign_image(dest, numpy_image<float>(src));
|
||||
else if (is_image<double>(src)) assign_image(dest, numpy_image<double>(src));
|
||||
else if (is_image<rgb_pixel>(src)) assign_image(dest, numpy_image<rgb_pixel>(src));
|
||||
else DLIB_CASSERT(false, "Unsupported pixel type used in assign_image().");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// BORING IMPLEMENTATION STUFF
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename pixel_type>
|
||||
long num_rows(const numpy_image<pixel_type>& img)
|
||||
{
|
||||
if (img.size()==0)
|
||||
return 0;
|
||||
|
||||
assert_correct_num_channels_in_image<pixel_type>(img);
|
||||
return img.shape(0);
|
||||
}
|
||||
|
||||
template <typename pixel_type>
|
||||
long num_columns(const numpy_image<pixel_type>& img)
|
||||
{
|
||||
if (img.size()==0)
|
||||
return 0;
|
||||
|
||||
assert_correct_num_channels_in_image<pixel_type>(img);
|
||||
return img.shape(1);
|
||||
}
|
||||
|
||||
template <typename pixel_type>
|
||||
void set_image_size(numpy_image<pixel_type>& img, size_t rows, size_t cols)
|
||||
{
|
||||
img.set_size(rows, cols);
|
||||
}
|
||||
|
||||
template <typename pixel_type>
|
||||
void* image_data(numpy_image<pixel_type>& img)
|
||||
{
|
||||
if (img.size()==0)
|
||||
return 0;
|
||||
|
||||
assert_is_image<pixel_type>(img);
|
||||
return img.mutable_data(0);
|
||||
}
|
||||
|
||||
template <typename pixel_type>
|
||||
const void* image_data (const numpy_image<pixel_type>& img)
|
||||
{
|
||||
if (img.size()==0)
|
||||
return 0;
|
||||
|
||||
assert_is_image<pixel_type>(img);
|
||||
return img.data(0);
|
||||
}
|
||||
|
||||
template <typename pixel_type>
|
||||
long width_step (const numpy_image<pixel_type>& img)
|
||||
{
|
||||
if (img.size()==0)
|
||||
return 0;
|
||||
|
||||
assert_correct_num_channels_in_image<pixel_type>(img);
|
||||
using basic_pixel_type = typename pixel_traits<pixel_type>::basic_pixel_type;
|
||||
if (img.ndim()==3 && img.strides(2) != sizeof(basic_pixel_type))
|
||||
throw dlib::error("The stride of the 3rd dimension (the channel dimension) of the numpy array must be " + std::to_string(sizeof(basic_pixel_type)));
|
||||
if (img.strides(1) != sizeof(pixel_type))
|
||||
throw dlib::error("The stride of the 2nd dimension (the columns dimension) of the numpy array must be " + std::to_string(sizeof(pixel_type)));
|
||||
|
||||
return img.strides(0);
|
||||
}
|
||||
|
||||
template <typename pixel_type>
|
||||
void swap(numpy_image<pixel_type>& a, numpy_image<pixel_type>& b)
|
||||
{
|
||||
std::swap(a,b);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct image_traits<numpy_image<T>>
|
||||
{
|
||||
typedef T pixel_type;
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace pybind11
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename pixel_type> struct handle_type_name<dlib::numpy_image<pixel_type>>
|
||||
{
|
||||
using basic_pixel_type = typename dlib::pixel_traits<pixel_type>::basic_pixel_type;
|
||||
|
||||
static PYBIND11_DESCR name() {
|
||||
constexpr size_t channels = dlib::pixel_traits<pixel_type>::num;
|
||||
if (channels == 1)
|
||||
return _("numpy.ndarray[(rows,cols),") + npy_format_descriptor<basic_pixel_type>::name() + _("]");
|
||||
else if (channels == 2)
|
||||
return _("numpy.ndarray[(rows,cols,2),") + npy_format_descriptor<basic_pixel_type>::name() + _("]");
|
||||
else if (channels == 3)
|
||||
return _("numpy.ndarray[(rows,cols,3),") + npy_format_descriptor<basic_pixel_type>::name() + _("]");
|
||||
else if (channels == 4)
|
||||
return _("numpy.ndarray[(rows,cols,4),") + npy_format_descriptor<basic_pixel_type>::name() + _("]");
|
||||
else
|
||||
DLIB_CASSERT(false,"unsupported pixel type");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename pixel_type>
|
||||
struct pyobject_caster<dlib::numpy_image<pixel_type>> {
|
||||
using type = dlib::numpy_image<pixel_type>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
// If passed a tuple where the first element of the tuple is a valid
|
||||
// numpy_image then bind the numpy_image to that element of the tuple.
|
||||
// We do this because there is a pattern of returning an image and some
|
||||
// associated metadata. This allows the returned tuple from such functions
|
||||
// to also be treated as an image without needing to unpack the first
|
||||
// argument.
|
||||
if (PyTuple_Check(src.ptr()) && PyTuple_Size(src.ptr()) >= 1)
|
||||
src = reinterpret_borrow<py::tuple>(src)[0];
|
||||
|
||||
if (!type::check_(src))
|
||||
return false;
|
||||
// stash the output of ensure into a temp variable since assigning it to
|
||||
// value (the member variable created by the PYBIND11_TYPE_CASTER)
|
||||
// apparently causes the return bool value to be ignored?
|
||||
auto temp = type::ensure(src);
|
||||
if (!dlib::is_image<pixel_type>(temp))
|
||||
return false;
|
||||
value = temp;
|
||||
return static_cast<bool>(value);
|
||||
}
|
||||
|
||||
static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
return src.inc_ref();
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // DLIB_PYTHON_NuMPY_IMAGE_Hh_
|
||||
|
||||
17
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/pyassert.h
vendored
Normal file
17
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/pyassert.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_PYaSSERT_Hh_
|
||||
#define DLIB_PYaSSERT_Hh_
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
#define pyassert(_exp,_message) \
|
||||
{if ( !(_exp) ) \
|
||||
{ \
|
||||
namespace py = pybind11; \
|
||||
PyErr_SetString( PyExc_ValueError, _message ); \
|
||||
throw py::error_already_set(); \
|
||||
}}
|
||||
|
||||
#endif // DLIB_PYaSSERT_Hh_
|
||||
|
||||
105
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/pybind_utils.h
vendored
Normal file
105
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/pybind_utils.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_PYBIND_UtILS_Hh_
|
||||
#define DLIB_PYBIND_UtILS_Hh_
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <dlib/serialize.h>
|
||||
#include <array>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> python_list_to_vector (
|
||||
const py::list& obj
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
- converts a python object into a std::vector<T> and returns it.
|
||||
!*/
|
||||
{
|
||||
std::vector<T> vect(len(obj));
|
||||
for (unsigned long i = 0; i < vect.size(); ++i)
|
||||
{
|
||||
vect[i] = obj[i].cast<T>();
|
||||
}
|
||||
return vect;
|
||||
}
|
||||
|
||||
template <typename T,size_t N>
|
||||
std::array<T,N> python_list_to_array (
|
||||
const py::list& the_list
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
- converts a python object into a std::array<T,N> and returns it.
|
||||
!*/
|
||||
{
|
||||
DLIB_CASSERT(len(the_list) == N, "Expected a list of " << N << " things.");
|
||||
std::array<T,N> vect;
|
||||
for (unsigned long i = 0; i < vect.size(); ++i)
|
||||
{
|
||||
vect[i] = the_list[i].cast<T>();
|
||||
}
|
||||
return vect;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
py::list vector_to_python_list (
|
||||
const std::vector<T>& vect
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
- converts a std::vector<T> into a python list object.
|
||||
!*/
|
||||
{
|
||||
py::list obj;
|
||||
for (unsigned long i = 0; i < vect.size(); ++i)
|
||||
obj.append(vect[i]);
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void extend_vector_with_python_list (
|
||||
std::vector<T> &v,
|
||||
const py::list &l
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
- appends items from a python list to the end of std::vector<T>.
|
||||
!*/
|
||||
{
|
||||
for (const auto &item : l)
|
||||
v.push_back(item.cast<T>());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> load_object_from_file (
|
||||
const std::string& filename
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
- deserializes an object of type T from the given file and returns it.
|
||||
!*/
|
||||
{
|
||||
std::ifstream fin(filename.c_str(), std::ios::binary);
|
||||
if (!fin)
|
||||
throw dlib::error("Unable to open " + filename);
|
||||
auto obj = std::make_shared<T>();
|
||||
deserialize(*obj, fin);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif // DLIB_PYBIND_UtILS_Hh_
|
||||
|
||||
73
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/serialize_pickle.h
vendored
Normal file
73
pkg/OpenFace/lib/3rdParty/dlib/include/dlib/python/serialize_pickle.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SERIALIZE_PiCKLE_Hh_
|
||||
#define DLIB_SERIALIZE_PiCKLE_Hh_
|
||||
|
||||
#include <dlib/serialize.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <sstream>
|
||||
#include <dlib/vectorstream.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
py::tuple getstate(const T& item)
|
||||
{
|
||||
using namespace dlib;
|
||||
std::vector<char> buf;
|
||||
buf.reserve(5000);
|
||||
vectorstream sout(buf);
|
||||
serialize(item, sout);
|
||||
return py::make_tuple(py::handle(
|
||||
PyBytes_FromStringAndSize(buf.size()?&buf[0]:0, buf.size())));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T setstate(py::tuple state)
|
||||
{
|
||||
using namespace dlib;
|
||||
if (len(state) != 1)
|
||||
{
|
||||
PyErr_SetObject(PyExc_ValueError,
|
||||
py::str("expected 1-item tuple in call to __setstate__; got {}").format(state).ptr()
|
||||
);
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
// We used to serialize by converting to a str but the boost.python routines for
|
||||
// doing this don't work in Python 3. You end up getting an error about invalid
|
||||
// UTF-8 encodings. So instead we access the python C interface directly and use
|
||||
// bytes objects. However, we keep the deserialization code that worked with str
|
||||
// for backwards compatibility with previously pickled files.
|
||||
T item;
|
||||
py::object obj = state[0];
|
||||
if (py::isinstance<py::str>(obj))
|
||||
{
|
||||
py::str data = state[0].cast<py::str>();
|
||||
std::string temp = data;
|
||||
std::istringstream sin(temp);
|
||||
deserialize(item, sin);
|
||||
}
|
||||
else if(PyBytes_Check(py::object(state[0]).ptr()))
|
||||
{
|
||||
py::object obj = state[0];
|
||||
char* data = PyBytes_AsString(obj.ptr());
|
||||
unsigned long num = PyBytes_Size(obj.ptr());
|
||||
std::istringstream sin(std::string(data, num));
|
||||
deserialize(item, sin);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw error("Unable to unpickle, error in input file.");
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SERIALIZE_PiCKLE_Hh_
|
||||
|
||||
Reference in New Issue
Block a user