Skip to content

Commit

Permalink
Doing some config for core module
Browse files Browse the repository at this point in the history
  • Loading branch information
SamFlt committed Nov 28, 2023
1 parent 129320d commit 39f248f
Show file tree
Hide file tree
Showing 3 changed files with 341 additions and 2 deletions.
2 changes: 2 additions & 0 deletions modules/python/bindings/include/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@
#include "core/arrays.hpp"
#include "core/images.hpp"
#include "core/pixel_meter.hpp"
#include "core/image_conversions.hpp"


#endif
205 changes: 205 additions & 0 deletions modules/python/bindings/include/core/image_conversions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/*
* ViSP, open source Visual Servoing Platform software.
* Copyright (C) 2005 - 2023 by Inria. All rights reserved.
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file LICENSE.txt at the root directory of this source
* distribution for additional information about the GNU GPL.
*
* For using ViSP with software that can not be combined with the GNU
* GPL, please contact Inria about acquiring a ViSP Professional
* Edition License.
*
* See https://visp.inria.fr for more information.
*
* This software was developed at:
* Inria Rennes - Bretagne Atlantique
* Campus Universitaire de Beaulieu
* 35042 Rennes Cedex
* France
*
* If you have questions regarding the use of this file, please contact
* Inria at [email protected]
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Description:
* Python bindings.
*/

#ifndef VISP_PYTHON_CORE_IMAGE_CONVERT_HPP
#define VISP_PYTHON_CORE_IMAGE_CONVERT_HPP

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

#include <visp3/core/vpImageConvert.h>

namespace
{
using ConversionFunction1D = void(*)(unsigned char *, unsigned char *, unsigned int);
using ConversionFunction2D = void(*)(unsigned char *, unsigned char *, unsigned int, unsigned int);
using ComputeBytesFunction = unsigned(*)(unsigned int, unsigned int);

void call_conversion_fn(ConversionFunction2D fn, unsigned char *src, unsigned char *dest, unsigned int h, unsigned int w)
{
fn(src, dest, h, w);
}
void call_conversion_fn(ConversionFunction1D fn, unsigned char *src, unsigned char *dest, unsigned int h, unsigned int w)
{
fn(src, dest, h * w);
}

template <typename ConversionFn>
struct SimpleConversionStruct
{
SimpleConversionStruct(const std::string &name, ConversionFn fn, unsigned int srcBytesPerPixel, unsigned int destBytesPerPixel) :
name(name), fn(fn), srcBytesPerPixel(srcBytesPerPixel), destBytesPerPixel(destBytesPerPixel)
{ }
std::string name;
ConversionFn fn;
unsigned int srcBytesPerPixel;
unsigned int destBytesPerPixel;

void add_conversion_binding(py::class_<vpImageConvert> &pyImageConvert)
{
pyImageConvert.def_static(name.c_str(), [this](py::array_t<unsigned char, py::array::c_style> &src,
py::array_t<unsigned char, py::array::c_style> &dest) {
py::buffer_info bufsrc = src.request(), bufdest = dest.request();
if (bufsrc.ndim < 2 || bufdest.ndim < 2) {
throw std::runtime_error("Expected to have src and dest arrays with at least two dimensions.");
}
if (bufsrc.shape[0] != bufdest.shape[0] || bufsrc.shape[1] != bufdest.shape[1]) {
std::stringstream ss;
ss << "src and dest must have the same number of pixels, but got src = " << shape_to_string(bufsrc.shape);
ss << "and dest = " << shape_to_string(bufdest.shape);
throw std::runtime_error(ss.str());
}
if (srcBytesPerPixel > 1 && (bufsrc.ndim != 3 || bufsrc.shape[2] != srcBytesPerPixel)) {
std::stringstream ss;
ss << "Source array should be a 3D array of shape (H, W, " << srcBytesPerPixel << ")";
throw std::runtime_error(ss.str());
}
else if (srcBytesPerPixel == 1 && bufsrc.ndim == 3 && bufsrc.shape[2] > 1) {
throw std::runtime_error("Source array should be a either a 2D array of shape H x W or a 3D array of shape (H, W, 1)");
}
if (destBytesPerPixel > 1 && (bufdest.ndim != 3 || bufdest.shape[2] != destBytesPerPixel)) {
std::stringstream ss;
ss << "Destination array should be a 3D array of shape (H, W, " << destBytesPerPixel << ")";
throw std::runtime_error(ss.str());
}
else if (destBytesPerPixel == 1 && bufdest.ndim == 3 && bufdest.shape[2] > 1) {
throw std::runtime_error("Destination should be a either a 2D array of shape H x W or a 3D array of shape (H, W, 1)");
}


unsigned char *src_ptr = static_cast<unsigned char *>(bufsrc.ptr);
unsigned char *dest_ptr = static_cast<unsigned char *>(bufdest.ptr);
call_conversion_fn(fn, src_ptr, dest_ptr, bufsrc.shape[0], bufsrc.shape[1]);
}, py::arg("src"), py::arg("dest"));
}

};

struct ConversionFromYUVLike
{
ConversionFromYUVLike(const std::string &name, ConversionFunction2D fn, ComputeBytesFunction sourceBytesFn, unsigned int destBytesPerPixel) :
name(name), fn(fn), , destBytesPerPixel(destBytesPerPixel)
{ }
std::string name;
ConversionFunction2D fn;
ComputeBytesFunction sourceBytesFn;

unsigned int destBytesPerPixel;

void add_conversion_binding(py::class_<vpImageConvert> &pyImageConvert)
{
pyImageConvert.def_static(name.c_str(), [this](py::array_t<unsigned char, py::array::c_style> &src,
py::array_t<unsigned char, py::array::c_style> &dest) {
py::buffer_info bufsrc = src.request(), bufdest = dest.request();
if (bufdest.ndim < 2) {
throw std::runtime_error("Expected to have dest array with at least two dimensions.");
}

unsigned int height = bufdest.shape[0], width = bufdest.shape[1];

unsigned expectedSourceBytes = sourceBytesFn(height, width);

unsigned actualBytes = 1;
for (unsigned int i = 0; i < bufsrc.ndim; ++i) {
actualBytes *= bufsrc.shape[i];
}

if (actualBytes != expectedSourceBytes) {
std::stringstream ss;
ss << "Expected to have " << expectedSourceBytes << " bytes in the input array, but got " << actualBytes << " elements.";
throw std::runtime_error(ss.str());
}

if (destBytesPerPixel > 1 && (bufdest.ndim != 3 || bufdest.shape[2] != destBytesPerPixel)) {
std::stringstream ss;
ss << "Destination array should be a 3D array of shape (H, W, " << destBytesPerPixel << ")";
throw std::runtime_error(ss.str());
}
else if (destBytesPerPixel == 1 && bufdest.ndim == 3 && bufdest.shape[2] > 1) {
throw std::runtime_error("Destination should be a either a 2D array of shape H x W or a 3D array of shape (H, W, 1)");
}


unsigned char *src_ptr = static_cast<unsigned char *>(bufsrc.ptr);
unsigned char *dest_ptr = static_cast<unsigned char *>(bufdest.ptr);
call_conversion_fn(fn, src_ptr, dest_ptr, bufdest.shape[0], bufdest.shape[1]);
}, py::arg("src"), py::arg("dest"));
}

};



}



void bindings_vpImageConvert(py::class_<vpImageConvert> &pyImageConvert)
{
// Simple conversions where the size input is a single argument
{
std::vector<SimpleConversionStruct<ConversionFunction1D>> conversions = {
SimpleConversionStruct("YUV444ToGrey", &vpImageConvert::YUV444ToGrey, 3, 1),
SimpleConversionStruct("YUV444ToRGB", &vpImageConvert::YUV444ToRGB, 3, 3),
SimpleConversionStruct("YUV444ToRGBa", &vpImageConvert::YUV444ToRGBa, 3, 4),
SimpleConversionStruct("RGBToRGBa", static_cast<ConversionFunction1D>(&vpImageConvert::RGBToRGBa), 3, 4),
SimpleConversionStruct("RGBaToRGB", &vpImageConvert::RGBaToRGB, 4, 3),
SimpleConversionStruct("GreyToRGB", &vpImageConvert::GreyToRGB, 1, 3),
SimpleConversionStruct("GreyToRGBa", static_cast<ConversionFunction1D>(&vpImageConvert::GreyToRGBa), 1, 4)
};
for (auto &conversion: conversions) {
conversion.add_conversion_binding(pyImageConvert);
}
}
//Simple conversions where the size input are height and width
{
std::vector<SimpleConversionStruct<ConversionFunction2D>> conversions = {
};
for (auto &conversion: conversions) {
conversion.add_conversion_binding(pyImageConvert);
}
}
//YUV conversions
{
std::vector<SimpleConversionStruct<ConversionFunction2D>> conversions = {
};
for (auto &conversion: conversions) {
conversion.add_conversion_binding(pyImageConvert);
}
}


}

#endif
136 changes: 134 additions & 2 deletions modules/python/config/core.json
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,116 @@
}
]
},

"vpImageConvert": {
"additional_bindings": "bindings_vpImageConvert",
"methods":
[
{
"static": true,
"signature": "void RGBaToRGB(unsigned char*, unsigned char*, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void RGBToRGBa(unsigned char*, unsigned char*, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void RGBToRGBa(unsigned char*, unsigned char*, unsigned int, unsigned int, bool)",
"ignore": true
},
{
"static": true,
"signature": "void YUV444ToRGBa(unsigned char*, unsigned char*, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void YUV444ToRGB(unsigned char*, unsigned char*, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void YUV444ToGrey(unsigned char*, unsigned char*, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void GreyToRGBa(unsigned char*, unsigned char*, unsigned int, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void GreyToRGBa(unsigned char*, unsigned char*, unsigned int)",
"ignore": true
},
{
"static": true,
"signature": "void GreyToRGB(unsigned char*, unsigned char*, unsigned int, unsigned int)",
"ignore": true
}
]
},
"vpConvert": {
"methods": [
{
"static": true,
"signature": "void convertToOpenCV(const std::vector<vpPoint>&, std::vector<cv::Point3d>&, bool)",
"ignore" :true
},
{
"static": true,
"signature": "void convertToOpenCV(const std::vector<vpPoint>&, std::vector<cv::Point3f>&, bool)",
"ignore" :true
},
{
"static": true,
"signature": "void convertToOpenCV(const std::vector<vpImagePoint>&, std::vector<cv::Point2d>&)",
"ignore" :true
},
{
"static": true,
"signature": "void convertToOpenCV(const std::vector<vpImagePoint>&, std::vector<cv::Point2f>&)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::DMatch>&, std::vector<unsigned int>&)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::DMatch>&, std::vector<unsigned int>&)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::Point3d>&, std::vector<vpPoint>&, bool)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::Point3f>&, std::vector<vpPoint>&, bool)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::Point2d>&, std::vector<vpImagePoint>&)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::Point2f>&, std::vector<vpImagePoint>&)",
"ignore": true
},
{
"static": true,
"signature": "void convertFromOpenCV(const std::vector<cv::KeyPoint>&, std::vector<vpImagePoint>&)",
"ignore": true
}
]
},
"vpDisplay": {
"methods":
[
Expand Down Expand Up @@ -361,14 +470,37 @@
},
"vpMomentDatabase": {
"methods": [

{
"static": false,
"signature": "const vpMoment& get(const std::string&, bool&)",
"use_default_param_policy": false,
"param_is_input": [
true,
false
],
"param_is_output": [
false,
true
]
}
]
},
"vpPixelMeterConversion": {
"additional_bindings": "bindings_vpPixelMeterConversion"
},
"vpMeterPixelConversion": {
"additional_bindings": "bindings_vpMeterPixelConversion"
},
"vpCircle": {
"methods": [
{
"static": true,
"signature": "void computeIntersectionPoint(const vpCircle&, const vpCameraParameters&, const double&, const double&, double&, double&)",
"use_default_param_policy": false,
"param_is_input": [true, true, true, true, false, false],
"param_is_output": [false, false, false, false, true, true]
}
]
}

}
Expand Down

0 comments on commit 39f248f

Please sign in to comment.