├── .gitignore ├── 002053.jpg ├── Data ├── CClikelihood.mat ├── EDlikelihood.mat ├── MSlikelihood.mat ├── SSlikelihood.mat └── params.mat ├── LICENSE ├── c_segment ├── 002053.jpg ├── 002053.ppm ├── 002053_out.ppm ├── CMakeLists.txt ├── COPYING ├── Makefile ├── README ├── __init__.py ├── c_segment.py ├── convolve.h ├── disjoint-set.h ├── filter.h ├── image.h ├── imconv.h ├── imutil.h ├── interface.cpp ├── misc.h ├── pnmfile.h ├── pybind11 │ ├── .appveyor.yml │ ├── .gitignore │ ├── .gitmodules │ ├── .readthedocs.yml │ ├── .travis.yml │ ├── CMakeLists.txt │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ ├── LICENSE │ ├── MANIFEST.in │ ├── README.md │ ├── docs │ │ ├── Doxyfile │ │ ├── _static │ │ │ └── theme_overrides.css │ │ ├── advanced │ │ │ ├── cast │ │ │ │ ├── chrono.rst │ │ │ │ ├── custom.rst │ │ │ │ ├── eigen.rst │ │ │ │ ├── functional.rst │ │ │ │ ├── index.rst │ │ │ │ ├── overview.rst │ │ │ │ ├── stl.rst │ │ │ │ └── strings.rst │ │ │ ├── classes.rst │ │ │ ├── embedding.rst │ │ │ ├── exceptions.rst │ │ │ ├── functions.rst │ │ │ ├── misc.rst │ │ │ ├── pycpp │ │ │ │ ├── index.rst │ │ │ │ ├── numpy.rst │ │ │ │ ├── object.rst │ │ │ │ └── utilities.rst │ │ │ └── smart_ptrs.rst │ │ ├── basics.rst │ │ ├── benchmark.py │ │ ├── benchmark.rst │ │ ├── changelog.rst │ │ ├── classes.rst │ │ ├── compiling.rst │ │ ├── conf.py │ │ ├── faq.rst │ │ ├── index.rst │ │ ├── intro.rst │ │ ├── limitations.rst │ │ ├── pybind11-logo.png │ │ ├── pybind11_vs_boost_python1.png │ │ ├── pybind11_vs_boost_python1.svg │ │ ├── pybind11_vs_boost_python2.png │ │ ├── pybind11_vs_boost_python2.svg │ │ ├── reference.rst │ │ ├── release.rst │ │ ├── requirements.txt │ │ └── upgrade.rst │ ├── include │ │ └── pybind11 │ │ │ ├── attr.h │ │ │ ├── buffer_info.h │ │ │ ├── cast.h │ │ │ ├── chrono.h │ │ │ ├── common.h │ │ │ ├── complex.h │ │ │ ├── detail │ │ │ ├── class.h │ │ │ ├── common.h │ │ │ ├── descr.h │ │ │ ├── init.h │ │ │ ├── internals.h │ │ │ └── typeid.h │ │ │ ├── eigen.h │ │ │ ├── embed.h │ │ │ ├── eval.h │ │ │ ├── functional.h │ │ │ ├── iostream.h │ │ │ ├── numpy.h │ │ │ ├── operators.h │ │ │ ├── options.h │ │ │ ├── pybind11.h │ │ │ ├── pytypes.h │ │ │ ├── stl.h │ │ │ └── stl_bind.h │ ├── pybind11 │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── _version.py │ ├── setup.cfg │ ├── setup.py │ ├── tests │ │ ├── CMakeLists.txt │ │ ├── conftest.py │ │ ├── constructor_stats.h │ │ ├── local_bindings.h │ │ ├── object.h │ │ ├── pybind11_cross_module_tests.cpp │ │ ├── pybind11_tests.cpp │ │ ├── pybind11_tests.h │ │ ├── pytest.ini │ │ ├── test_buffers.cpp │ │ ├── test_buffers.py │ │ ├── test_builtin_casters.cpp │ │ ├── test_builtin_casters.py │ │ ├── test_call_policies.cpp │ │ ├── test_call_policies.py │ │ ├── test_callbacks.cpp │ │ ├── test_callbacks.py │ │ ├── test_chrono.cpp │ │ ├── test_chrono.py │ │ ├── test_class.cpp │ │ ├── test_class.py │ │ ├── test_cmake_build │ │ │ ├── CMakeLists.txt │ │ │ ├── embed.cpp │ │ │ ├── installed_embed │ │ │ │ └── CMakeLists.txt │ │ │ ├── installed_function │ │ │ │ └── CMakeLists.txt │ │ │ ├── installed_target │ │ │ │ └── CMakeLists.txt │ │ │ ├── main.cpp │ │ │ ├── subdirectory_embed │ │ │ │ └── CMakeLists.txt │ │ │ ├── subdirectory_function │ │ │ │ └── CMakeLists.txt │ │ │ ├── subdirectory_target │ │ │ │ └── CMakeLists.txt │ │ │ └── test.py │ │ ├── test_constants_and_functions.cpp │ │ ├── test_constants_and_functions.py │ │ ├── test_copy_move.cpp │ │ ├── test_copy_move.py │ │ ├── test_docstring_options.cpp │ │ ├── test_docstring_options.py │ │ ├── test_eigen.cpp │ │ ├── test_eigen.py │ │ ├── test_embed │ │ │ ├── CMakeLists.txt │ │ │ ├── catch.cpp │ │ │ ├── external_module.cpp │ │ │ ├── test_interpreter.cpp │ │ │ └── test_interpreter.py │ │ ├── test_enum.cpp │ │ ├── test_enum.py │ │ ├── test_eval.cpp │ │ ├── test_eval.py │ │ ├── test_eval_call.py │ │ ├── test_exceptions.cpp │ │ ├── test_exceptions.py │ │ ├── test_factory_constructors.cpp │ │ ├── test_factory_constructors.py │ │ ├── test_gil_scoped.cpp │ │ ├── test_gil_scoped.py │ │ ├── test_iostream.cpp │ │ ├── test_iostream.py │ │ ├── test_kwargs_and_defaults.cpp │ │ ├── test_kwargs_and_defaults.py │ │ ├── test_local_bindings.cpp │ │ ├── test_local_bindings.py │ │ ├── test_methods_and_attributes.cpp │ │ ├── test_methods_and_attributes.py │ │ ├── test_modules.cpp │ │ ├── test_modules.py │ │ ├── test_multiple_inheritance.cpp │ │ ├── test_multiple_inheritance.py │ │ ├── test_numpy_array.cpp │ │ ├── test_numpy_array.py │ │ ├── test_numpy_dtypes.cpp │ │ ├── test_numpy_dtypes.py │ │ ├── test_numpy_vectorize.cpp │ │ ├── test_numpy_vectorize.py │ │ ├── test_opaque_types.cpp │ │ ├── test_opaque_types.py │ │ ├── test_operator_overloading.cpp │ │ ├── test_operator_overloading.py │ │ ├── test_pickling.cpp │ │ ├── test_pickling.py │ │ ├── test_pytypes.cpp │ │ ├── test_pytypes.py │ │ ├── test_sequences_and_iterators.cpp │ │ ├── test_sequences_and_iterators.py │ │ ├── test_smart_ptr.cpp │ │ ├── test_smart_ptr.py │ │ ├── test_stl.cpp │ │ ├── test_stl.py │ │ ├── test_stl_binders.cpp │ │ ├── test_stl_binders.py │ │ ├── test_tagbased_polymorphic.cpp │ │ ├── test_tagbased_polymorphic.py │ │ ├── test_virtual_functions.cpp │ │ └── test_virtual_functions.py │ └── tools │ │ ├── FindCatch.cmake │ │ ├── FindEigen3.cmake │ │ ├── FindPythonLibsNew.cmake │ │ ├── check-style.sh │ │ ├── clang │ │ ├── .gitignore │ │ ├── LICENSE.TXT │ │ ├── README.md │ │ ├── __init__.py │ │ ├── cindex.py │ │ └── enumerations.py │ │ ├── libsize.py │ │ ├── mkdoc.py │ │ ├── pybind11Config.cmake.in │ │ └── pybind11Tools.cmake ├── segment ├── segment-graph.h ├── segment-image.h └── segment.cpp ├── computeIntegralImageScores.py ├── computeObjectnessHeatMap.py ├── computeQuantMatrix.py ├── computeScores.py ├── defaultParams.py ├── demo.py ├── drawBoxes.py ├── generateWindows.py ├── integralHistSuperpixels.py ├── integrateBayes.py ├── matlab_functions ├── fspecial.py └── mat2gray.py ├── mex_functions ├── NMS_sampling.py ├── computeIntegralHistogram.py ├── computeScoreContrast.py ├── scoreSampling.py └── slidingWindowComputeScore.py ├── nms_pascal.py ├── py_segment ├── __init__.py ├── graph.py └── py_segment.py ├── readme.md ├── results ├── my_impl │ ├── 002053_CC_boxes.png │ ├── 002053_CC_heatmap.png │ ├── 002053_ED_boxes.png │ ├── 002053_ED_heatmap.png │ ├── 002053_MS_boxes.png │ ├── 002053_MS_heatmap.png │ ├── 002053_SS_boxes.png │ ├── 002053_SS_heatmap.png │ ├── 002053_comb_boxes.png │ └── 002053_comb_heatmap.png ├── original │ ├── 002053_CC_boxes.jpg │ ├── 002053_CC_heatmap.jpg │ ├── 002053_ED_boxes.jpg │ ├── 002053_ED_heatmap.jpg │ ├── 002053_MS_boxes.jpg │ ├── 002053_MS_heatmap.jpg │ ├── 002053_SS_boxes.jpg │ ├── 002053_SS_heatmap.jpg │ ├── 002053_comb_boxes.jpg │ └── 002053_comb_heatmap.jpg └── readme.md ├── retrieveCoordinates.py ├── rgb2lab.py ├── runObjectness.py ├── segmentArea.py └── windowComputeScores.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .idea 3 | test_imgs 4 | c_segment/build 5 | c_segment/.vscode 6 | test_single_MS.py -------------------------------------------------------------------------------- /002053.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/002053.jpg -------------------------------------------------------------------------------- /Data/CClikelihood.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/Data/CClikelihood.mat -------------------------------------------------------------------------------- /Data/EDlikelihood.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/Data/EDlikelihood.mat -------------------------------------------------------------------------------- /Data/MSlikelihood.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/Data/MSlikelihood.mat -------------------------------------------------------------------------------- /Data/SSlikelihood.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/Data/SSlikelihood.mat -------------------------------------------------------------------------------- /Data/params.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/Data/params.mat -------------------------------------------------------------------------------- /c_segment/002053.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/002053.jpg -------------------------------------------------------------------------------- /c_segment/002053.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/002053.ppm -------------------------------------------------------------------------------- /c_segment/002053_out.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/002053_out.ppm -------------------------------------------------------------------------------- /c_segment/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(c_segment) 3 | add_subdirectory(pybind11) 4 | pybind11_add_module(c_segment interface.cpp) 5 | 6 | # aux_source_directory(. SRC_LIST) 7 | # set(CXXFLAGS "-g -std=c++11") 8 | # set(CXXFLAGS "-lrt -std=c++11 -DHAVE_CXX0X -openmp -march=native -fpic -w -fopenmp -ftree-vectorize -ftree-vectorizer-verbose=0") 9 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXXFLAGS}") 10 | # pybind11_add_module(interface ${SRC_LIST}) 11 | # add_executable(c_segment_test ${SRC_LIST}) 12 | # set(CXXFLAGS "-O2 -std=c++14") 13 | # set(CXXFLAGS "-lrt -std=c++11 -DHAVE_CXX0X -openmp -march=native -fpic -w -fopenmp -ftree-vectorize -ftree-vectorizer-verbose=0") 14 | # set(CXXFLAGS "-O2 -lrt -DNDEBUG -std=c++11 -DHAVE_CXX0X -openmp -march=native -fpic -w -fopenmp -ftree-vectorize -ftree-vectorizer-verbose=0") -------------------------------------------------------------------------------- /c_segment/Makefile: -------------------------------------------------------------------------------- 1 | INCDIR = -I. 2 | DBG = -g 3 | OPT = -O3 4 | CPP = g++ 5 | CFLAGS = $(DBG) $(OPT) $(INCDIR) 6 | LINK = -lm 7 | 8 | .cpp.o: 9 | $(CPP) $(CFLAGS) -c $< -o $@ 10 | 11 | all: segment 12 | 13 | segment: segment.cpp segment-image.h segment-graph.h disjoint-set.h 14 | $(CPP) $(CFLAGS) -o segment segment.cpp $(LINK) 15 | 16 | clean: 17 | /bin/rm -f segment *.o 18 | 19 | clean-all: clean 20 | /bin/rm -f *~ 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /c_segment/README: -------------------------------------------------------------------------------- 1 | 2 | Implementation of the segmentation algorithm described in: 3 | 4 | Efficient Graph-Based Image Segmentation 5 | Pedro F. Felzenszwalb and Daniel P. Huttenlocher 6 | International Journal of Computer Vision, 59(2) September 2004. 7 | 8 | The program takes a color image (PPM format) and produces a segmentation 9 | with a random color assigned to each region. 10 | 11 | 1) Type "make" to compile "segment". 12 | 13 | 2) Run "segment sigma k min input output". 14 | 15 | The parameters are: (see the paper for details) 16 | 17 | sigma: Used to smooth the input image before segmenting it. 18 | k: Value for the threshold function. 19 | min: Minimum component size enforced by post-processing. 20 | input: Input image. 21 | output: Output image. 22 | 23 | Typical parameters are sigma = 0.5, k = 500, min = 20. 24 | Larger values for k result in larger components in the result. 25 | 26 | -------------------------------------------------------------------------------- /c_segment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/__init__.py -------------------------------------------------------------------------------- /c_segment/c_segment.py: -------------------------------------------------------------------------------- 1 | from .build.c_segment import segment_img 2 | import numpy as np 3 | import cv2 4 | 5 | 6 | def c_segment_img(img, sigma, k, min_area): 7 | img = np.ascontiguousarray(img) 8 | height, width, _ = img.shape 9 | segmented_img = segment_img(img.reshape(-1), height, width, float(sigma), float(k), int(min_area)) 10 | return np.array(segmented_img).reshape(height, width) 11 | 12 | 13 | if __name__ == '__main__': 14 | img = cv2.imread('002053.jpg')[:, :, ::-1] 15 | segmented_img = c_segment_img(img, sigma=0.8354, k=450, min_area=334) 16 | pass 17 | -------------------------------------------------------------------------------- /c_segment/convolve.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* convolution */ 20 | 21 | #ifndef CONVOLVE_H 22 | #define CONVOLVE_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include "image.h" 28 | 29 | /* convolve src with mask. dst is flipped! */ 30 | static void convolve_even(image *src, image *dst, 31 | std::vector &mask) { 32 | int width = src->width(); 33 | int height = src->height(); 34 | int len = mask.size(); 35 | 36 | for (int y = 0; y < height; y++) { 37 | for (int x = 0; x < width; x++) { 38 | float sum = mask[0] * imRef(src, x, y); 39 | for (int i = 1; i < len; i++) { 40 | sum += mask[i] * 41 | (imRef(src, std::max(x-i,0), y) + 42 | imRef(src, std::min(x+i, width-1), y)); 43 | } 44 | imRef(dst, y, x) = sum; 45 | } 46 | } 47 | } 48 | 49 | /* convolve src with mask. dst is flipped! */ 50 | static void convolve_odd(image *src, image *dst, 51 | std::vector &mask) { 52 | int width = src->width(); 53 | int height = src->height(); 54 | int len = mask.size(); 55 | 56 | for (int y = 0; y < height; y++) { 57 | for (int x = 0; x < width; x++) { 58 | float sum = mask[0] * imRef(src, x, y); 59 | for (int i = 1; i < len; i++) { 60 | sum += mask[i] * 61 | (imRef(src, std::max(x-i,0), y) - 62 | imRef(src, std::min(x+i, width-1), y)); 63 | } 64 | imRef(dst, y, x) = sum; 65 | } 66 | } 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /c_segment/disjoint-set.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef DISJOINT_SET 20 | #define DISJOINT_SET 21 | 22 | // disjoint-set forests using union-by-rank and path compression (sort of). 23 | 24 | typedef struct { 25 | int rank; 26 | int p; 27 | int size; 28 | } uni_elt; 29 | 30 | class universe { 31 | public: 32 | universe(int elements); 33 | ~universe(); 34 | int find(int x); 35 | void join(int x, int y); 36 | int size(int x) const { return elts[x].size; } 37 | int num_sets() const { return num; } 38 | 39 | private: 40 | uni_elt *elts; 41 | int num; 42 | }; 43 | 44 | universe::universe(int elements) { 45 | elts = new uni_elt[elements]; 46 | num = elements; 47 | for (int i = 0; i < elements; i++) { 48 | elts[i].rank = 0; 49 | elts[i].size = 1; 50 | elts[i].p = i; 51 | } 52 | } 53 | 54 | universe::~universe() { 55 | delete [] elts; 56 | } 57 | 58 | int universe::find(int x) { 59 | int y = x; 60 | while (y != elts[y].p) 61 | y = elts[y].p; 62 | elts[x].p = y; 63 | return y; 64 | } 65 | 66 | void universe::join(int x, int y) { 67 | if (elts[x].rank > elts[y].rank) { 68 | elts[y].p = x; 69 | elts[x].size += elts[y].size; 70 | } else { 71 | elts[x].p = y; 72 | elts[y].size += elts[x].size; 73 | if (elts[x].rank == elts[y].rank) 74 | elts[y].rank++; 75 | } 76 | num--; 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /c_segment/filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* simple filters */ 20 | 21 | #ifndef FILTER_H 22 | #define FILTER_H 23 | 24 | #include 25 | #include 26 | #include "image.h" 27 | #include "misc.h" 28 | #include "convolve.h" 29 | #include "imconv.h" 30 | 31 | #define WIDTH 4.0 32 | 33 | /* normalize mask so it integrates to one */ 34 | static void normalize(std::vector &mask) { 35 | int len = mask.size(); 36 | float sum = 0; 37 | for (int i = 1; i < len; i++) { 38 | sum += fabs(mask[i]); 39 | } 40 | sum = 2*sum + fabs(mask[0]); 41 | for (int i = 0; i < len; i++) { 42 | mask[i] /= sum; 43 | } 44 | } 45 | 46 | /* make filters */ 47 | #define MAKE_FILTER(name, fun) \ 48 | static std::vector make_ ## name (float sigma) { \ 49 | sigma = std::max(sigma, 0.01F); \ 50 | int len = (int)ceil(sigma * WIDTH) + 1; \ 51 | std::vector mask(len); \ 52 | for (int i = 0; i < len; i++) { \ 53 | mask[i] = fun; \ 54 | } \ 55 | return mask; \ 56 | } 57 | 58 | MAKE_FILTER(fgauss, exp(-0.5*square(i/sigma))); 59 | 60 | /* convolve image with gaussian filter */ 61 | static image *smooth(image *src, float sigma) { 62 | std::vector mask = make_fgauss(sigma); 63 | normalize(mask); 64 | 65 | image *tmp = new image(src->height(), src->width(), false); 66 | image *dst = new image(src->width(), src->height(), false); 67 | convolve_even(src, tmp, mask); 68 | convolve_even(tmp, dst, mask); 69 | 70 | delete tmp; 71 | return dst; 72 | } 73 | 74 | /* convolve image with gaussian filter */ 75 | image *smooth(image *src, float sigma) { 76 | image *tmp = imageUCHARtoFLOAT(src); 77 | image *dst = smooth(tmp, sigma); 78 | delete tmp; 79 | return dst; 80 | } 81 | 82 | /* compute laplacian */ 83 | static image *laplacian(image *src) { 84 | int width = src->width(); 85 | int height = src->height(); 86 | image *dst = new image(width, height); 87 | 88 | for (int y = 1; y < height-1; y++) { 89 | for (int x = 1; x < width-1; x++) { 90 | float d2x = imRef(src, x-1, y) + imRef(src, x+1, y) - 91 | 2*imRef(src, x, y); 92 | float d2y = imRef(src, x, y-1) + imRef(src, x, y+1) - 93 | 2*imRef(src, x, y); 94 | imRef(dst, x, y) = d2x + d2y; 95 | } 96 | } 97 | return dst; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /c_segment/image.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* a simple image class */ 20 | 21 | #ifndef IMAGE_H 22 | #define IMAGE_H 23 | 24 | #include 25 | 26 | template 27 | class image { 28 | public: 29 | /* create an image */ 30 | image(const int width, const int height, const bool init = true); 31 | 32 | /* delete an image */ 33 | ~image(); 34 | 35 | /* init an image */ 36 | void init(const T &val); 37 | 38 | /* copy an image */ 39 | image *copy() const; 40 | 41 | /* get the width of an image. */ 42 | int width() const { return w; } 43 | 44 | /* get the height of an image. */ 45 | int height() const { return h; } 46 | 47 | /* image data. */ 48 | T *data; 49 | 50 | /* row pointers. */ 51 | T **access; 52 | 53 | private: 54 | int w, h; 55 | }; 56 | 57 | /* use imRef to access image data. */ 58 | #define imRef(im, x, y) (im->access[y][x]) 59 | 60 | /* use imPtr to get pointer to image data. */ 61 | #define imPtr(im, x, y) &(im->access[y][x]) 62 | 63 | template 64 | image::image(const int width, const int height, const bool init) { 65 | w = width; 66 | h = height; 67 | data = new T[w * h]; // allocate space for image data 68 | access = new T*[h]; // allocate space for row pointers 69 | 70 | // initialize row pointers 71 | for (int i = 0; i < h; i++) 72 | access[i] = data + (i * w); 73 | 74 | if (init) 75 | memset(data, 0, w * h * sizeof(T)); 76 | } 77 | 78 | template 79 | image::~image() { 80 | delete [] data; 81 | delete [] access; 82 | } 83 | 84 | template 85 | void image::init(const T &val) { 86 | T *ptr = imPtr(this, 0, 0); 87 | T *end = imPtr(this, w-1, h-1); 88 | while (ptr <= end) 89 | *ptr++ = val; 90 | } 91 | 92 | 93 | template 94 | image *image::copy() const { 95 | image *im = new image(w, h, false); 96 | memcpy(im->data, data, w * h * sizeof(T)); 97 | return im; 98 | } 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /c_segment/imutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* some image utilities */ 20 | 21 | #ifndef IMUTIL_H 22 | #define IMUTIL_H 23 | 24 | #include "image.h" 25 | #include "misc.h" 26 | 27 | /* compute minimum and maximum value in an image */ 28 | template 29 | void min_max(image *im, T *ret_min, T *ret_max) { 30 | int width = im->width(); 31 | int height = im->height(); 32 | 33 | T min = imRef(im, 0, 0); 34 | T max = imRef(im, 0, 0); 35 | for (int y = 0; y < height; y++) { 36 | for (int x = 0; x < width; x++) { 37 | T val = imRef(im, x, y); 38 | if (min > val) 39 | min = val; 40 | if (max < val) 41 | max = val; 42 | } 43 | } 44 | 45 | *ret_min = min; 46 | *ret_max = max; 47 | } 48 | 49 | /* threshold image */ 50 | template 51 | image *threshold(image *src, int t) { 52 | int width = src->width(); 53 | int height = src->height(); 54 | image *dst = new image(width, height); 55 | 56 | for (int y = 0; y < height; y++) { 57 | for (int x = 0; x < width; x++) { 58 | imRef(dst, x, y) = (imRef(src, x, y) >= t); 59 | } 60 | } 61 | 62 | return dst; 63 | } 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /c_segment/interface.cpp: -------------------------------------------------------------------------------- 1 | #include "pybind11/pybind11.h" 2 | #include "pybind11/stl.h" 3 | #include "pybind11/numpy.h" 4 | #include "image.h" 5 | #include 6 | #include "segment-image.h" 7 | 8 | namespace py = pybind11; 9 | 10 | // ------------- 11 | // pure C++ code 12 | // ------------- 13 | 14 | std::vector segment_img(const std::vector &img_vec, const int height, const int width, const double sigma, const double k, const int min_size) 15 | { 16 | // Assume the img_vec is from an rgb image. 17 | image *seg; 18 | image *im = new image(width, height); 19 | rgb *imPtr = im->data; 20 | int num_elem = height * width; 21 | for (int y = 0; y < height; ++y) 22 | { 23 | for (int x = 0; x < width; ++x) 24 | { 25 | rgb pixel; 26 | int start_idx = (y * width + x) * 3; 27 | pixel.r = img_vec[start_idx]; 28 | pixel.g = img_vec[start_idx + 1]; 29 | pixel.b = img_vec[start_idx + 2]; 30 | *(imPtr++) = pixel; 31 | } 32 | } 33 | 34 | int num_ccs; 35 | seg = segment_image_int(im, sigma, k, min_size, &num_ccs); 36 | delete im; 37 | 38 | int *seg_ptr = seg->data; 39 | std::vector output(num_elem); // output is an H x W image. 40 | for(int y = 0; y < height; ++y) 41 | { 42 | for(int x = 0; x < width; ++x) 43 | { 44 | output[y * width + x] = *(seg_ptr++); 45 | } 46 | } 47 | 48 | delete seg; 49 | 50 | return output; 51 | } 52 | 53 | // ---------------- 54 | // Python interface 55 | // ---------------- 56 | 57 | // wrap C++ function with NumPy array IO 58 | py::array_t py_(py::array_t flatten_img, const int height, const int width, const double sigma, const double k, const int min_size) 59 | { 60 | // allocate std::vector (to pass to the C++ function) 61 | std::vector img_vec(flatten_img.size()); 62 | 63 | // copy py::array -> std::vector 64 | std::memcpy(img_vec.data(), flatten_img.data(), flatten_img.size() * sizeof(uint8_t)); 65 | 66 | // call pure C++ function 67 | std::vector result_vec = segment_img(img_vec, height, width, sigma, k, min_size); 68 | 69 | // allocate py::array (to pass the result of the C++ function to Python) 70 | auto result = py::array_t(result_vec.size()); 71 | auto result_buffer = result.request(); 72 | int *result_ptr = (int *)result_buffer.ptr; 73 | 74 | // copy std::vector -> py::array 75 | std::memcpy(result_ptr, result_vec.data(), result_vec.size() * sizeof(int)); 76 | 77 | return result; 78 | } 79 | 80 | // wrap as Python module 81 | PYBIND11_MODULE(c_segment, m) 82 | { 83 | m.doc() = "Segment an rgb image into superpixels."; 84 | 85 | m.def("segment_img", &segment_img, "Segment an rgb image into superpixels."); 86 | } -------------------------------------------------------------------------------- /c_segment/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* random stuff */ 20 | 21 | #ifndef MISC_H 22 | #define MISC_H 23 | 24 | #include 25 | 26 | #ifndef M_PI 27 | #define M_PI 3.141592653589793 28 | #endif 29 | 30 | typedef unsigned char uchar; 31 | 32 | typedef struct { uchar r, g, b; } rgb; 33 | 34 | inline bool operator==(const rgb &a, const rgb &b) { 35 | return ((a.r == b.r) && (a.g == b.g) && (a.b == b.b)); 36 | } 37 | 38 | template 39 | inline T abs(const T &x) { return (x > 0 ? x : -x); }; 40 | 41 | template 42 | inline int sign(const T &x) { return (x >= 0 ? 1 : -1); }; 43 | 44 | template 45 | inline T square(const T &x) { return x*x; }; 46 | 47 | template 48 | inline T bound(const T &x, const T &min, const T &max) { 49 | return (x < min ? min : (x > max ? max : x)); 50 | } 51 | 52 | template 53 | inline bool check_bound(const T &x, const T&min, const T &max) { 54 | return ((x < min) || (x > max)); 55 | } 56 | 57 | inline int vlib_round(float x) { return (int)(x + 0.5F); } 58 | 59 | inline int vlib_round(double x) { return (int)(x + 0.5); } 60 | 61 | inline double gaussian(double val, double sigma) { 62 | return exp(-square(val/sigma)/2)/(sqrt(2*M_PI)*sigma); 63 | } 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /c_segment/pybind11/.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | image: 3 | - Visual Studio 2017 4 | - Visual Studio 2015 5 | test: off 6 | skip_branch_with_pr: true 7 | build: 8 | parallel: true 9 | platform: 10 | - x64 11 | - x86 12 | environment: 13 | matrix: 14 | - PYTHON: 36 15 | CPP: 14 16 | CONFIG: Debug 17 | - PYTHON: 27 18 | CPP: 14 19 | CONFIG: Debug 20 | - CONDA: 36 21 | CPP: latest 22 | CONFIG: Release 23 | matrix: 24 | exclude: 25 | - image: Visual Studio 2015 26 | platform: x86 27 | - image: Visual Studio 2015 28 | CPP: latest 29 | - image: Visual Studio 2017 30 | CPP: latest 31 | platform: x86 32 | install: 33 | - ps: | 34 | if ($env:PLATFORM -eq "x64") { $env:CMAKE_ARCH = "x64" } 35 | if ($env:APPVEYOR_JOB_NAME -like "*Visual Studio 2017*") { 36 | $env:CMAKE_GENERATOR = "Visual Studio 15 2017" 37 | $env:CMAKE_INCLUDE_PATH = "C:\Libraries\boost_1_64_0" 38 | $env:CXXFLAGS = "-permissive-" 39 | } else { 40 | $env:CMAKE_GENERATOR = "Visual Studio 14 2015" 41 | } 42 | if ($env:PYTHON) { 43 | if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" } 44 | $env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH" 45 | python -W ignore -m pip install --upgrade pip wheel 46 | python -W ignore -m pip install pytest numpy --no-warn-script-location 47 | } elseif ($env:CONDA) { 48 | if ($env:CONDA -eq "27") { $env:CONDA = "" } 49 | if ($env:PLATFORM -eq "x64") { $env:CONDA = "$env:CONDA-x64" } 50 | $env:PATH = "C:\Miniconda$env:CONDA\;C:\Miniconda$env:CONDA\Scripts\;$env:PATH" 51 | $env:PYTHONHOME = "C:\Miniconda$env:CONDA" 52 | conda update -y -n base conda 53 | conda install -y -q pytest numpy scipy 54 | } 55 | - ps: | 56 | Start-FileDownload 'http://bitbucket.org/eigen/eigen/get/3.3.3.zip' 57 | 7z x 3.3.3.zip -y > $null 58 | $env:CMAKE_INCLUDE_PATH = "eigen-eigen-67e894c6cd8f;$env:CMAKE_INCLUDE_PATH" 59 | build_script: 60 | - cmake -G "%CMAKE_GENERATOR%" -A "%CMAKE_ARCH%" 61 | -DPYBIND11_CPP_STANDARD=/std:c++%CPP% 62 | -DPYBIND11_WERROR=ON 63 | -DDOWNLOAD_CATCH=ON 64 | -DCMAKE_SUPPRESS_REGENERATION=1 65 | - set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" 66 | - cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger% 67 | - cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger% 68 | - if "%CPP%"=="latest" (cmake --build . --config %CONFIG% --target test_cmake_build -- /m /v:m /logger:%MSBuildLogger%) 69 | on_failure: if exist "tests\test_cmake_build" type tests\test_cmake_build\*.log* 70 | -------------------------------------------------------------------------------- /c_segment/pybind11/.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | Makefile 4 | cmake_install.cmake 5 | .DS_Store 6 | *.so 7 | *.pyd 8 | *.dll 9 | *.sln 10 | *.sdf 11 | *.opensdf 12 | *.vcxproj 13 | *.filters 14 | example.dir 15 | Win32 16 | x64 17 | Release 18 | Debug 19 | .vs 20 | CTestTestfile.cmake 21 | Testing 22 | autogen 23 | MANIFEST 24 | /.ninja_* 25 | /*.ninja 26 | /docs/.build 27 | *.py[co] 28 | *.egg-info 29 | *~ 30 | .*.swp 31 | .DS_Store 32 | /dist 33 | /build 34 | /cmake/ 35 | .cache/ 36 | sosize-*.txt 37 | pybind11Config*.cmake 38 | pybind11Targets.cmake 39 | -------------------------------------------------------------------------------- /c_segment/pybind11/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tools/clang"] 2 | path = tools/clang 3 | url = ../../wjakob/clang-cindex-python3 4 | -------------------------------------------------------------------------------- /c_segment/pybind11/.readthedocs.yml: -------------------------------------------------------------------------------- 1 | python: 2 | version: 3 3 | requirements_file: docs/requirements.txt 4 | -------------------------------------------------------------------------------- /c_segment/pybind11/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thank you for your interest in this project! Please refer to the following 2 | sections on how to contribute code and bug reports. 3 | 4 | ### Reporting bugs 5 | 6 | At the moment, this project is run in the spare time of a single person 7 | ([Wenzel Jakob](http://rgl.epfl.ch/people/wjakob)) with very limited resources 8 | for issue tracker tickets. Thus, before submitting a question or bug report, 9 | please take a moment of your time and ensure that your issue isn't already 10 | discussed in the project documentation provided at 11 | [http://pybind11.readthedocs.org/en/latest](http://pybind11.readthedocs.org/en/latest). 12 | 13 | Assuming that you have identified a previously unknown problem or an important 14 | question, it's essential that you submit a self-contained and minimal piece of 15 | code that reproduces the problem. In other words: no external dependencies, 16 | isolate the function(s) that cause breakage, submit matched and complete C++ 17 | and Python snippets that can be easily compiled and run on my end. 18 | 19 | ## Pull requests 20 | Contributions are submitted, reviewed, and accepted using Github pull requests. 21 | Please refer to [this 22 | article](https://help.github.com/articles/using-pull-requests) for details and 23 | adhere to the following rules to make the process as smooth as possible: 24 | 25 | * Make a new branch for every feature you're working on. 26 | * Make small and clean pull requests that are easy to review but make sure they 27 | do add value by themselves. 28 | * Add tests for any new functionality and run the test suite (``make pytest``) 29 | to ensure that no existing features break. 30 | * Please run ``flake8`` and ``tools/check-style.sh`` to check your code matches 31 | the project style. (Note that ``check-style.sh`` requires ``gawk``.) 32 | * This project has a strong focus on providing general solutions using a 33 | minimal amount of code, thus small pull requests are greatly preferred. 34 | 35 | ### Licensing of contributions 36 | 37 | pybind11 is provided under a BSD-style license that can be found in the 38 | ``LICENSE`` file. By using, distributing, or contributing to this project, you 39 | agree to the terms and conditions of this license. 40 | 41 | You are under no obligation whatsoever to provide any bug fixes, patches, or 42 | upgrades to the features, functionality or performance of the source code 43 | ("Enhancements") to anyone; however, if you choose to make your Enhancements 44 | available either publicly, or directly to the author of this software, without 45 | imposing a separate written license agreement for such Enhancements, then you 46 | hereby grant the following license: a non-exclusive, royalty-free perpetual 47 | license to install, use, modify, prepare derivative works, incorporate into 48 | other computer software, distribute, and sublicense such enhancements or 49 | derivative works thereof, in binary and source code form. 50 | -------------------------------------------------------------------------------- /c_segment/pybind11/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Make sure you've completed the following steps before submitting your issue -- thank you! 2 | 3 | 1. Check if your question has already been answered in the [FAQ](http://pybind11.readthedocs.io/en/latest/faq.html) section. 4 | 2. Make sure you've read the [documentation](http://pybind11.readthedocs.io/en/latest/). Your issue may be addressed there. 5 | 3. If those resources didn't help and you only have a short question (not a bug report), consider asking in the [Gitter chat room](https://gitter.im/pybind/Lobby). 6 | 4. If you have a genuine bug report or a more complex question which is not answered in the previous items (or not suitable for chat), please fill in the details below. 7 | 5. Include a self-contained and minimal piece of code that reproduces the problem. If that's not possible, try to make the description as clear as possible. 8 | 9 | *After reading, remove this checklist and the template text in parentheses below.* 10 | 11 | ## Issue description 12 | 13 | (Provide a short description, state the expected behavior and what actually happens.) 14 | 15 | ## Reproducible example code 16 | 17 | (The code should be minimal, have no external dependencies, isolate the function(s) that cause breakage. Submit matched and complete C++ and Python snippets that can be easily compiled and run to diagnose the issue.) 18 | -------------------------------------------------------------------------------- /c_segment/pybind11/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Wenzel Jakob , All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | Please also refer to the file CONTRIBUTING.md, which clarifies licensing of 29 | external contributions to this project including patches, pull requests, etc. 30 | -------------------------------------------------------------------------------- /c_segment/pybind11/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include include/pybind11 *.h 2 | include LICENSE README.md CONTRIBUTING.md 3 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = pybind11 2 | INPUT = ../include/pybind11/ 3 | RECURSIVE = YES 4 | 5 | GENERATE_HTML = NO 6 | GENERATE_LATEX = NO 7 | GENERATE_XML = YES 8 | XML_OUTPUT = .build/doxygenxml 9 | XML_PROGRAMLISTING = YES 10 | 11 | MACRO_EXPANSION = YES 12 | EXPAND_ONLY_PREDEF = YES 13 | EXPAND_AS_DEFINED = PYBIND11_RUNTIME_EXCEPTION 14 | 15 | ALIASES = "rst=\verbatim embed:rst" 16 | ALIASES += "endrst=\endverbatim" 17 | 18 | QUIET = YES 19 | WARNINGS = YES 20 | WARN_IF_UNDOCUMENTED = NO 21 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/_static/theme_overrides.css: -------------------------------------------------------------------------------- 1 | .wy-table-responsive table td, 2 | .wy-table-responsive table th { 3 | white-space: initial !important; 4 | } 5 | .rst-content table.docutils td { 6 | vertical-align: top !important; 7 | } 8 | div[class^='highlight'] pre { 9 | white-space: pre; 10 | white-space: pre-wrap; 11 | } 12 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/advanced/cast/chrono.rst: -------------------------------------------------------------------------------- 1 | Chrono 2 | ====== 3 | 4 | When including the additional header file :file:`pybind11/chrono.h` conversions 5 | from C++11 chrono datatypes to python datetime objects are automatically enabled. 6 | This header also enables conversions of python floats (often from sources such 7 | as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``) 8 | into durations. 9 | 10 | An overview of clocks in C++11 11 | ------------------------------ 12 | 13 | A point of confusion when using these conversions is the differences between 14 | clocks provided in C++11. There are three clock types defined by the C++11 15 | standard and users can define their own if needed. Each of these clocks have 16 | different properties and when converting to and from python will give different 17 | results. 18 | 19 | The first clock defined by the standard is ``std::chrono::system_clock``. This 20 | clock measures the current date and time. However, this clock changes with to 21 | updates to the operating system time. For example, if your time is synchronised 22 | with a time server this clock will change. This makes this clock a poor choice 23 | for timing purposes but good for measuring the wall time. 24 | 25 | The second clock defined in the standard is ``std::chrono::steady_clock``. 26 | This clock ticks at a steady rate and is never adjusted. This makes it excellent 27 | for timing purposes, however the value in this clock does not correspond to the 28 | current date and time. Often this clock will be the amount of time your system 29 | has been on, although it does not have to be. This clock will never be the same 30 | clock as the system clock as the system clock can change but steady clocks 31 | cannot. 32 | 33 | The third clock defined in the standard is ``std::chrono::high_resolution_clock``. 34 | This clock is the clock that has the highest resolution out of the clocks in the 35 | system. It is normally a typedef to either the system clock or the steady clock 36 | but can be its own independent clock. This is important as when using these 37 | conversions as the types you get in python for this clock might be different 38 | depending on the system. 39 | If it is a typedef of the system clock, python will get datetime objects, but if 40 | it is a different clock they will be timedelta objects. 41 | 42 | Provided conversions 43 | -------------------- 44 | 45 | .. rubric:: C++ to Python 46 | 47 | - ``std::chrono::system_clock::time_point`` → ``datetime.datetime`` 48 | System clock times are converted to python datetime instances. They are 49 | in the local timezone, but do not have any timezone information attached 50 | to them (they are naive datetime objects). 51 | 52 | - ``std::chrono::duration`` → ``datetime.timedelta`` 53 | Durations are converted to timedeltas, any precision in the duration 54 | greater than microseconds is lost by rounding towards zero. 55 | 56 | - ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta`` 57 | Any clock time that is not the system clock is converted to a time delta. 58 | This timedelta measures the time from the clocks epoch to now. 59 | 60 | .. rubric:: Python to C++ 61 | 62 | - ``datetime.datetime`` → ``std::chrono::system_clock::time_point`` 63 | Date/time objects are converted into system clock timepoints. Any 64 | timezone information is ignored and the type is treated as a naive 65 | object. 66 | 67 | - ``datetime.timedelta`` → ``std::chrono::duration`` 68 | Time delta are converted into durations with microsecond precision. 69 | 70 | - ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point`` 71 | Time deltas that are converted into clock timepoints are treated as 72 | the amount of time from the start of the clocks epoch. 73 | 74 | - ``float`` → ``std::chrono::duration`` 75 | Floats that are passed to C++ as durations be interpreted as a number of 76 | seconds. These will be converted to the duration using ``duration_cast`` 77 | from the float. 78 | 79 | - ``float`` → ``std::chrono::[other_clocks]::time_point`` 80 | Floats that are passed to C++ as time points will be interpreted as the 81 | number of seconds from the start of the clocks epoch. 82 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/advanced/cast/custom.rst: -------------------------------------------------------------------------------- 1 | Custom type casters 2 | =================== 3 | 4 | In very rare cases, applications may require custom type casters that cannot be 5 | expressed using the abstractions provided by pybind11, thus requiring raw 6 | Python C API calls. This is fairly advanced usage and should only be pursued by 7 | experts who are familiar with the intricacies of Python reference counting. 8 | 9 | The following snippets demonstrate how this works for a very simple ``inty`` 10 | type that that should be convertible from Python types that provide a 11 | ``__int__(self)`` method. 12 | 13 | .. code-block:: cpp 14 | 15 | struct inty { long long_value; }; 16 | 17 | void print(inty s) { 18 | std::cout << s.long_value << std::endl; 19 | } 20 | 21 | The following Python snippet demonstrates the intended usage from the Python side: 22 | 23 | .. code-block:: python 24 | 25 | class A: 26 | def __int__(self): 27 | return 123 28 | 29 | from example import print 30 | print(A()) 31 | 32 | To register the necessary conversion routines, it is necessary to add 33 | a partial overload to the ``pybind11::detail::type_caster`` template. 34 | Although this is an implementation detail, adding partial overloads to this 35 | type is explicitly allowed. 36 | 37 | .. code-block:: cpp 38 | 39 | namespace pybind11 { namespace detail { 40 | template <> struct type_caster { 41 | public: 42 | /** 43 | * This macro establishes the name 'inty' in 44 | * function signatures and declares a local variable 45 | * 'value' of type inty 46 | */ 47 | PYBIND11_TYPE_CASTER(inty, _("inty")); 48 | 49 | /** 50 | * Conversion part 1 (Python->C++): convert a PyObject into a inty 51 | * instance or return false upon failure. The second argument 52 | * indicates whether implicit conversions should be applied. 53 | */ 54 | bool load(handle src, bool) { 55 | /* Extract PyObject from handle */ 56 | PyObject *source = src.ptr(); 57 | /* Try converting into a Python integer value */ 58 | PyObject *tmp = PyNumber_Long(source); 59 | if (!tmp) 60 | return false; 61 | /* Now try to convert into a C++ int */ 62 | value.long_value = PyLong_AsLong(tmp); 63 | Py_DECREF(tmp); 64 | /* Ensure return code was OK (to avoid out-of-range errors etc) */ 65 | return !(value.long_value == -1 && !PyErr_Occurred()); 66 | } 67 | 68 | /** 69 | * Conversion part 2 (C++ -> Python): convert an inty instance into 70 | * a Python object. The second and third arguments are used to 71 | * indicate the return value policy and parent object (for 72 | * ``return_value_policy::reference_internal``) and are generally 73 | * ignored by implicit casters. 74 | */ 75 | static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) { 76 | return PyLong_FromLong(src.long_value); 77 | } 78 | }; 79 | }} // namespace pybind11::detail 80 | 81 | .. note:: 82 | 83 | A ``type_caster`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires 84 | that ``T`` is default-constructible (``value`` is first default constructed 85 | and then ``load()`` assigns to it). 86 | 87 | .. warning:: 88 | 89 | When using custom type casters, it's important to declare them consistently 90 | in every compilation unit of the Python extension module. Otherwise, 91 | undefined behavior can ensue. 92 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/advanced/cast/index.rst: -------------------------------------------------------------------------------- 1 | Type conversions 2 | ################ 3 | 4 | Apart from enabling cross-language function calls, a fundamental problem 5 | that a binding tool like pybind11 must address is to provide access to 6 | native Python types in C++ and vice versa. There are three fundamentally 7 | different ways to do this—which approach is preferable for a particular type 8 | depends on the situation at hand. 9 | 10 | 1. Use a native C++ type everywhere. In this case, the type must be wrapped 11 | using pybind11-generated bindings so that Python can interact with it. 12 | 13 | 2. Use a native Python type everywhere. It will need to be wrapped so that 14 | C++ functions can interact with it. 15 | 16 | 3. Use a native C++ type on the C++ side and a native Python type on the 17 | Python side. pybind11 refers to this as a *type conversion*. 18 | 19 | Type conversions are the most "natural" option in the sense that native 20 | (non-wrapped) types are used everywhere. The main downside is that a copy 21 | of the data must be made on every Python ↔ C++ transition: this is 22 | needed since the C++ and Python versions of the same type generally won't 23 | have the same memory layout. 24 | 25 | pybind11 can perform many kinds of conversions automatically. An overview 26 | is provided in the table ":ref:`conversion_table`". 27 | 28 | The following subsections discuss the differences between these options in more 29 | detail. The main focus in this section is on type conversions, which represent 30 | the last case of the above list. 31 | 32 | .. toctree:: 33 | :maxdepth: 1 34 | 35 | overview 36 | strings 37 | stl 38 | functional 39 | chrono 40 | eigen 41 | custom 42 | 43 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/advanced/pycpp/index.rst: -------------------------------------------------------------------------------- 1 | Python C++ interface 2 | #################### 3 | 4 | pybind11 exposes Python types and functions using thin C++ wrappers, which 5 | makes it possible to conveniently call Python code from C++ without resorting 6 | to Python's C API. 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | object 12 | numpy 13 | utilities 14 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/benchmark.py: -------------------------------------------------------------------------------- 1 | import random 2 | import os 3 | import time 4 | import datetime as dt 5 | 6 | nfns = 4 # Functions per class 7 | nargs = 4 # Arguments per function 8 | 9 | 10 | def generate_dummy_code_pybind11(nclasses=10): 11 | decl = "" 12 | bindings = "" 13 | 14 | for cl in range(nclasses): 15 | decl += "class cl%03i;\n" % cl 16 | decl += '\n' 17 | 18 | for cl in range(nclasses): 19 | decl += "class cl%03i {\n" % cl 20 | decl += "public:\n" 21 | bindings += ' py::class_(m, "cl%03i")\n' % (cl, cl) 22 | for fn in range(nfns): 23 | ret = random.randint(0, nclasses - 1) 24 | params = [random.randint(0, nclasses - 1) for i in range(nargs)] 25 | decl += " cl%03i *fn_%03i(" % (ret, fn) 26 | decl += ", ".join("cl%03i *" % p for p in params) 27 | decl += ");\n" 28 | bindings += ' .def("fn_%03i", &cl%03i::fn_%03i)\n' % \ 29 | (fn, cl, fn) 30 | decl += "};\n\n" 31 | bindings += ' ;\n' 32 | 33 | result = "#include \n\n" 34 | result += "namespace py = pybind11;\n\n" 35 | result += decl + '\n' 36 | result += "PYBIND11_MODULE(example, m) {\n" 37 | result += bindings 38 | result += "}" 39 | return result 40 | 41 | 42 | def generate_dummy_code_boost(nclasses=10): 43 | decl = "" 44 | bindings = "" 45 | 46 | for cl in range(nclasses): 47 | decl += "class cl%03i;\n" % cl 48 | decl += '\n' 49 | 50 | for cl in range(nclasses): 51 | decl += "class cl%03i {\n" % cl 52 | decl += "public:\n" 53 | bindings += ' py::class_("cl%03i")\n' % (cl, cl) 54 | for fn in range(nfns): 55 | ret = random.randint(0, nclasses - 1) 56 | params = [random.randint(0, nclasses - 1) for i in range(nargs)] 57 | decl += " cl%03i *fn_%03i(" % (ret, fn) 58 | decl += ", ".join("cl%03i *" % p for p in params) 59 | decl += ");\n" 60 | bindings += ' .def("fn_%03i", &cl%03i::fn_%03i, py::return_value_policy())\n' % \ 61 | (fn, cl, fn) 62 | decl += "};\n\n" 63 | bindings += ' ;\n' 64 | 65 | result = "#include \n\n" 66 | result += "namespace py = boost::python;\n\n" 67 | result += decl + '\n' 68 | result += "BOOST_PYTHON_MODULE(example) {\n" 69 | result += bindings 70 | result += "}" 71 | return result 72 | 73 | 74 | for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]: 75 | print ("{") 76 | for i in range(0, 10): 77 | nclasses = 2 ** i 78 | with open("test.cpp", "w") as f: 79 | f.write(codegen(nclasses)) 80 | n1 = dt.datetime.now() 81 | os.system("g++ -Os -shared -rdynamic -undefined dynamic_lookup " 82 | "-fvisibility=hidden -std=c++14 test.cpp -I include " 83 | "-I /System/Library/Frameworks/Python.framework/Headers -o test.so") 84 | n2 = dt.datetime.now() 85 | elapsed = (n2 - n1).total_seconds() 86 | size = os.stat('test.so').st_size 87 | print(" {%i, %f, %i}," % (nclasses * nfns, elapsed, size)) 88 | print ("}") 89 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/benchmark.rst: -------------------------------------------------------------------------------- 1 | Benchmark 2 | ========= 3 | 4 | The following is the result of a synthetic benchmark comparing both compilation 5 | time and module size of pybind11 against Boost.Python. A detailed report about a 6 | Boost.Python to pybind11 conversion of a real project is available here: [#f1]_. 7 | 8 | .. [#f1] http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf 9 | 10 | Setup 11 | ----- 12 | 13 | A python script (see the ``docs/benchmark.py`` file) was used to generate a set 14 | of files with dummy classes whose count increases for each successive benchmark 15 | (between 1 and 2048 classes in powers of two). Each class has four methods with 16 | a randomly generated signature with a return value and four arguments. (There 17 | was no particular reason for this setup other than the desire to generate many 18 | unique function signatures whose count could be controlled in a simple way.) 19 | 20 | Here is an example of the binding code for one class: 21 | 22 | .. code-block:: cpp 23 | 24 | ... 25 | class cl034 { 26 | public: 27 | cl279 *fn_000(cl084 *, cl057 *, cl065 *, cl042 *); 28 | cl025 *fn_001(cl098 *, cl262 *, cl414 *, cl121 *); 29 | cl085 *fn_002(cl445 *, cl297 *, cl145 *, cl421 *); 30 | cl470 *fn_003(cl200 *, cl323 *, cl332 *, cl492 *); 31 | }; 32 | ... 33 | 34 | PYBIND11_MODULE(example, m) { 35 | ... 36 | py::class_(m, "cl034") 37 | .def("fn_000", &cl034::fn_000) 38 | .def("fn_001", &cl034::fn_001) 39 | .def("fn_002", &cl034::fn_002) 40 | .def("fn_003", &cl034::fn_003) 41 | ... 42 | } 43 | 44 | The Boost.Python version looks almost identical except that a return value 45 | policy had to be specified as an argument to ``def()``. For both libraries, 46 | compilation was done with 47 | 48 | .. code-block:: bash 49 | 50 | Apple LLVM version 7.0.2 (clang-700.1.81) 51 | 52 | and the following compilation flags 53 | 54 | .. code-block:: bash 55 | 56 | g++ -Os -shared -rdynamic -undefined dynamic_lookup -fvisibility=hidden -std=c++14 57 | 58 | Compilation time 59 | ---------------- 60 | 61 | The following log-log plot shows how the compilation time grows for an 62 | increasing number of class and function declarations. pybind11 includes many 63 | fewer headers, which initially leads to shorter compilation times, but the 64 | performance is ultimately fairly similar (pybind11 is 19.8 seconds faster for 65 | the largest largest file with 2048 classes and a total of 8192 methods -- a 66 | modest **1.2x** speedup relative to Boost.Python, which required 116.35 67 | seconds). 68 | 69 | .. only:: not latex 70 | 71 | .. image:: pybind11_vs_boost_python1.svg 72 | 73 | .. only:: latex 74 | 75 | .. image:: pybind11_vs_boost_python1.png 76 | 77 | Module size 78 | ----------- 79 | 80 | Differences between the two libraries become much more pronounced when 81 | considering the file size of the generated Python plugin: for the largest file, 82 | the binary generated by Boost.Python required 16.8 MiB, which was **2.17 83 | times** / **9.1 megabytes** larger than the output generated by pybind11. For 84 | very small inputs, Boost.Python has an edge in the plot below -- however, note 85 | that it stores many definitions in an external library, whose size was not 86 | included here, hence the comparison is slightly shifted in Boost.Python's 87 | favor. 88 | 89 | .. only:: not latex 90 | 91 | .. image:: pybind11_vs_boost_python2.svg 92 | 93 | .. only:: latex 94 | 95 | .. image:: pybind11_vs_boost_python2.png 96 | 97 | 98 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/index.rst: -------------------------------------------------------------------------------- 1 | .. only: not latex 2 | 3 | .. image:: pybind11-logo.png 4 | 5 | pybind11 --- Seamless operability between C++11 and Python 6 | ========================================================== 7 | 8 | .. only: not latex 9 | 10 | Contents: 11 | 12 | .. toctree:: 13 | :maxdepth: 1 14 | 15 | intro 16 | changelog 17 | upgrade 18 | 19 | .. toctree:: 20 | :caption: The Basics 21 | :maxdepth: 2 22 | 23 | basics 24 | classes 25 | compiling 26 | 27 | .. toctree:: 28 | :caption: Advanced Topics 29 | :maxdepth: 2 30 | 31 | advanced/functions 32 | advanced/classes 33 | advanced/exceptions 34 | advanced/smart_ptrs 35 | advanced/cast/index 36 | advanced/pycpp/index 37 | advanced/embedding 38 | advanced/misc 39 | 40 | .. toctree:: 41 | :caption: Extra Information 42 | :maxdepth: 1 43 | 44 | faq 45 | benchmark 46 | limitations 47 | reference 48 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/limitations.rst: -------------------------------------------------------------------------------- 1 | Limitations 2 | ########### 3 | 4 | pybind11 strives to be a general solution to binding generation, but it also has 5 | certain limitations: 6 | 7 | - pybind11 casts away ``const``-ness in function arguments and return values. 8 | This is in line with the Python language, which has no concept of ``const`` 9 | values. This means that some additional care is needed to avoid bugs that 10 | would be caught by the type checker in a traditional C++ program. 11 | 12 | - The NumPy interface ``pybind11::array`` greatly simplifies accessing 13 | numerical data from C++ (and vice versa), but it's not a full-blown array 14 | class like ``Eigen::Array`` or ``boost.multi_array``. 15 | 16 | These features could be implemented but would lead to a significant increase in 17 | complexity. I've decided to draw the line here to keep this project simple and 18 | compact. Users who absolutely require these features are encouraged to fork 19 | pybind11. 20 | 21 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/pybind11-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/pybind11/docs/pybind11-logo.png -------------------------------------------------------------------------------- /c_segment/pybind11/docs/pybind11_vs_boost_python1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/pybind11/docs/pybind11_vs_boost_python1.png -------------------------------------------------------------------------------- /c_segment/pybind11/docs/pybind11_vs_boost_python2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/pybind11/docs/pybind11_vs_boost_python2.png -------------------------------------------------------------------------------- /c_segment/pybind11/docs/reference.rst: -------------------------------------------------------------------------------- 1 | .. _reference: 2 | 3 | .. warning:: 4 | 5 | Please be advised that the reference documentation discussing pybind11 6 | internals is currently incomplete. Please refer to the previous sections 7 | and the pybind11 header files for the nitty gritty details. 8 | 9 | Reference 10 | ######### 11 | 12 | .. _macros: 13 | 14 | Macros 15 | ====== 16 | 17 | .. doxygendefine:: PYBIND11_MODULE 18 | 19 | .. _core_types: 20 | 21 | Convenience classes for arbitrary Python types 22 | ============================================== 23 | 24 | Common member functions 25 | ----------------------- 26 | 27 | .. doxygenclass:: object_api 28 | :members: 29 | 30 | Without reference counting 31 | -------------------------- 32 | 33 | .. doxygenclass:: handle 34 | :members: 35 | 36 | With reference counting 37 | ----------------------- 38 | 39 | .. doxygenclass:: object 40 | :members: 41 | 42 | .. doxygenfunction:: reinterpret_borrow 43 | 44 | .. doxygenfunction:: reinterpret_steal 45 | 46 | Convenience classes for specific Python types 47 | ============================================= 48 | 49 | .. doxygenclass:: module 50 | :members: 51 | 52 | .. doxygengroup:: pytypes 53 | :members: 54 | 55 | .. _extras: 56 | 57 | Passing extra arguments to ``def`` or ``class_`` 58 | ================================================ 59 | 60 | .. doxygengroup:: annotations 61 | :members: 62 | 63 | Embedding the interpreter 64 | ========================= 65 | 66 | .. doxygendefine:: PYBIND11_EMBEDDED_MODULE 67 | 68 | .. doxygenfunction:: initialize_interpreter 69 | 70 | .. doxygenfunction:: finalize_interpreter 71 | 72 | .. doxygenclass:: scoped_interpreter 73 | 74 | Redirecting C++ streams 75 | ======================= 76 | 77 | .. doxygenclass:: scoped_ostream_redirect 78 | 79 | .. doxygenclass:: scoped_estream_redirect 80 | 81 | .. doxygenfunction:: add_ostream_redirect 82 | 83 | Python built-in functions 84 | ========================= 85 | 86 | .. doxygengroup:: python_builtins 87 | :members: 88 | 89 | Exceptions 90 | ========== 91 | 92 | .. doxygenclass:: error_already_set 93 | :members: 94 | 95 | .. doxygenclass:: builtin_exception 96 | :members: 97 | 98 | 99 | Literals 100 | ======== 101 | 102 | .. doxygennamespace:: literals 103 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/release.rst: -------------------------------------------------------------------------------- 1 | To release a new version of pybind11: 2 | 3 | - Update the version number and push to pypi 4 | - Update ``pybind11/_version.py`` (set release version, remove 'dev'). 5 | - Update ``PYBIND11_VERSION_MAJOR`` etc. in ``include/pybind11/detail/common.h``. 6 | - Ensure that all the information in ``setup.py`` is up-to-date. 7 | - Update version in ``docs/conf.py``. 8 | - Tag release date in ``docs/changelog.rst``. 9 | - ``git add`` and ``git commit``. 10 | - if new minor version: ``git checkout -b vX.Y``, ``git push -u origin vX.Y`` 11 | - ``git tag -a vX.Y.Z -m 'vX.Y.Z release'``. 12 | - ``git push`` 13 | - ``git push --tags``. 14 | - ``python setup.py sdist upload``. 15 | - ``python setup.py bdist_wheel upload``. 16 | - Update conda-forge (https://github.com/conda-forge/pybind11-feedstock) via PR 17 | - download release package from Github: ``wget https://github.com/pybind/pybind11/archive/vX.Y.Z.tar.gz`` 18 | - compute checksum: ``shasum -a 256 vX.Y.Z.tar.gz`` 19 | - change version number and checksum in ``recipe/meta.yml`` 20 | - Get back to work 21 | - Update ``_version.py`` (add 'dev' and increment minor). 22 | - Update version in ``docs/conf.py`` 23 | - Update version macros in ``include/pybind11/common.h`` 24 | - ``git add`` and ``git commit``. 25 | ``git push`` 26 | -------------------------------------------------------------------------------- /c_segment/pybind11/docs/requirements.txt: -------------------------------------------------------------------------------- 1 | breathe == 4.5.0 2 | -------------------------------------------------------------------------------- /c_segment/pybind11/include/pybind11/common.h: -------------------------------------------------------------------------------- 1 | #include "detail/common.h" 2 | #warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'." 3 | -------------------------------------------------------------------------------- /c_segment/pybind11/include/pybind11/complex.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/complex.h: Complex number support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | /// glibc defines I as a macro which breaks things, e.g., boost template names 16 | #ifdef I 17 | # undef I 18 | #endif 19 | 20 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 21 | 22 | template struct format_descriptor, detail::enable_if_t::value>> { 23 | static constexpr const char c = format_descriptor::c; 24 | static constexpr const char value[3] = { 'Z', c, '\0' }; 25 | static std::string format() { return std::string(value); } 26 | }; 27 | 28 | #ifndef PYBIND11_CPP17 29 | 30 | template constexpr const char format_descriptor< 31 | std::complex, detail::enable_if_t::value>>::value[3]; 32 | 33 | #endif 34 | 35 | NAMESPACE_BEGIN(detail) 36 | 37 | template struct is_fmt_numeric, detail::enable_if_t::value>> { 38 | static constexpr bool value = true; 39 | static constexpr int index = is_fmt_numeric::index + 3; 40 | }; 41 | 42 | template class type_caster> { 43 | public: 44 | bool load(handle src, bool convert) { 45 | if (!src) 46 | return false; 47 | if (!convert && !PyComplex_Check(src.ptr())) 48 | return false; 49 | Py_complex result = PyComplex_AsCComplex(src.ptr()); 50 | if (result.real == -1.0 && PyErr_Occurred()) { 51 | PyErr_Clear(); 52 | return false; 53 | } 54 | value = std::complex((T) result.real, (T) result.imag); 55 | return true; 56 | } 57 | 58 | static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { 59 | return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); 60 | } 61 | 62 | PYBIND11_TYPE_CASTER(std::complex, _("complex")); 63 | }; 64 | NAMESPACE_END(detail) 65 | NAMESPACE_END(PYBIND11_NAMESPACE) 66 | -------------------------------------------------------------------------------- /c_segment/pybind11/include/pybind11/detail/descr.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | NAMESPACE_BEGIN(detail) 16 | 17 | #if !defined(_MSC_VER) 18 | # define PYBIND11_DESCR_CONSTEXPR static constexpr 19 | #else 20 | # define PYBIND11_DESCR_CONSTEXPR const 21 | #endif 22 | 23 | /* Concatenate type signatures at compile time */ 24 | template 25 | struct descr { 26 | char text[N + 1]; 27 | 28 | constexpr descr() : text{'\0'} { } 29 | constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { } 30 | 31 | template 32 | constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { } 33 | 34 | template 35 | constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { } 36 | 37 | static constexpr std::array types() { 38 | return {{&typeid(Ts)..., nullptr}}; 39 | } 40 | }; 41 | 42 | template 43 | constexpr descr plus_impl(const descr &a, const descr &b, 44 | index_sequence, index_sequence) { 45 | return {a.text[Is1]..., b.text[Is2]...}; 46 | } 47 | 48 | template 49 | constexpr descr operator+(const descr &a, const descr &b) { 50 | return plus_impl(a, b, make_index_sequence(), make_index_sequence()); 51 | } 52 | 53 | template 54 | constexpr descr _(char const(&text)[N]) { return descr(text); } 55 | constexpr descr<0> _(char const(&)[1]) { return {}; } 56 | 57 | template struct int_to_str : int_to_str { }; 58 | template struct int_to_str<0, Digits...> { 59 | static constexpr auto digits = descr(('0' + Digits)...); 60 | }; 61 | 62 | // Ternary description (like std::conditional) 63 | template 64 | constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) { 65 | return _(text1); 66 | } 67 | template 68 | constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) { 69 | return _(text2); 70 | } 71 | 72 | template 73 | constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } 74 | template 75 | constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } 76 | 77 | template auto constexpr _() -> decltype(int_to_str::digits) { 78 | return int_to_str::digits; 79 | } 80 | 81 | template constexpr descr<1, Type> _() { return {'%'}; } 82 | 83 | constexpr descr<0> concat() { return {}; } 84 | 85 | template 86 | constexpr descr concat(const descr &descr) { return descr; } 87 | 88 | template 89 | constexpr auto concat(const descr &d, const Args &...args) 90 | -> decltype(std::declval>() + concat(args...)) { 91 | return d + _(", ") + concat(args...); 92 | } 93 | 94 | template 95 | constexpr descr type_descr(const descr &descr) { 96 | return _("{") + descr + _("}"); 97 | } 98 | 99 | NAMESPACE_END(detail) 100 | NAMESPACE_END(PYBIND11_NAMESPACE) 101 | -------------------------------------------------------------------------------- /c_segment/pybind11/include/pybind11/detail/typeid.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/typeid.h: Compiler-independent access to type identifiers 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #if defined(__GNUG__) 16 | #include 17 | #endif 18 | 19 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 20 | NAMESPACE_BEGIN(detail) 21 | /// Erase all occurrences of a substring 22 | inline void erase_all(std::string &string, const std::string &search) { 23 | for (size_t pos = 0;;) { 24 | pos = string.find(search, pos); 25 | if (pos == std::string::npos) break; 26 | string.erase(pos, search.length()); 27 | } 28 | } 29 | 30 | PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { 31 | #if defined(__GNUG__) 32 | int status = 0; 33 | std::unique_ptr res { 34 | abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; 35 | if (status == 0) 36 | name = res.get(); 37 | #else 38 | detail::erase_all(name, "class "); 39 | detail::erase_all(name, "struct "); 40 | detail::erase_all(name, "enum "); 41 | #endif 42 | detail::erase_all(name, "pybind11::"); 43 | } 44 | NAMESPACE_END(detail) 45 | 46 | /// Return a string representation of a C++ type 47 | template static std::string type_id() { 48 | std::string name(typeid(T).name()); 49 | detail::clean_type_id(name); 50 | return name; 51 | } 52 | 53 | NAMESPACE_END(PYBIND11_NAMESPACE) 54 | -------------------------------------------------------------------------------- /c_segment/pybind11/include/pybind11/functional.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/functional.h: std::function<> support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 16 | NAMESPACE_BEGIN(detail) 17 | 18 | template 19 | struct type_caster> { 20 | using type = std::function; 21 | using retval_type = conditional_t::value, void_type, Return>; 22 | using function_type = Return (*) (Args...); 23 | 24 | public: 25 | bool load(handle src, bool convert) { 26 | if (src.is_none()) { 27 | // Defer accepting None to other overloads (if we aren't in convert mode): 28 | if (!convert) return false; 29 | return true; 30 | } 31 | 32 | if (!isinstance(src)) 33 | return false; 34 | 35 | auto func = reinterpret_borrow(src); 36 | 37 | /* 38 | When passing a C++ function as an argument to another C++ 39 | function via Python, every function call would normally involve 40 | a full C++ -> Python -> C++ roundtrip, which can be prohibitive. 41 | Here, we try to at least detect the case where the function is 42 | stateless (i.e. function pointer or lambda function without 43 | captured variables), in which case the roundtrip can be avoided. 44 | */ 45 | if (auto cfunc = func.cpp_function()) { 46 | auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); 47 | auto rec = (function_record *) c; 48 | 49 | if (rec && rec->is_stateless && 50 | same_type(typeid(function_type), *reinterpret_cast(rec->data[1]))) { 51 | struct capture { function_type f; }; 52 | value = ((capture *) &rec->data)->f; 53 | return true; 54 | } 55 | } 56 | 57 | value = [func](Args... args) -> Return { 58 | gil_scoped_acquire acq; 59 | object retval(func(std::forward(args)...)); 60 | /* Visual studio 2015 parser issue: need parentheses around this expression */ 61 | return (retval.template cast()); 62 | }; 63 | return true; 64 | } 65 | 66 | template 67 | static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { 68 | if (!f_) 69 | return none().inc_ref(); 70 | 71 | auto result = f_.template target(); 72 | if (result) 73 | return cpp_function(*result, policy).release(); 74 | else 75 | return cpp_function(std::forward(f_), policy).release(); 76 | } 77 | 78 | PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster::name...) + _("], ") 79 | + make_caster::name + _("]")); 80 | }; 81 | 82 | NAMESPACE_END(detail) 83 | NAMESPACE_END(PYBIND11_NAMESPACE) 84 | -------------------------------------------------------------------------------- /c_segment/pybind11/include/pybind11/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/options.h: global settings that are configurable at runtime. 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "detail/common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | 16 | class options { 17 | public: 18 | 19 | // Default RAII constructor, which leaves settings as they currently are. 20 | options() : previous_state(global_state()) {} 21 | 22 | // Class is non-copyable. 23 | options(const options&) = delete; 24 | options& operator=(const options&) = delete; 25 | 26 | // Destructor, which restores settings that were in effect before. 27 | ~options() { 28 | global_state() = previous_state; 29 | } 30 | 31 | // Setter methods (affect the global state): 32 | 33 | options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } 34 | 35 | options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } 36 | 37 | options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } 38 | 39 | options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } 40 | 41 | // Getter methods (return the global state): 42 | 43 | static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } 44 | 45 | static bool show_function_signatures() { return global_state().show_function_signatures; } 46 | 47 | // This type is not meant to be allocated on the heap. 48 | void* operator new(size_t) = delete; 49 | 50 | private: 51 | 52 | struct state { 53 | bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. 54 | bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. 55 | }; 56 | 57 | static state &global_state() { 58 | static state instance; 59 | return instance; 60 | } 61 | 62 | state previous_state; 63 | }; 64 | 65 | NAMESPACE_END(PYBIND11_NAMESPACE) 66 | -------------------------------------------------------------------------------- /c_segment/pybind11/pybind11/__init__.py: -------------------------------------------------------------------------------- 1 | from ._version import version_info, __version__ # noqa: F401 imported but unused 2 | 3 | 4 | def get_include(user=False): 5 | from distutils.dist import Distribution 6 | import os 7 | import sys 8 | 9 | # Are we running in a virtual environment? 10 | virtualenv = hasattr(sys, 'real_prefix') or \ 11 | sys.prefix != getattr(sys, "base_prefix", sys.prefix) 12 | 13 | if virtualenv: 14 | return os.path.join(sys.prefix, 'include', 'site', 15 | 'python' + sys.version[:3]) 16 | else: 17 | dist = Distribution({'name': 'pybind11'}) 18 | dist.parse_config_files() 19 | 20 | dist_cobj = dist.get_command_obj('install', create=True) 21 | 22 | # Search for packages in user's home directory? 23 | if user: 24 | dist_cobj.user = user 25 | dist_cobj.prefix = "" 26 | dist_cobj.finalize_options() 27 | 28 | return os.path.dirname(dist_cobj.install_headers) 29 | -------------------------------------------------------------------------------- /c_segment/pybind11/pybind11/__main__.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import argparse 4 | import sys 5 | import sysconfig 6 | 7 | from . import get_include 8 | 9 | 10 | def print_includes(): 11 | dirs = [sysconfig.get_path('include'), 12 | sysconfig.get_path('platinclude'), 13 | get_include(), 14 | get_include(True)] 15 | 16 | # Make unique but preserve order 17 | unique_dirs = [] 18 | for d in dirs: 19 | if d not in unique_dirs: 20 | unique_dirs.append(d) 21 | 22 | print(' '.join('-I' + d for d in unique_dirs)) 23 | 24 | 25 | def main(): 26 | parser = argparse.ArgumentParser(prog='python -m pybind11') 27 | parser.add_argument('--includes', action='store_true', 28 | help='Include flags for both pybind11 and Python headers.') 29 | args = parser.parse_args() 30 | if not sys.argv[1:]: 31 | parser.print_help() 32 | if args.includes: 33 | print_includes() 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /c_segment/pybind11/pybind11/_version.py: -------------------------------------------------------------------------------- 1 | version_info = (2, 3, 'dev0') 2 | __version__ = '.'.join(map(str, version_info)) 3 | -------------------------------------------------------------------------------- /c_segment/pybind11/setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | 4 | [flake8] 5 | max-line-length = 99 6 | show_source = True 7 | exclude = .git, __pycache__, build, dist, docs, tools, venv 8 | ignore = 9 | # required for pretty matrix formatting: multiple spaces after `,` and `[` 10 | E201, E241, W504, 11 | # camelcase 'cPickle' imported as lowercase 'pickle' 12 | N813 13 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/local_bindings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "pybind11_tests.h" 3 | 4 | /// Simple class used to test py::local: 5 | template class LocalBase { 6 | public: 7 | LocalBase(int i) : i(i) { } 8 | int i = -1; 9 | }; 10 | 11 | /// Registered with py::module_local in both main and secondary modules: 12 | using LocalType = LocalBase<0>; 13 | /// Registered without py::module_local in both modules: 14 | using NonLocalType = LocalBase<1>; 15 | /// A second non-local type (for stl_bind tests): 16 | using NonLocal2 = LocalBase<2>; 17 | /// Tests within-module, different-compilation-unit local definition conflict: 18 | using LocalExternal = LocalBase<3>; 19 | /// Mixed: registered local first, then global 20 | using MixedLocalGlobal = LocalBase<4>; 21 | /// Mixed: global first, then local 22 | using MixedGlobalLocal = LocalBase<5>; 23 | 24 | /// Registered with py::module_local only in the secondary module: 25 | using ExternalType1 = LocalBase<6>; 26 | using ExternalType2 = LocalBase<7>; 27 | 28 | using LocalVec = std::vector; 29 | using LocalVec2 = std::vector; 30 | using LocalMap = std::unordered_map; 31 | using NonLocalVec = std::vector; 32 | using NonLocalVec2 = std::vector; 33 | using NonLocalMap = std::unordered_map; 34 | using NonLocalMap2 = std::unordered_map; 35 | 36 | PYBIND11_MAKE_OPAQUE(LocalVec); 37 | PYBIND11_MAKE_OPAQUE(LocalVec2); 38 | PYBIND11_MAKE_OPAQUE(LocalMap); 39 | PYBIND11_MAKE_OPAQUE(NonLocalVec); 40 | //PYBIND11_MAKE_OPAQUE(NonLocalVec2); // same type as LocalVec2 41 | PYBIND11_MAKE_OPAQUE(NonLocalMap); 42 | PYBIND11_MAKE_OPAQUE(NonLocalMap2); 43 | 44 | 45 | // Simple bindings (used with the above): 46 | template 47 | py::class_ bind_local(Args && ...args) { 48 | return py::class_(std::forward(args)...) 49 | .def(py::init()) 50 | .def("get", [](T &i) { return i.i + Adjust; }); 51 | }; 52 | 53 | // Simulate a foreign library base class (to match the example in the docs): 54 | namespace pets { 55 | class Pet { 56 | public: 57 | Pet(std::string name) : name_(name) {} 58 | std::string name_; 59 | const std::string &name() { return name_; } 60 | }; 61 | } 62 | 63 | struct MixGL { int i; MixGL(int i) : i{i} {} }; 64 | struct MixGL2 { int i; MixGL2(int i) : i{i} {} }; 65 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/pybind11_tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/pybind11_tests.cpp -- pybind example plugin 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | #include "constructor_stats.h" 12 | 13 | #include 14 | #include 15 | 16 | /* 17 | For testing purposes, we define a static global variable here in a function that each individual 18 | test .cpp calls with its initialization lambda. It's convenient here because we can just not 19 | compile some test files to disable/ignore some of the test code. 20 | 21 | It is NOT recommended as a way to use pybind11 in practice, however: the initialization order will 22 | be essentially random, which is okay for our test scripts (there are no dependencies between the 23 | individual pybind11 test .cpp files), but most likely not what you want when using pybind11 24 | productively. 25 | 26 | Instead, see the "How can I reduce the build time?" question in the "Frequently asked questions" 27 | section of the documentation for good practice on splitting binding code over multiple files. 28 | */ 29 | std::list> &initializers() { 30 | static std::list> inits; 31 | return inits; 32 | } 33 | 34 | test_initializer::test_initializer(Initializer init) { 35 | initializers().push_back(init); 36 | } 37 | 38 | test_initializer::test_initializer(const char *submodule_name, Initializer init) { 39 | initializers().push_back([=](py::module &parent) { 40 | auto m = parent.def_submodule(submodule_name); 41 | init(m); 42 | }); 43 | } 44 | 45 | void bind_ConstructorStats(py::module &m) { 46 | py::class_(m, "ConstructorStats") 47 | .def("alive", &ConstructorStats::alive) 48 | .def("values", &ConstructorStats::values) 49 | .def_readwrite("default_constructions", &ConstructorStats::default_constructions) 50 | .def_readwrite("copy_assignments", &ConstructorStats::copy_assignments) 51 | .def_readwrite("move_assignments", &ConstructorStats::move_assignments) 52 | .def_readwrite("copy_constructions", &ConstructorStats::copy_constructions) 53 | .def_readwrite("move_constructions", &ConstructorStats::move_constructions) 54 | .def_static("get", (ConstructorStats &(*)(py::object)) &ConstructorStats::get, py::return_value_policy::reference_internal) 55 | 56 | // Not exactly ConstructorStats, but related: expose the internal pybind number of registered instances 57 | // to allow instance cleanup checks (invokes a GC first) 58 | .def_static("detail_reg_inst", []() { 59 | ConstructorStats::gc(); 60 | return py::detail::get_internals().registered_instances.size(); 61 | }) 62 | ; 63 | } 64 | 65 | PYBIND11_MODULE(pybind11_tests, m) { 66 | m.doc() = "pybind11 test module"; 67 | 68 | bind_ConstructorStats(m); 69 | 70 | #if !defined(NDEBUG) 71 | m.attr("debug_enabled") = true; 72 | #else 73 | m.attr("debug_enabled") = false; 74 | #endif 75 | 76 | py::class_(m, "UserType", "A `py::class_` type for testing") 77 | .def(py::init<>()) 78 | .def(py::init()) 79 | .def("get_value", &UserType::value, "Get value using a method") 80 | .def("set_value", &UserType::set, "Set value using a method") 81 | .def_property("value", &UserType::value, &UserType::set, "Get/set value using a property") 82 | .def("__repr__", [](const UserType& u) { return "UserType({})"_s.format(u.value()); }); 83 | 84 | py::class_(m, "IncType") 85 | .def(py::init<>()) 86 | .def(py::init()) 87 | .def("__repr__", [](const IncType& u) { return "IncType({})"_s.format(u.value()); }); 88 | 89 | for (const auto &initializer : initializers()) 90 | initializer(m); 91 | 92 | if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = false; 93 | } 94 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/pybind11_tests.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #if defined(_MSC_VER) && _MSC_VER < 1910 5 | // We get some really long type names here which causes MSVC 2015 to emit warnings 6 | # pragma warning(disable: 4503) // warning C4503: decorated name length exceeded, name was truncated 7 | #endif 8 | 9 | namespace py = pybind11; 10 | using namespace pybind11::literals; 11 | 12 | class test_initializer { 13 | using Initializer = void (*)(py::module &); 14 | 15 | public: 16 | test_initializer(Initializer init); 17 | test_initializer(const char *submodule_name, Initializer init); 18 | }; 19 | 20 | #define TEST_SUBMODULE(name, variable) \ 21 | void test_submodule_##name(py::module &); \ 22 | test_initializer name(#name, test_submodule_##name); \ 23 | void test_submodule_##name(py::module &variable) 24 | 25 | 26 | /// Dummy type which is not exported anywhere -- something to trigger a conversion error 27 | struct UnregisteredType { }; 28 | 29 | /// A user-defined type which is exported and can be used by any test 30 | class UserType { 31 | public: 32 | UserType() = default; 33 | UserType(int i) : i(i) { } 34 | 35 | int value() const { return i; } 36 | void set(int set) { i = set; } 37 | 38 | private: 39 | int i = -1; 40 | }; 41 | 42 | /// Like UserType, but increments `value` on copy for quick reference vs. copy tests 43 | class IncType : public UserType { 44 | public: 45 | using UserType::UserType; 46 | IncType() = default; 47 | IncType(const IncType &other) : IncType(other.value() + 1) { } 48 | IncType(IncType &&) = delete; 49 | IncType &operator=(const IncType &) = delete; 50 | IncType &operator=(IncType &&) = delete; 51 | }; 52 | 53 | /// Custom cast-only type that casts to a string "rvalue" or "lvalue" depending on the cast context. 54 | /// Used to test recursive casters (e.g. std::tuple, stl containers). 55 | struct RValueCaster {}; 56 | NAMESPACE_BEGIN(pybind11) 57 | NAMESPACE_BEGIN(detail) 58 | template<> class type_caster { 59 | public: 60 | PYBIND11_TYPE_CASTER(RValueCaster, _("RValueCaster")); 61 | static handle cast(RValueCaster &&, return_value_policy, handle) { return py::str("rvalue").release(); } 62 | static handle cast(const RValueCaster &, return_value_policy, handle) { return py::str("lvalue").release(); } 63 | }; 64 | NAMESPACE_END(detail) 65 | NAMESPACE_END(pybind11) 66 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | minversion = 3.0 3 | norecursedirs = test_cmake_build test_embed 4 | addopts = 5 | # show summary of skipped tests 6 | -rs 7 | # capture only Python print and C++ py::print, but not C output (low-level Python errors) 8 | --capture=sys 9 | filterwarnings = 10 | # make warnings into errors but ignore certain third-party extension issues 11 | error 12 | # importing scipy submodules on some version of Python 13 | ignore::ImportWarning 14 | # bogus numpy ABI warning (see numpy/#432) 15 | ignore:.*numpy.dtype size changed.*:RuntimeWarning 16 | ignore:.*numpy.ufunc size changed.*:RuntimeWarning 17 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_buffers.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import pytest 3 | from pybind11_tests import buffers as m 4 | from pybind11_tests import ConstructorStats 5 | 6 | pytestmark = pytest.requires_numpy 7 | 8 | with pytest.suppress(ImportError): 9 | import numpy as np 10 | 11 | 12 | def test_from_python(): 13 | with pytest.raises(RuntimeError) as excinfo: 14 | m.Matrix(np.array([1, 2, 3])) # trying to assign a 1D array 15 | assert str(excinfo.value) == "Incompatible buffer format!" 16 | 17 | m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32) 18 | m4 = m.Matrix(m3) 19 | 20 | for i in range(m4.rows()): 21 | for j in range(m4.cols()): 22 | assert m3[i, j] == m4[i, j] 23 | 24 | cstats = ConstructorStats.get(m.Matrix) 25 | assert cstats.alive() == 1 26 | del m3, m4 27 | assert cstats.alive() == 0 28 | assert cstats.values() == ["2x3 matrix"] 29 | assert cstats.copy_constructions == 0 30 | # assert cstats.move_constructions >= 0 # Don't invoke any 31 | assert cstats.copy_assignments == 0 32 | assert cstats.move_assignments == 0 33 | 34 | 35 | # PyPy: Memory leak in the "np.array(m, copy=False)" call 36 | # https://bitbucket.org/pypy/pypy/issues/2444 37 | @pytest.unsupported_on_pypy 38 | def test_to_python(): 39 | mat = m.Matrix(5, 4) 40 | assert memoryview(mat).shape == (5, 4) 41 | 42 | assert mat[2, 3] == 0 43 | mat[2, 3] = 4.0 44 | mat[3, 2] = 7.0 45 | assert mat[2, 3] == 4 46 | assert mat[3, 2] == 7 47 | assert struct.unpack_from('f', mat, (3 * 4 + 2) * 4) == (7, ) 48 | assert struct.unpack_from('f', mat, (2 * 4 + 3) * 4) == (4, ) 49 | 50 | mat2 = np.array(mat, copy=False) 51 | assert mat2.shape == (5, 4) 52 | assert abs(mat2).sum() == 11 53 | assert mat2[2, 3] == 4 and mat2[3, 2] == 7 54 | mat2[2, 3] = 5 55 | assert mat2[2, 3] == 5 56 | 57 | cstats = ConstructorStats.get(m.Matrix) 58 | assert cstats.alive() == 1 59 | del mat 60 | pytest.gc_collect() 61 | assert cstats.alive() == 1 62 | del mat2 # holds a mat reference 63 | pytest.gc_collect() 64 | assert cstats.alive() == 0 65 | assert cstats.values() == ["5x4 matrix"] 66 | assert cstats.copy_constructions == 0 67 | # assert cstats.move_constructions >= 0 # Don't invoke any 68 | assert cstats.copy_assignments == 0 69 | assert cstats.move_assignments == 0 70 | 71 | 72 | @pytest.unsupported_on_pypy 73 | def test_inherited_protocol(): 74 | """SquareMatrix is derived from Matrix and inherits the buffer protocol""" 75 | 76 | matrix = m.SquareMatrix(5) 77 | assert memoryview(matrix).shape == (5, 5) 78 | assert np.asarray(matrix).shape == (5, 5) 79 | 80 | 81 | @pytest.unsupported_on_pypy 82 | def test_pointer_to_member_fn(): 83 | for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]: 84 | buf = cls() 85 | buf.value = 0x12345678 86 | value = struct.unpack('i', bytearray(buf))[0] 87 | assert value == 0x12345678 88 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_call_policies.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_call_policies.cpp -- keep_alive and call_guard 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | 12 | struct CustomGuard { 13 | static bool enabled; 14 | 15 | CustomGuard() { enabled = true; } 16 | ~CustomGuard() { enabled = false; } 17 | 18 | static const char *report_status() { return enabled ? "guarded" : "unguarded"; } 19 | }; 20 | bool CustomGuard::enabled = false; 21 | 22 | struct DependentGuard { 23 | static bool enabled; 24 | 25 | DependentGuard() { enabled = CustomGuard::enabled; } 26 | ~DependentGuard() { enabled = false; } 27 | 28 | static const char *report_status() { return enabled ? "guarded" : "unguarded"; } 29 | }; 30 | bool DependentGuard::enabled = false; 31 | 32 | TEST_SUBMODULE(call_policies, m) { 33 | // Parent/Child are used in: 34 | // test_keep_alive_argument, test_keep_alive_return_value, test_alive_gc_derived, 35 | // test_alive_gc_multi_derived, test_return_none, test_keep_alive_constructor 36 | class Child { 37 | public: 38 | Child() { py::print("Allocating child."); } 39 | Child(const Child &) = default; 40 | Child(Child &&) = default; 41 | ~Child() { py::print("Releasing child."); } 42 | }; 43 | py::class_(m, "Child") 44 | .def(py::init<>()); 45 | 46 | class Parent { 47 | public: 48 | Parent() { py::print("Allocating parent."); } 49 | ~Parent() { py::print("Releasing parent."); } 50 | void addChild(Child *) { } 51 | Child *returnChild() { return new Child(); } 52 | Child *returnNullChild() { return nullptr; } 53 | }; 54 | py::class_(m, "Parent") 55 | .def(py::init<>()) 56 | .def(py::init([](Child *) { return new Parent(); }), py::keep_alive<1, 2>()) 57 | .def("addChild", &Parent::addChild) 58 | .def("addChildKeepAlive", &Parent::addChild, py::keep_alive<1, 2>()) 59 | .def("returnChild", &Parent::returnChild) 60 | .def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>()) 61 | .def("returnNullChildKeepAliveChild", &Parent::returnNullChild, py::keep_alive<1, 0>()) 62 | .def("returnNullChildKeepAliveParent", &Parent::returnNullChild, py::keep_alive<0, 1>()); 63 | 64 | #if !defined(PYPY_VERSION) 65 | // test_alive_gc 66 | class ParentGC : public Parent { 67 | public: 68 | using Parent::Parent; 69 | }; 70 | py::class_(m, "ParentGC", py::dynamic_attr()) 71 | .def(py::init<>()); 72 | #endif 73 | 74 | // test_call_guard 75 | m.def("unguarded_call", &CustomGuard::report_status); 76 | m.def("guarded_call", &CustomGuard::report_status, py::call_guard()); 77 | 78 | m.def("multiple_guards_correct_order", []() { 79 | return CustomGuard::report_status() + std::string(" & ") + DependentGuard::report_status(); 80 | }, py::call_guard()); 81 | 82 | m.def("multiple_guards_wrong_order", []() { 83 | return DependentGuard::report_status() + std::string(" & ") + CustomGuard::report_status(); 84 | }, py::call_guard()); 85 | 86 | #if defined(WITH_THREAD) && !defined(PYPY_VERSION) 87 | // `py::call_guard()` should work in PyPy as well, 88 | // but it's unclear how to test it without `PyGILState_GetThisThreadState`. 89 | auto report_gil_status = []() { 90 | auto is_gil_held = false; 91 | if (auto tstate = py::detail::get_thread_state_unchecked()) 92 | is_gil_held = (tstate == PyGILState_GetThisThreadState()); 93 | 94 | return is_gil_held ? "GIL held" : "GIL released"; 95 | }; 96 | 97 | m.def("with_gil", report_gil_status); 98 | m.def("without_gil", report_gil_status, py::call_guard()); 99 | #endif 100 | } 101 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_chrono.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_chrono.cpp -- test conversions to/from std::chrono types 3 | 4 | Copyright (c) 2016 Trent Houliston and 5 | Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #include "pybind11_tests.h" 12 | #include 13 | 14 | TEST_SUBMODULE(chrono, m) { 15 | using system_time = std::chrono::system_clock::time_point; 16 | using steady_time = std::chrono::steady_clock::time_point; 17 | // test_chrono_system_clock 18 | // Return the current time off the wall clock 19 | m.def("test_chrono1", []() { return std::chrono::system_clock::now(); }); 20 | 21 | // test_chrono_system_clock_roundtrip 22 | // Round trip the passed in system clock time 23 | m.def("test_chrono2", [](system_time t) { return t; }); 24 | 25 | // test_chrono_duration_roundtrip 26 | // Round trip the passed in duration 27 | m.def("test_chrono3", [](std::chrono::system_clock::duration d) { return d; }); 28 | 29 | // test_chrono_duration_subtraction_equivalence 30 | // Difference between two passed in time_points 31 | m.def("test_chrono4", [](system_time a, system_time b) { return a - b; }); 32 | 33 | // test_chrono_steady_clock 34 | // Return the current time off the steady_clock 35 | m.def("test_chrono5", []() { return std::chrono::steady_clock::now(); }); 36 | 37 | // test_chrono_steady_clock_roundtrip 38 | // Round trip a steady clock timepoint 39 | m.def("test_chrono6", [](steady_time t) { return t; }); 40 | 41 | // test_floating_point_duration 42 | // Roundtrip a duration in microseconds from a float argument 43 | m.def("test_chrono7", [](std::chrono::microseconds t) { return t; }); 44 | // Float durations (issue #719) 45 | m.def("test_chrono_float_diff", [](std::chrono::duration a, std::chrono::duration b) { 46 | return a - b; }); 47 | } 48 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_chrono.py: -------------------------------------------------------------------------------- 1 | from pybind11_tests import chrono as m 2 | import datetime 3 | 4 | 5 | def test_chrono_system_clock(): 6 | 7 | # Get the time from both c++ and datetime 8 | date1 = m.test_chrono1() 9 | date2 = datetime.datetime.today() 10 | 11 | # The returned value should be a datetime 12 | assert isinstance(date1, datetime.datetime) 13 | 14 | # The numbers should vary by a very small amount (time it took to execute) 15 | diff = abs(date1 - date2) 16 | 17 | # There should never be a days/seconds difference 18 | assert diff.days == 0 19 | assert diff.seconds == 0 20 | 21 | # We test that no more than about 0.5 seconds passes here 22 | # This makes sure that the dates created are very close to the same 23 | # but if the testing system is incredibly overloaded this should still pass 24 | assert diff.microseconds < 500000 25 | 26 | 27 | def test_chrono_system_clock_roundtrip(): 28 | date1 = datetime.datetime.today() 29 | 30 | # Roundtrip the time 31 | date2 = m.test_chrono2(date1) 32 | 33 | # The returned value should be a datetime 34 | assert isinstance(date2, datetime.datetime) 35 | 36 | # They should be identical (no information lost on roundtrip) 37 | diff = abs(date1 - date2) 38 | assert diff.days == 0 39 | assert diff.seconds == 0 40 | assert diff.microseconds == 0 41 | 42 | 43 | def test_chrono_duration_roundtrip(): 44 | 45 | # Get the difference between two times (a timedelta) 46 | date1 = datetime.datetime.today() 47 | date2 = datetime.datetime.today() 48 | diff = date2 - date1 49 | 50 | # Make sure this is a timedelta 51 | assert isinstance(diff, datetime.timedelta) 52 | 53 | cpp_diff = m.test_chrono3(diff) 54 | 55 | assert cpp_diff.days == diff.days 56 | assert cpp_diff.seconds == diff.seconds 57 | assert cpp_diff.microseconds == diff.microseconds 58 | 59 | 60 | def test_chrono_duration_subtraction_equivalence(): 61 | 62 | date1 = datetime.datetime.today() 63 | date2 = datetime.datetime.today() 64 | 65 | diff = date2 - date1 66 | cpp_diff = m.test_chrono4(date2, date1) 67 | 68 | assert cpp_diff.days == diff.days 69 | assert cpp_diff.seconds == diff.seconds 70 | assert cpp_diff.microseconds == diff.microseconds 71 | 72 | 73 | def test_chrono_steady_clock(): 74 | time1 = m.test_chrono5() 75 | assert isinstance(time1, datetime.timedelta) 76 | 77 | 78 | def test_chrono_steady_clock_roundtrip(): 79 | time1 = datetime.timedelta(days=10, seconds=10, microseconds=100) 80 | time2 = m.test_chrono6(time1) 81 | 82 | assert isinstance(time2, datetime.timedelta) 83 | 84 | # They should be identical (no information lost on roundtrip) 85 | assert time1.days == time2.days 86 | assert time1.seconds == time2.seconds 87 | assert time1.microseconds == time2.microseconds 88 | 89 | 90 | def test_floating_point_duration(): 91 | # Test using a floating point number in seconds 92 | time = m.test_chrono7(35.525123) 93 | 94 | assert isinstance(time, datetime.timedelta) 95 | 96 | assert time.seconds == 35 97 | assert 525122 <= time.microseconds <= 525123 98 | 99 | diff = m.test_chrono_float_diff(43.789012, 1.123456) 100 | assert diff.seconds == 42 101 | assert 665556 <= diff.microseconds <= 665557 102 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(test_cmake_build) 2 | 3 | if(CMAKE_VERSION VERSION_LESS 3.1) 4 | # 3.0 needed for interface library for subdirectory_target/installed_target 5 | # 3.1 needed for cmake -E env for testing 6 | return() 7 | endif() 8 | 9 | include(CMakeParseArguments) 10 | function(pybind11_add_build_test name) 11 | cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN}) 12 | 13 | set(build_options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/mock_install" 14 | "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" 15 | "-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}" 16 | "-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}") 17 | if(NOT ARG_INSTALL) 18 | list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${PROJECT_SOURCE_DIR}") 19 | endif() 20 | 21 | add_custom_target(test_${name} ${CMAKE_CTEST_COMMAND} 22 | --quiet --output-log ${name}.log 23 | --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/${name}" 24 | "${CMAKE_CURRENT_BINARY_DIR}/${name}" 25 | --build-config Release 26 | --build-noclean 27 | --build-generator ${CMAKE_GENERATOR} 28 | $<$:--build-generator-platform> ${CMAKE_GENERATOR_PLATFORM} 29 | --build-makeprogram ${CMAKE_MAKE_PROGRAM} 30 | --build-target check 31 | --build-options ${build_options} 32 | ) 33 | if(ARG_INSTALL) 34 | add_dependencies(test_${name} mock_install) 35 | endif() 36 | add_dependencies(test_cmake_build test_${name}) 37 | endfunction() 38 | 39 | pybind11_add_build_test(subdirectory_function) 40 | pybind11_add_build_test(subdirectory_target) 41 | if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy") 42 | pybind11_add_build_test(subdirectory_embed) 43 | endif() 44 | 45 | if(PYBIND11_INSTALL) 46 | add_custom_target(mock_install ${CMAKE_COMMAND} 47 | "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/mock_install" 48 | -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" 49 | ) 50 | 51 | pybind11_add_build_test(installed_function INSTALL) 52 | pybind11_add_build_test(installed_target INSTALL) 53 | if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy") 54 | pybind11_add_build_test(installed_embed INSTALL) 55 | endif() 56 | endif() 57 | 58 | add_dependencies(check test_cmake_build) 59 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/embed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | namespace py = pybind11; 3 | 4 | PYBIND11_EMBEDDED_MODULE(test_cmake_build, m) { 5 | m.def("add", [](int i, int j) { return i + j; }); 6 | } 7 | 8 | int main(int argc, char *argv[]) { 9 | if (argc != 2) 10 | throw std::runtime_error("Expected test.py file as the first argument"); 11 | auto test_py_file = argv[1]; 12 | 13 | py::scoped_interpreter guard{}; 14 | 15 | auto m = py::module::import("test_cmake_build"); 16 | if (m.attr("add")(1, 2).cast() != 3) 17 | throw std::runtime_error("embed.cpp failed"); 18 | 19 | py::module::import("sys").attr("argv") = py::make_tuple("test.py", "embed.cpp"); 20 | py::eval_file(test_py_file, py::globals()); 21 | } 22 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(test_installed_embed CXX) 3 | 4 | set(CMAKE_MODULE_PATH "") 5 | find_package(pybind11 CONFIG REQUIRED) 6 | message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") 7 | 8 | add_executable(test_cmake_build ../embed.cpp) 9 | target_link_libraries(test_cmake_build PRIVATE pybind11::embed) 10 | 11 | # Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::embed). 12 | # This may be needed to resolve header conflicts, e.g. between Python release and debug headers. 13 | set_target_properties(test_cmake_build PROPERTIES NO_SYSTEM_FROM_IMPORTED ON) 14 | 15 | add_custom_target(check $ ${PROJECT_SOURCE_DIR}/../test.py) 16 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(test_installed_module CXX) 3 | 4 | set(CMAKE_MODULE_PATH "") 5 | 6 | find_package(pybind11 CONFIG REQUIRED) 7 | message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") 8 | 9 | pybind11_add_module(test_cmake_build SHARED NO_EXTRAS ../main.cpp) 10 | 11 | add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ 12 | ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) 13 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(test_installed_target CXX) 3 | 4 | set(CMAKE_MODULE_PATH "") 5 | 6 | find_package(pybind11 CONFIG REQUIRED) 7 | message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") 8 | 9 | add_library(test_cmake_build MODULE ../main.cpp) 10 | 11 | target_link_libraries(test_cmake_build PRIVATE pybind11::module) 12 | 13 | # make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib 14 | set_target_properties(test_cmake_build PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" 15 | SUFFIX "${PYTHON_MODULE_EXTENSION}") 16 | 17 | # Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module). 18 | # This may be needed to resolve header conflicts, e.g. between Python release and debug headers. 19 | set_target_properties(test_cmake_build PROPERTIES NO_SYSTEM_FROM_IMPORTED ON) 20 | 21 | add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ 22 | ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) 23 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | namespace py = pybind11; 3 | 4 | PYBIND11_MODULE(test_cmake_build, m) { 5 | m.def("add", [](int i, int j) { return i + j; }); 6 | } 7 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(test_subdirectory_embed CXX) 3 | 4 | set(PYBIND11_INSTALL ON CACHE BOOL "") 5 | set(PYBIND11_EXPORT_NAME test_export) 6 | 7 | add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) 8 | 9 | # Test basic target functionality 10 | add_executable(test_cmake_build ../embed.cpp) 11 | target_link_libraries(test_cmake_build PRIVATE pybind11::embed) 12 | 13 | add_custom_target(check $ ${PROJECT_SOURCE_DIR}/../test.py) 14 | 15 | # Test custom export group -- PYBIND11_EXPORT_NAME 16 | add_library(test_embed_lib ../embed.cpp) 17 | target_link_libraries(test_embed_lib PRIVATE pybind11::embed) 18 | 19 | install(TARGETS test_embed_lib 20 | EXPORT test_export 21 | ARCHIVE DESTINATION bin 22 | LIBRARY DESTINATION lib 23 | RUNTIME DESTINATION lib) 24 | install(EXPORT test_export 25 | DESTINATION lib/cmake/test_export/test_export-Targets.cmake) 26 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(test_subdirectory_module CXX) 3 | 4 | add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) 5 | pybind11_add_module(test_cmake_build THIN_LTO ../main.cpp) 6 | 7 | add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ 8 | ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) 9 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0) 2 | project(test_subdirectory_target CXX) 3 | 4 | add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) 5 | 6 | add_library(test_cmake_build MODULE ../main.cpp) 7 | 8 | target_link_libraries(test_cmake_build PRIVATE pybind11::module) 9 | 10 | # make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib 11 | set_target_properties(test_cmake_build PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" 12 | SUFFIX "${PYTHON_MODULE_EXTENSION}") 13 | 14 | add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ 15 | ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) 16 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_cmake_build/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import test_cmake_build 3 | 4 | assert test_cmake_build.add(1, 2) == 3 5 | print("{} imports, runs, and adds: 1 + 2 = 3".format(sys.argv[1])) 6 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_constants_and_functions.py: -------------------------------------------------------------------------------- 1 | from pybind11_tests import constants_and_functions as m 2 | 3 | 4 | def test_constants(): 5 | assert m.some_constant == 14 6 | 7 | 8 | def test_function_overloading(): 9 | assert m.test_function() == "test_function()" 10 | assert m.test_function(7) == "test_function(7)" 11 | assert m.test_function(m.MyEnum.EFirstEntry) == "test_function(enum=1)" 12 | assert m.test_function(m.MyEnum.ESecondEntry) == "test_function(enum=2)" 13 | 14 | assert m.test_function() == "test_function()" 15 | assert m.test_function("abcd") == "test_function(char *)" 16 | assert m.test_function(1, 1.0) == "test_function(int, float)" 17 | assert m.test_function(1, 1.0) == "test_function(int, float)" 18 | assert m.test_function(2.0, 2) == "test_function(float, int)" 19 | 20 | 21 | def test_bytes(): 22 | assert m.print_bytes(m.return_bytes()) == "bytes[1 0 2 0]" 23 | 24 | 25 | def test_exception_specifiers(): 26 | c = m.C() 27 | assert c.m1(2) == 1 28 | assert c.m2(3) == 1 29 | assert c.m3(5) == 2 30 | assert c.m4(7) == 3 31 | assert c.m5(10) == 5 32 | assert c.m6(14) == 8 33 | assert c.m7(20) == 13 34 | assert c.m8(29) == 21 35 | 36 | assert m.f1(33) == 34 37 | assert m.f2(53) == 55 38 | assert m.f3(86) == 89 39 | assert m.f4(140) == 144 40 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_docstring_options.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_docstring_options.cpp -- generation of docstrings and signatures 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | 12 | TEST_SUBMODULE(docstring_options, m) { 13 | // test_docstring_options 14 | { 15 | py::options options; 16 | options.disable_function_signatures(); 17 | 18 | m.def("test_function1", [](int, int) {}, py::arg("a"), py::arg("b")); 19 | m.def("test_function2", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); 20 | 21 | m.def("test_overloaded1", [](int) {}, py::arg("i"), "Overload docstring"); 22 | m.def("test_overloaded1", [](double) {}, py::arg("d")); 23 | 24 | m.def("test_overloaded2", [](int) {}, py::arg("i"), "overload docstring 1"); 25 | m.def("test_overloaded2", [](double) {}, py::arg("d"), "overload docstring 2"); 26 | 27 | m.def("test_overloaded3", [](int) {}, py::arg("i")); 28 | m.def("test_overloaded3", [](double) {}, py::arg("d"), "Overload docstr"); 29 | 30 | options.enable_function_signatures(); 31 | 32 | m.def("test_function3", [](int, int) {}, py::arg("a"), py::arg("b")); 33 | m.def("test_function4", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); 34 | 35 | options.disable_function_signatures().disable_user_defined_docstrings(); 36 | 37 | m.def("test_function5", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); 38 | 39 | { 40 | py::options nested_options; 41 | nested_options.enable_user_defined_docstrings(); 42 | m.def("test_function6", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); 43 | } 44 | } 45 | 46 | m.def("test_function7", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring"); 47 | 48 | { 49 | py::options options; 50 | options.disable_user_defined_docstrings(); 51 | 52 | struct DocstringTestFoo { 53 | int value; 54 | void setValue(int v) { value = v; } 55 | int getValue() const { return value; } 56 | }; 57 | py::class_(m, "DocstringTestFoo", "This is a class docstring") 58 | .def_property("value_prop", &DocstringTestFoo::getValue, &DocstringTestFoo::setValue, "This is a property docstring") 59 | ; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_docstring_options.py: -------------------------------------------------------------------------------- 1 | from pybind11_tests import docstring_options as m 2 | 3 | 4 | def test_docstring_options(): 5 | # options.disable_function_signatures() 6 | assert not m.test_function1.__doc__ 7 | 8 | assert m.test_function2.__doc__ == "A custom docstring" 9 | 10 | # docstring specified on just the first overload definition: 11 | assert m.test_overloaded1.__doc__ == "Overload docstring" 12 | 13 | # docstring on both overloads: 14 | assert m.test_overloaded2.__doc__ == "overload docstring 1\noverload docstring 2" 15 | 16 | # docstring on only second overload: 17 | assert m.test_overloaded3.__doc__ == "Overload docstr" 18 | 19 | # options.enable_function_signatures() 20 | assert m.test_function3.__doc__ .startswith("test_function3(a: int, b: int) -> None") 21 | 22 | assert m.test_function4.__doc__ .startswith("test_function4(a: int, b: int) -> None") 23 | assert m.test_function4.__doc__ .endswith("A custom docstring\n") 24 | 25 | # options.disable_function_signatures() 26 | # options.disable_user_defined_docstrings() 27 | assert not m.test_function5.__doc__ 28 | 29 | # nested options.enable_user_defined_docstrings() 30 | assert m.test_function6.__doc__ == "A custom docstring" 31 | 32 | # RAII destructor 33 | assert m.test_function7.__doc__ .startswith("test_function7(a: int, b: int) -> None") 34 | assert m.test_function7.__doc__ .endswith("A custom docstring\n") 35 | 36 | # Suppression of user-defined docstrings for non-function objects 37 | assert not m.DocstringTestFoo.__doc__ 38 | assert not m.DocstringTestFoo.value_prop.__doc__ 39 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_embed/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(${PYTHON_MODULE_EXTENSION} MATCHES "pypy") 2 | add_custom_target(cpptest) # Dummy target on PyPy. Embedding is not supported. 3 | set(_suppress_unused_variable_warning "${DOWNLOAD_CATCH}") 4 | return() 5 | endif() 6 | 7 | find_package(Catch 1.9.3) 8 | if(CATCH_FOUND) 9 | message(STATUS "Building interpreter tests using Catch v${CATCH_VERSION}") 10 | else() 11 | message(STATUS "Catch not detected. Interpreter tests will be skipped. Install Catch headers" 12 | " manually or use `cmake -DDOWNLOAD_CATCH=1` to fetch them automatically.") 13 | return() 14 | endif() 15 | 16 | add_executable(test_embed 17 | catch.cpp 18 | test_interpreter.cpp 19 | ) 20 | target_include_directories(test_embed PRIVATE ${CATCH_INCLUDE_DIR}) 21 | pybind11_enable_warnings(test_embed) 22 | 23 | if(NOT CMAKE_VERSION VERSION_LESS 3.0) 24 | target_link_libraries(test_embed PRIVATE pybind11::embed) 25 | else() 26 | target_include_directories(test_embed PRIVATE ${PYBIND11_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS}) 27 | target_compile_options(test_embed PRIVATE ${PYBIND11_CPP_STANDARD}) 28 | target_link_libraries(test_embed PRIVATE ${PYTHON_LIBRARIES}) 29 | endif() 30 | 31 | find_package(Threads REQUIRED) 32 | target_link_libraries(test_embed PUBLIC ${CMAKE_THREAD_LIBS_INIT}) 33 | 34 | add_custom_target(cpptest COMMAND $ 35 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 36 | 37 | pybind11_add_module(external_module THIN_LTO external_module.cpp) 38 | set_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 39 | add_dependencies(cpptest external_module) 40 | 41 | add_dependencies(check cpptest) 42 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_embed/catch.cpp: -------------------------------------------------------------------------------- 1 | // The Catch implementation is compiled here. This is a standalone 2 | // translation unit to avoid recompiling it for every test change. 3 | 4 | #include 5 | 6 | #ifdef _MSC_VER 7 | // Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to catch 8 | // 2.0.1; this should be fixed in the next catch release after 2.0.1). 9 | # pragma warning(disable: 4996) 10 | #endif 11 | 12 | #define CATCH_CONFIG_RUNNER 13 | #include 14 | 15 | namespace py = pybind11; 16 | 17 | int main(int argc, char *argv[]) { 18 | py::scoped_interpreter guard{}; 19 | auto result = Catch::Session().run(argc, argv); 20 | 21 | return result < 0xff ? result : 0xff; 22 | } 23 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_embed/external_module.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace py = pybind11; 4 | 5 | /* Simple test module/test class to check that the referenced internals data of external pybind11 6 | * modules aren't preserved over a finalize/initialize. 7 | */ 8 | 9 | PYBIND11_MODULE(external_module, m) { 10 | class A { 11 | public: 12 | A(int value) : v{value} {}; 13 | int v; 14 | }; 15 | 16 | py::class_(m, "A") 17 | .def(py::init()) 18 | .def_readwrite("value", &A::v); 19 | 20 | m.def("internals_at", []() { 21 | return reinterpret_cast(&py::detail::get_internals()); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_embed/test_interpreter.py: -------------------------------------------------------------------------------- 1 | from widget_module import Widget 2 | 3 | 4 | class DerivedWidget(Widget): 5 | def __init__(self, message): 6 | super(DerivedWidget, self).__init__(message) 7 | 8 | def the_answer(self): 9 | return 42 10 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_enum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_enums.cpp -- enumerations 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | 12 | TEST_SUBMODULE(enums, m) { 13 | // test_unscoped_enum 14 | enum UnscopedEnum { 15 | EOne = 1, 16 | ETwo 17 | }; 18 | py::enum_(m, "UnscopedEnum", py::arithmetic(), "An unscoped enumeration") 19 | .value("EOne", EOne, "Docstring for EOne") 20 | .value("ETwo", ETwo, "Docstring for ETwo") 21 | .export_values(); 22 | 23 | // test_scoped_enum 24 | enum class ScopedEnum { 25 | Two = 2, 26 | Three 27 | }; 28 | py::enum_(m, "ScopedEnum", py::arithmetic()) 29 | .value("Two", ScopedEnum::Two) 30 | .value("Three", ScopedEnum::Three); 31 | 32 | m.def("test_scoped_enum", [](ScopedEnum z) { 33 | return "ScopedEnum::" + std::string(z == ScopedEnum::Two ? "Two" : "Three"); 34 | }); 35 | 36 | // test_binary_operators 37 | enum Flags { 38 | Read = 4, 39 | Write = 2, 40 | Execute = 1 41 | }; 42 | py::enum_(m, "Flags", py::arithmetic()) 43 | .value("Read", Flags::Read) 44 | .value("Write", Flags::Write) 45 | .value("Execute", Flags::Execute) 46 | .export_values(); 47 | 48 | // test_implicit_conversion 49 | class ClassWithUnscopedEnum { 50 | public: 51 | enum EMode { 52 | EFirstMode = 1, 53 | ESecondMode 54 | }; 55 | 56 | static EMode test_function(EMode mode) { 57 | return mode; 58 | } 59 | }; 60 | py::class_ exenum_class(m, "ClassWithUnscopedEnum"); 61 | exenum_class.def_static("test_function", &ClassWithUnscopedEnum::test_function); 62 | py::enum_(exenum_class, "EMode") 63 | .value("EFirstMode", ClassWithUnscopedEnum::EFirstMode) 64 | .value("ESecondMode", ClassWithUnscopedEnum::ESecondMode) 65 | .export_values(); 66 | 67 | // test_enum_to_int 68 | m.def("test_enum_to_int", [](int) { }); 69 | m.def("test_enum_to_uint", [](uint32_t) { }); 70 | m.def("test_enum_to_long_long", [](long long) { }); 71 | 72 | // test_duplicate_enum_name 73 | enum SimpleEnum 74 | { 75 | ONE, TWO, THREE 76 | }; 77 | 78 | m.def("register_bad_enum", [m]() { 79 | py::enum_(m, "SimpleEnum") 80 | .value("ONE", SimpleEnum::ONE) //NOTE: all value function calls are called with the same first parameter value 81 | .value("ONE", SimpleEnum::TWO) 82 | .value("ONE", SimpleEnum::THREE) 83 | .export_values(); 84 | }); 85 | } 86 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_eval.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_eval.cpp -- Usage of eval() and eval_file() 3 | 4 | Copyright (c) 2016 Klemens D. Morgenstern 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | 11 | #include 12 | #include "pybind11_tests.h" 13 | 14 | TEST_SUBMODULE(eval_, m) { 15 | // test_evals 16 | 17 | auto global = py::dict(py::module::import("__main__").attr("__dict__")); 18 | 19 | m.def("test_eval_statements", [global]() { 20 | auto local = py::dict(); 21 | local["call_test"] = py::cpp_function([&]() -> int { 22 | return 42; 23 | }); 24 | 25 | // Regular string literal 26 | py::exec( 27 | "message = 'Hello World!'\n" 28 | "x = call_test()", 29 | global, local 30 | ); 31 | 32 | // Multi-line raw string literal 33 | py::exec(R"( 34 | if x == 42: 35 | print(message) 36 | else: 37 | raise RuntimeError 38 | )", global, local 39 | ); 40 | auto x = local["x"].cast(); 41 | 42 | return x == 42; 43 | }); 44 | 45 | m.def("test_eval", [global]() { 46 | auto local = py::dict(); 47 | local["x"] = py::int_(42); 48 | auto x = py::eval("x", global, local); 49 | return x.cast() == 42; 50 | }); 51 | 52 | m.def("test_eval_single_statement", []() { 53 | auto local = py::dict(); 54 | local["call_test"] = py::cpp_function([&]() -> int { 55 | return 42; 56 | }); 57 | 58 | auto result = py::eval("x = call_test()", py::dict(), local); 59 | auto x = local["x"].cast(); 60 | return result.is_none() && x == 42; 61 | }); 62 | 63 | m.def("test_eval_file", [global](py::str filename) { 64 | auto local = py::dict(); 65 | local["y"] = py::int_(43); 66 | 67 | int val_out; 68 | local["call_test2"] = py::cpp_function([&](int value) { val_out = value; }); 69 | 70 | auto result = py::eval_file(filename, global, local); 71 | return val_out == 43 && result.is_none(); 72 | }); 73 | 74 | m.def("test_eval_failure", []() { 75 | try { 76 | py::eval("nonsense code ..."); 77 | } catch (py::error_already_set &) { 78 | return true; 79 | } 80 | return false; 81 | }); 82 | 83 | m.def("test_eval_file_failure", []() { 84 | try { 85 | py::eval_file("non-existing file"); 86 | } catch (std::exception &) { 87 | return true; 88 | } 89 | return false; 90 | }); 91 | } 92 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_eval.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pybind11_tests import eval_ as m 3 | 4 | 5 | def test_evals(capture): 6 | with capture: 7 | assert m.test_eval_statements() 8 | assert capture == "Hello World!" 9 | 10 | assert m.test_eval() 11 | assert m.test_eval_single_statement() 12 | 13 | filename = os.path.join(os.path.dirname(__file__), "test_eval_call.py") 14 | assert m.test_eval_file(filename) 15 | 16 | assert m.test_eval_failure() 17 | assert m.test_eval_file_failure() 18 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_eval_call.py: -------------------------------------------------------------------------------- 1 | # This file is called from 'test_eval.py' 2 | 3 | if 'call_test2' in locals(): 4 | call_test2(y) # noqa: F821 undefined name 5 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_gil_scoped.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_gil_scoped.cpp -- acquire and release gil 3 | 4 | Copyright (c) 2017 Borja Zarco (Google LLC) 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | #include 12 | 13 | 14 | class VirtClass { 15 | public: 16 | virtual void virtual_func() {} 17 | virtual void pure_virtual_func() = 0; 18 | }; 19 | 20 | class PyVirtClass : public VirtClass { 21 | void virtual_func() override { 22 | PYBIND11_OVERLOAD(void, VirtClass, virtual_func,); 23 | } 24 | void pure_virtual_func() override { 25 | PYBIND11_OVERLOAD_PURE(void, VirtClass, pure_virtual_func,); 26 | } 27 | }; 28 | 29 | TEST_SUBMODULE(gil_scoped, m) { 30 | py::class_(m, "VirtClass") 31 | .def(py::init<>()) 32 | .def("virtual_func", &VirtClass::virtual_func) 33 | .def("pure_virtual_func", &VirtClass::pure_virtual_func); 34 | 35 | m.def("test_callback_py_obj", 36 | [](py::object func) { func(); }); 37 | m.def("test_callback_std_func", 38 | [](const std::function &func) { func(); }); 39 | m.def("test_callback_virtual_func", 40 | [](VirtClass &virt) { virt.virtual_func(); }); 41 | m.def("test_callback_pure_virtual_func", 42 | [](VirtClass &virt) { virt.pure_virtual_func(); }); 43 | } 44 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_gil_scoped.py: -------------------------------------------------------------------------------- 1 | import multiprocessing 2 | import threading 3 | from pybind11_tests import gil_scoped as m 4 | 5 | 6 | def _run_in_process(target, *args, **kwargs): 7 | """Runs target in process and returns its exitcode after 10s (None if still alive).""" 8 | process = multiprocessing.Process(target=target, args=args, kwargs=kwargs) 9 | process.daemon = True 10 | try: 11 | process.start() 12 | # Do not need to wait much, 10s should be more than enough. 13 | process.join(timeout=10) 14 | return process.exitcode 15 | finally: 16 | if process.is_alive(): 17 | process.terminate() 18 | 19 | 20 | def _python_to_cpp_to_python(): 21 | """Calls different C++ functions that come back to Python.""" 22 | class ExtendedVirtClass(m.VirtClass): 23 | def virtual_func(self): 24 | pass 25 | 26 | def pure_virtual_func(self): 27 | pass 28 | 29 | extended = ExtendedVirtClass() 30 | m.test_callback_py_obj(lambda: None) 31 | m.test_callback_std_func(lambda: None) 32 | m.test_callback_virtual_func(extended) 33 | m.test_callback_pure_virtual_func(extended) 34 | 35 | 36 | def _python_to_cpp_to_python_from_threads(num_threads, parallel=False): 37 | """Calls different C++ functions that come back to Python, from Python threads.""" 38 | threads = [] 39 | for _ in range(num_threads): 40 | thread = threading.Thread(target=_python_to_cpp_to_python) 41 | thread.daemon = True 42 | thread.start() 43 | if parallel: 44 | threads.append(thread) 45 | else: 46 | thread.join() 47 | for thread in threads: 48 | thread.join() 49 | 50 | 51 | def test_python_to_cpp_to_python_from_thread(): 52 | """Makes sure there is no GIL deadlock when running in a thread. 53 | 54 | It runs in a separate process to be able to stop and assert if it deadlocks. 55 | """ 56 | assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0 57 | 58 | 59 | def test_python_to_cpp_to_python_from_thread_multiple_parallel(): 60 | """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel. 61 | 62 | It runs in a separate process to be able to stop and assert if it deadlocks. 63 | """ 64 | assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0 65 | 66 | 67 | def test_python_to_cpp_to_python_from_thread_multiple_sequential(): 68 | """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially. 69 | 70 | It runs in a separate process to be able to stop and assert if it deadlocks. 71 | """ 72 | assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0 73 | 74 | 75 | def test_python_to_cpp_to_python_from_process(): 76 | """Makes sure there is no GIL deadlock when using processes. 77 | 78 | This test is for completion, but it was never an issue. 79 | """ 80 | assert _run_in_process(_python_to_cpp_to_python) == 0 81 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_iostream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_iostream.cpp -- Usage of scoped_output_redirect 3 | 4 | Copyright (c) 2017 Henry F. Schreiner 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | 11 | #include 12 | #include "pybind11_tests.h" 13 | #include 14 | 15 | 16 | void noisy_function(std::string msg, bool flush) { 17 | 18 | std::cout << msg; 19 | if (flush) 20 | std::cout << std::flush; 21 | } 22 | 23 | void noisy_funct_dual(std::string msg, std::string emsg) { 24 | std::cout << msg; 25 | std::cerr << emsg; 26 | } 27 | 28 | TEST_SUBMODULE(iostream, m) { 29 | 30 | add_ostream_redirect(m); 31 | 32 | // test_evals 33 | 34 | m.def("captured_output_default", [](std::string msg) { 35 | py::scoped_ostream_redirect redir; 36 | std::cout << msg << std::flush; 37 | }); 38 | 39 | m.def("captured_output", [](std::string msg) { 40 | py::scoped_ostream_redirect redir(std::cout, py::module::import("sys").attr("stdout")); 41 | std::cout << msg << std::flush; 42 | }); 43 | 44 | m.def("guard_output", &noisy_function, 45 | py::call_guard(), 46 | py::arg("msg"), py::arg("flush")=true); 47 | 48 | m.def("captured_err", [](std::string msg) { 49 | py::scoped_ostream_redirect redir(std::cerr, py::module::import("sys").attr("stderr")); 50 | std::cerr << msg << std::flush; 51 | }); 52 | 53 | m.def("noisy_function", &noisy_function, py::arg("msg"), py::arg("flush") = true); 54 | 55 | m.def("dual_guard", &noisy_funct_dual, 56 | py::call_guard(), 57 | py::arg("msg"), py::arg("emsg")); 58 | 59 | m.def("raw_output", [](std::string msg) { 60 | std::cout << msg << std::flush; 61 | }); 62 | 63 | m.def("raw_err", [](std::string msg) { 64 | std::cerr << msg << std::flush; 65 | }); 66 | 67 | m.def("captured_dual", [](std::string msg, std::string emsg) { 68 | py::scoped_ostream_redirect redirout(std::cout, py::module::import("sys").attr("stdout")); 69 | py::scoped_ostream_redirect redirerr(std::cerr, py::module::import("sys").attr("stderr")); 70 | std::cout << msg << std::flush; 71 | std::cerr << emsg << std::flush; 72 | }); 73 | } 74 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_modules.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_modules.cpp -- nested modules, importing modules, and 3 | internal references 4 | 5 | Copyright (c) 2016 Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #include "pybind11_tests.h" 12 | #include "constructor_stats.h" 13 | 14 | TEST_SUBMODULE(modules, m) { 15 | // test_nested_modules 16 | py::module m_sub = m.def_submodule("subsubmodule"); 17 | m_sub.def("submodule_func", []() { return "submodule_func()"; }); 18 | 19 | // test_reference_internal 20 | class A { 21 | public: 22 | A(int v) : v(v) { print_created(this, v); } 23 | ~A() { print_destroyed(this); } 24 | A(const A&) { print_copy_created(this); } 25 | A& operator=(const A ©) { print_copy_assigned(this); v = copy.v; return *this; } 26 | std::string toString() { return "A[" + std::to_string(v) + "]"; } 27 | private: 28 | int v; 29 | }; 30 | py::class_(m_sub, "A") 31 | .def(py::init()) 32 | .def("__repr__", &A::toString); 33 | 34 | class B { 35 | public: 36 | B() { print_default_created(this); } 37 | ~B() { print_destroyed(this); } 38 | B(const B&) { print_copy_created(this); } 39 | B& operator=(const B ©) { print_copy_assigned(this); a1 = copy.a1; a2 = copy.a2; return *this; } 40 | A &get_a1() { return a1; } 41 | A &get_a2() { return a2; } 42 | 43 | A a1{1}; 44 | A a2{2}; 45 | }; 46 | py::class_(m_sub, "B") 47 | .def(py::init<>()) 48 | .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal) 49 | .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal) 50 | .def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default 51 | .def_readwrite("a2", &B::a2); 52 | 53 | m.attr("OD") = py::module::import("collections").attr("OrderedDict"); 54 | 55 | // test_duplicate_registration 56 | // Registering two things with the same name 57 | m.def("duplicate_registration", []() { 58 | class Dupe1 { }; 59 | class Dupe2 { }; 60 | class Dupe3 { }; 61 | class DupeException { }; 62 | 63 | auto dm = py::module("dummy"); 64 | auto failures = py::list(); 65 | 66 | py::class_(dm, "Dupe1"); 67 | py::class_(dm, "Dupe2"); 68 | dm.def("dupe1_factory", []() { return Dupe1(); }); 69 | py::exception(dm, "DupeException"); 70 | 71 | try { 72 | py::class_(dm, "Dupe1"); 73 | failures.append("Dupe1 class"); 74 | } catch (std::runtime_error &) {} 75 | try { 76 | dm.def("Dupe1", []() { return Dupe1(); }); 77 | failures.append("Dupe1 function"); 78 | } catch (std::runtime_error &) {} 79 | try { 80 | py::class_(dm, "dupe1_factory"); 81 | failures.append("dupe1_factory"); 82 | } catch (std::runtime_error &) {} 83 | try { 84 | py::exception(dm, "Dupe2"); 85 | failures.append("Dupe2"); 86 | } catch (std::runtime_error &) {} 87 | try { 88 | dm.def("DupeException", []() { return 30; }); 89 | failures.append("DupeException1"); 90 | } catch (std::runtime_error &) {} 91 | try { 92 | py::class_(dm, "DupeException"); 93 | failures.append("DupeException2"); 94 | } catch (std::runtime_error &) {} 95 | 96 | return failures; 97 | }); 98 | } 99 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_modules.py: -------------------------------------------------------------------------------- 1 | from pybind11_tests import modules as m 2 | from pybind11_tests.modules import subsubmodule as ms 3 | from pybind11_tests import ConstructorStats 4 | 5 | 6 | def test_nested_modules(): 7 | import pybind11_tests 8 | assert pybind11_tests.__name__ == "pybind11_tests" 9 | assert pybind11_tests.modules.__name__ == "pybind11_tests.modules" 10 | assert pybind11_tests.modules.subsubmodule.__name__ == "pybind11_tests.modules.subsubmodule" 11 | assert m.__name__ == "pybind11_tests.modules" 12 | assert ms.__name__ == "pybind11_tests.modules.subsubmodule" 13 | 14 | assert ms.submodule_func() == "submodule_func()" 15 | 16 | 17 | def test_reference_internal(): 18 | b = ms.B() 19 | assert str(b.get_a1()) == "A[1]" 20 | assert str(b.a1) == "A[1]" 21 | assert str(b.get_a2()) == "A[2]" 22 | assert str(b.a2) == "A[2]" 23 | 24 | b.a1 = ms.A(42) 25 | b.a2 = ms.A(43) 26 | assert str(b.get_a1()) == "A[42]" 27 | assert str(b.a1) == "A[42]" 28 | assert str(b.get_a2()) == "A[43]" 29 | assert str(b.a2) == "A[43]" 30 | 31 | astats, bstats = ConstructorStats.get(ms.A), ConstructorStats.get(ms.B) 32 | assert astats.alive() == 2 33 | assert bstats.alive() == 1 34 | del b 35 | assert astats.alive() == 0 36 | assert bstats.alive() == 0 37 | assert astats.values() == ['1', '2', '42', '43'] 38 | assert bstats.values() == [] 39 | assert astats.default_constructions == 0 40 | assert bstats.default_constructions == 1 41 | assert astats.copy_constructions == 0 42 | assert bstats.copy_constructions == 0 43 | # assert astats.move_constructions >= 0 # Don't invoke any 44 | # assert bstats.move_constructions >= 0 # Don't invoke any 45 | assert astats.copy_assignments == 2 46 | assert bstats.copy_assignments == 0 47 | assert astats.move_assignments == 0 48 | assert bstats.move_assignments == 0 49 | 50 | 51 | def test_importing(): 52 | from pybind11_tests.modules import OD 53 | from collections import OrderedDict 54 | 55 | assert OD is OrderedDict 56 | assert str(OD([(1, 'a'), (2, 'b')])) == "OrderedDict([(1, 'a'), (2, 'b')])" 57 | 58 | 59 | def test_pydoc(): 60 | """Pydoc needs to be able to provide help() for everything inside a pybind11 module""" 61 | import pybind11_tests 62 | import pydoc 63 | 64 | assert pybind11_tests.__name__ == "pybind11_tests" 65 | assert pybind11_tests.__doc__ == "pybind11 test module" 66 | assert pydoc.text.docmodule(pybind11_tests) 67 | 68 | 69 | def test_duplicate_registration(): 70 | """Registering two things with the same name""" 71 | 72 | assert m.duplicate_registration() == [] 73 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_numpy_vectorize.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_numpy_vectorize.cpp -- auto-vectorize functions over NumPy array 3 | arguments 4 | 5 | Copyright (c) 2016 Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #include "pybind11_tests.h" 12 | #include 13 | 14 | double my_func(int x, float y, double z) { 15 | py::print("my_func(x:int={}, y:float={:.0f}, z:float={:.0f})"_s.format(x, y, z)); 16 | return (float) x*y*z; 17 | } 18 | 19 | TEST_SUBMODULE(numpy_vectorize, m) { 20 | try { py::module::import("numpy"); } 21 | catch (...) { return; } 22 | 23 | // test_vectorize, test_docs, test_array_collapse 24 | // Vectorize all arguments of a function (though non-vector arguments are also allowed) 25 | m.def("vectorized_func", py::vectorize(my_func)); 26 | 27 | // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the vectorization) 28 | m.def("vectorized_func2", 29 | [](py::array_t x, py::array_t y, float z) { 30 | return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(x, y); 31 | } 32 | ); 33 | 34 | // Vectorize a complex-valued function 35 | m.def("vectorized_func3", py::vectorize( 36 | [](std::complex c) { return c * std::complex(2.f); } 37 | )); 38 | 39 | // test_type_selection 40 | // Numpy function which only accepts specific data types 41 | m.def("selective_func", [](py::array_t) { return "Int branch taken."; }); 42 | m.def("selective_func", [](py::array_t) { return "Float branch taken."; }); 43 | m.def("selective_func", [](py::array_t, py::array::c_style>) { return "Complex float branch taken."; }); 44 | 45 | 46 | // test_passthrough_arguments 47 | // Passthrough test: references and non-pod types should be automatically passed through (in the 48 | // function definition below, only `b`, `d`, and `g` are vectorized): 49 | struct NonPODClass { 50 | NonPODClass(int v) : value{v} {} 51 | int value; 52 | }; 53 | py::class_(m, "NonPODClass").def(py::init()); 54 | m.def("vec_passthrough", py::vectorize( 55 | [](double *a, double b, py::array_t c, const int &d, int &e, NonPODClass f, const double g) { 56 | return *a + b + c.at(0) + d + e + f.value + g; 57 | } 58 | )); 59 | 60 | // test_method_vectorization 61 | struct VectorizeTestClass { 62 | VectorizeTestClass(int v) : value{v} {}; 63 | float method(int x, float y) { return y + (float) (x + value); } 64 | int value = 0; 65 | }; 66 | py::class_ vtc(m, "VectorizeTestClass"); 67 | vtc .def(py::init()) 68 | .def_readwrite("value", &VectorizeTestClass::value); 69 | 70 | // Automatic vectorizing of methods 71 | vtc.def("method", py::vectorize(&VectorizeTestClass::method)); 72 | 73 | // test_trivial_broadcasting 74 | // Internal optimization test for whether the input is trivially broadcastable: 75 | py::enum_(m, "trivial") 76 | .value("f_trivial", py::detail::broadcast_trivial::f_trivial) 77 | .value("c_trivial", py::detail::broadcast_trivial::c_trivial) 78 | .value("non_trivial", py::detail::broadcast_trivial::non_trivial); 79 | m.def("vectorized_is_trivial", []( 80 | py::array_t arg1, 81 | py::array_t arg2, 82 | py::array_t arg3 83 | ) { 84 | ssize_t ndim; 85 | std::vector shape; 86 | std::array buffers {{ arg1.request(), arg2.request(), arg3.request() }}; 87 | return py::detail::broadcast(buffers, ndim, shape); 88 | }); 89 | } 90 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_opaque_types.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_opaque_types.cpp -- opaque types, passing void pointers 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | #include 12 | #include 13 | 14 | // IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures 15 | // 16 | // This also deliberately doesn't use the below StringList type alias to test 17 | // that MAKE_OPAQUE can handle a type containing a `,`. (The `std::allocator` 18 | // bit is just the default `std::vector` allocator). 19 | PYBIND11_MAKE_OPAQUE(std::vector>); 20 | 21 | using StringList = std::vector>; 22 | 23 | TEST_SUBMODULE(opaque_types, m) { 24 | // test_string_list 25 | py::class_(m, "StringList") 26 | .def(py::init<>()) 27 | .def("pop_back", &StringList::pop_back) 28 | /* There are multiple versions of push_back(), etc. Select the right ones. */ 29 | .def("push_back", (void (StringList::*)(const std::string &)) &StringList::push_back) 30 | .def("back", (std::string &(StringList::*)()) &StringList::back) 31 | .def("__len__", [](const StringList &v) { return v.size(); }) 32 | .def("__iter__", [](StringList &v) { 33 | return py::make_iterator(v.begin(), v.end()); 34 | }, py::keep_alive<0, 1>()); 35 | 36 | class ClassWithSTLVecProperty { 37 | public: 38 | StringList stringList; 39 | }; 40 | py::class_(m, "ClassWithSTLVecProperty") 41 | .def(py::init<>()) 42 | .def_readwrite("stringList", &ClassWithSTLVecProperty::stringList); 43 | 44 | m.def("print_opaque_list", [](const StringList &l) { 45 | std::string ret = "Opaque list: ["; 46 | bool first = true; 47 | for (auto entry : l) { 48 | if (!first) 49 | ret += ", "; 50 | ret += entry; 51 | first = false; 52 | } 53 | return ret + "]"; 54 | }); 55 | 56 | // test_pointers 57 | m.def("return_void_ptr", []() { return (void *) 0x1234; }); 58 | m.def("get_void_ptr_value", [](void *ptr) { return reinterpret_cast(ptr); }); 59 | m.def("return_null_str", []() { return (char *) nullptr; }); 60 | m.def("get_null_str_value", [](char *ptr) { return reinterpret_cast(ptr); }); 61 | 62 | m.def("return_unique_ptr", []() -> std::unique_ptr { 63 | StringList *result = new StringList(); 64 | result->push_back("some value"); 65 | return std::unique_ptr(result); 66 | }); 67 | } 68 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_opaque_types.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pybind11_tests import opaque_types as m 3 | from pybind11_tests import ConstructorStats, UserType 4 | 5 | 6 | def test_string_list(): 7 | lst = m.StringList() 8 | lst.push_back("Element 1") 9 | lst.push_back("Element 2") 10 | assert m.print_opaque_list(lst) == "Opaque list: [Element 1, Element 2]" 11 | assert lst.back() == "Element 2" 12 | 13 | for i, k in enumerate(lst, start=1): 14 | assert k == "Element {}".format(i) 15 | lst.pop_back() 16 | assert m.print_opaque_list(lst) == "Opaque list: [Element 1]" 17 | 18 | cvp = m.ClassWithSTLVecProperty() 19 | assert m.print_opaque_list(cvp.stringList) == "Opaque list: []" 20 | 21 | cvp.stringList = lst 22 | cvp.stringList.push_back("Element 3") 23 | assert m.print_opaque_list(cvp.stringList) == "Opaque list: [Element 1, Element 3]" 24 | 25 | 26 | def test_pointers(msg): 27 | living_before = ConstructorStats.get(UserType).alive() 28 | assert m.get_void_ptr_value(m.return_void_ptr()) == 0x1234 29 | assert m.get_void_ptr_value(UserType()) # Should also work for other C++ types 30 | assert ConstructorStats.get(UserType).alive() == living_before 31 | 32 | with pytest.raises(TypeError) as excinfo: 33 | m.get_void_ptr_value([1, 2, 3]) # This should not work 34 | assert msg(excinfo.value) == """ 35 | get_void_ptr_value(): incompatible function arguments. The following argument types are supported: 36 | 1. (arg0: capsule) -> int 37 | 38 | Invoked with: [1, 2, 3] 39 | """ # noqa: E501 line too long 40 | 41 | assert m.return_null_str() is None 42 | assert m.get_null_str_value(m.return_null_str()) is not None 43 | 44 | ptr = m.return_unique_ptr() 45 | assert "StringList" in repr(ptr) 46 | assert m.print_opaque_list(ptr) == "Opaque list: [some value]" 47 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_operator_overloading.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pybind11_tests import operators as m 3 | from pybind11_tests import ConstructorStats 4 | 5 | 6 | def test_operator_overloading(): 7 | v1 = m.Vector2(1, 2) 8 | v2 = m.Vector(3, -1) 9 | assert str(v1) == "[1.000000, 2.000000]" 10 | assert str(v2) == "[3.000000, -1.000000]" 11 | 12 | assert str(v1 + v2) == "[4.000000, 1.000000]" 13 | assert str(v1 - v2) == "[-2.000000, 3.000000]" 14 | assert str(v1 - 8) == "[-7.000000, -6.000000]" 15 | assert str(v1 + 8) == "[9.000000, 10.000000]" 16 | assert str(v1 * 8) == "[8.000000, 16.000000]" 17 | assert str(v1 / 8) == "[0.125000, 0.250000]" 18 | assert str(8 - v1) == "[7.000000, 6.000000]" 19 | assert str(8 + v1) == "[9.000000, 10.000000]" 20 | assert str(8 * v1) == "[8.000000, 16.000000]" 21 | assert str(8 / v1) == "[8.000000, 4.000000]" 22 | assert str(v1 * v2) == "[3.000000, -2.000000]" 23 | assert str(v2 / v1) == "[3.000000, -0.500000]" 24 | 25 | v1 += 2 * v2 26 | assert str(v1) == "[7.000000, 0.000000]" 27 | v1 -= v2 28 | assert str(v1) == "[4.000000, 1.000000]" 29 | v1 *= 2 30 | assert str(v1) == "[8.000000, 2.000000]" 31 | v1 /= 16 32 | assert str(v1) == "[0.500000, 0.125000]" 33 | v1 *= v2 34 | assert str(v1) == "[1.500000, -0.125000]" 35 | v2 /= v1 36 | assert str(v2) == "[2.000000, 8.000000]" 37 | 38 | assert hash(v1) == 4 39 | 40 | cstats = ConstructorStats.get(m.Vector2) 41 | assert cstats.alive() == 2 42 | del v1 43 | assert cstats.alive() == 1 44 | del v2 45 | assert cstats.alive() == 0 46 | assert cstats.values() == ['[1.000000, 2.000000]', '[3.000000, -1.000000]', 47 | '[4.000000, 1.000000]', '[-2.000000, 3.000000]', 48 | '[-7.000000, -6.000000]', '[9.000000, 10.000000]', 49 | '[8.000000, 16.000000]', '[0.125000, 0.250000]', 50 | '[7.000000, 6.000000]', '[9.000000, 10.000000]', 51 | '[8.000000, 16.000000]', '[8.000000, 4.000000]', 52 | '[3.000000, -2.000000]', '[3.000000, -0.500000]', 53 | '[6.000000, -2.000000]'] 54 | assert cstats.default_constructions == 0 55 | assert cstats.copy_constructions == 0 56 | assert cstats.move_constructions >= 10 57 | assert cstats.copy_assignments == 0 58 | assert cstats.move_assignments == 0 59 | 60 | 61 | def test_operators_notimplemented(): 62 | """#393: need to return NotSupported to ensure correct arithmetic operator behavior""" 63 | 64 | c1, c2 = m.C1(), m.C2() 65 | assert c1 + c1 == 11 66 | assert c2 + c2 == 22 67 | assert c2 + c1 == 21 68 | assert c1 + c2 == 12 69 | 70 | 71 | def test_nested(): 72 | """#328: first member in a class can't be used in operators""" 73 | 74 | a = m.NestA() 75 | b = m.NestB() 76 | c = m.NestC() 77 | 78 | a += 10 79 | assert m.get_NestA(a) == 13 80 | b.a += 100 81 | assert m.get_NestA(b.a) == 103 82 | c.b.a += 1000 83 | assert m.get_NestA(c.b.a) == 1003 84 | b -= 1 85 | assert m.get_NestB(b) == 3 86 | c.b -= 3 87 | assert m.get_NestB(c.b) == 1 88 | c *= 7 89 | assert m.get_NestC(c) == 35 90 | 91 | abase = a.as_base() 92 | assert abase.value == -2 93 | a.as_base().value += 44 94 | assert abase.value == 42 95 | assert c.b.a.as_base().value == -2 96 | c.b.a.as_base().value += 44 97 | assert c.b.a.as_base().value == 42 98 | 99 | del c 100 | pytest.gc_collect() 101 | del a # Shouldn't delete while abase is still alive 102 | pytest.gc_collect() 103 | 104 | assert abase.value == 42 105 | del abase, b 106 | pytest.gc_collect() 107 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_pickling.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pybind11_tests import pickling as m 3 | 4 | try: 5 | import cPickle as pickle # Use cPickle on Python 2.7 6 | except ImportError: 7 | import pickle 8 | 9 | 10 | @pytest.mark.parametrize("cls_name", ["Pickleable", "PickleableNew"]) 11 | def test_roundtrip(cls_name): 12 | cls = getattr(m, cls_name) 13 | p = cls("test_value") 14 | p.setExtra1(15) 15 | p.setExtra2(48) 16 | 17 | data = pickle.dumps(p, 2) # Must use pickle protocol >= 2 18 | p2 = pickle.loads(data) 19 | assert p2.value() == p.value() 20 | assert p2.extra1() == p.extra1() 21 | assert p2.extra2() == p.extra2() 22 | 23 | 24 | @pytest.unsupported_on_pypy 25 | @pytest.mark.parametrize("cls_name", ["PickleableWithDict", "PickleableWithDictNew"]) 26 | def test_roundtrip_with_dict(cls_name): 27 | cls = getattr(m, cls_name) 28 | p = cls("test_value") 29 | p.extra = 15 30 | p.dynamic = "Attribute" 31 | 32 | data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL) 33 | p2 = pickle.loads(data) 34 | assert p2.value == p.value 35 | assert p2.extra == p.extra 36 | assert p2.dynamic == p.dynamic 37 | 38 | 39 | def test_enum_pickle(): 40 | from pybind11_tests import enums as e 41 | data = pickle.dumps(e.EOne, 2) 42 | assert e.EOne == pickle.loads(data) 43 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_stl_binders.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | tests/test_stl_binders.cpp -- Usage of stl_binders functions 3 | 4 | Copyright (c) 2016 Sergey Lyskov 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #include "pybind11_tests.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | class El { 19 | public: 20 | El() = delete; 21 | El(int v) : a(v) { } 22 | 23 | int a; 24 | }; 25 | 26 | std::ostream & operator<<(std::ostream &s, El const&v) { 27 | s << "El{" << v.a << '}'; 28 | return s; 29 | } 30 | 31 | /// Issue #487: binding std::vector with E non-copyable 32 | class E_nc { 33 | public: 34 | explicit E_nc(int i) : value{i} {} 35 | E_nc(const E_nc &) = delete; 36 | E_nc &operator=(const E_nc &) = delete; 37 | E_nc(E_nc &&) = default; 38 | E_nc &operator=(E_nc &&) = default; 39 | 40 | int value; 41 | }; 42 | 43 | template Container *one_to_n(int n) { 44 | auto v = new Container(); 45 | for (int i = 1; i <= n; i++) 46 | v->emplace_back(i); 47 | return v; 48 | } 49 | 50 | template Map *times_ten(int n) { 51 | auto m = new Map(); 52 | for (int i = 1; i <= n; i++) 53 | m->emplace(int(i), E_nc(10*i)); 54 | return m; 55 | } 56 | 57 | TEST_SUBMODULE(stl_binders, m) { 58 | // test_vector_int 59 | py::bind_vector>(m, "VectorInt", py::buffer_protocol()); 60 | 61 | // test_vector_custom 62 | py::class_(m, "El") 63 | .def(py::init()); 64 | py::bind_vector>(m, "VectorEl"); 65 | py::bind_vector>>(m, "VectorVectorEl"); 66 | 67 | // test_map_string_double 68 | py::bind_map>(m, "MapStringDouble"); 69 | py::bind_map>(m, "UnorderedMapStringDouble"); 70 | 71 | // test_map_string_double_const 72 | py::bind_map>(m, "MapStringDoubleConst"); 73 | py::bind_map>(m, "UnorderedMapStringDoubleConst"); 74 | 75 | py::class_(m, "ENC") 76 | .def(py::init()) 77 | .def_readwrite("value", &E_nc::value); 78 | 79 | // test_noncopyable_containers 80 | py::bind_vector>(m, "VectorENC"); 81 | m.def("get_vnc", &one_to_n>, py::return_value_policy::reference); 82 | py::bind_vector>(m, "DequeENC"); 83 | m.def("get_dnc", &one_to_n>, py::return_value_policy::reference); 84 | py::bind_map>(m, "MapENC"); 85 | m.def("get_mnc", ×_ten>, py::return_value_policy::reference); 86 | py::bind_map>(m, "UmapENC"); 87 | m.def("get_umnc", ×_ten>, py::return_value_policy::reference); 88 | 89 | // test_vector_buffer 90 | py::bind_vector>(m, "VectorUChar", py::buffer_protocol()); 91 | // no dtype declared for this version: 92 | struct VUndeclStruct { bool w; uint32_t x; double y; bool z; }; 93 | m.def("create_undeclstruct", [m] () mutable { 94 | py::bind_vector>(m, "VectorUndeclStruct", py::buffer_protocol()); 95 | }); 96 | 97 | // The rest depends on numpy: 98 | try { py::module::import("numpy"); } 99 | catch (...) { return; } 100 | 101 | // test_vector_buffer_numpy 102 | struct VStruct { bool w; uint32_t x; double y; bool z; }; 103 | PYBIND11_NUMPY_DTYPE(VStruct, w, x, y, z); 104 | py::class_(m, "VStruct").def_readwrite("x", &VStruct::x); 105 | py::bind_vector>(m, "VectorStruct", py::buffer_protocol()); 106 | m.def("get_vectorstruct", [] {return std::vector {{0, 5, 3.0, 1}, {1, 30, -1e4, 0}};}); 107 | } 108 | -------------------------------------------------------------------------------- /c_segment/pybind11/tests/test_tagbased_polymorphic.py: -------------------------------------------------------------------------------- 1 | from pybind11_tests import tagbased_polymorphic as m 2 | 3 | 4 | def test_downcast(): 5 | zoo = m.create_zoo() 6 | assert [type(animal) for animal in zoo] == [ 7 | m.Labrador, m.Dog, m.Chihuahua, m.Cat, m.Panther 8 | ] 9 | assert [animal.name for animal in zoo] == [ 10 | "Fido", "Ginger", "Hertzl", "Tiger", "Leo" 11 | ] 12 | zoo[1].sound = "woooooo" 13 | assert [dog.bark() for dog in zoo[:3]] == [ 14 | "Labrador Fido goes WOOF!", 15 | "Dog Ginger goes woooooo", 16 | "Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles" 17 | ] 18 | assert [cat.purr() for cat in zoo[3:]] == ["mrowr", "mrrrRRRRRR"] 19 | zoo[0].excitement -= 1000 20 | assert zoo[0].excitement == 14000 21 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/FindCatch.cmake: -------------------------------------------------------------------------------- 1 | # - Find the Catch test framework or download it (single header) 2 | # 3 | # This is a quick module for internal use. It assumes that Catch is 4 | # REQUIRED and that a minimum version is provided (not EXACT). If 5 | # a suitable version isn't found locally, the single header file 6 | # will be downloaded and placed in the build dir: PROJECT_BINARY_DIR. 7 | # 8 | # This code sets the following variables: 9 | # CATCH_INCLUDE_DIR - path to catch.hpp 10 | # CATCH_VERSION - version number 11 | 12 | if(NOT Catch_FIND_VERSION) 13 | message(FATAL_ERROR "A version number must be specified.") 14 | elseif(Catch_FIND_REQUIRED) 15 | message(FATAL_ERROR "This module assumes Catch is not required.") 16 | elseif(Catch_FIND_VERSION_EXACT) 17 | message(FATAL_ERROR "Exact version numbers are not supported, only minimum.") 18 | endif() 19 | 20 | # Extract the version number from catch.hpp 21 | function(_get_catch_version) 22 | file(STRINGS "${CATCH_INCLUDE_DIR}/catch.hpp" version_line REGEX "Catch v.*" LIMIT_COUNT 1) 23 | if(version_line MATCHES "Catch v([0-9]+)\\.([0-9]+)\\.([0-9]+)") 24 | set(CATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE) 25 | endif() 26 | endfunction() 27 | 28 | # Download the single-header version of Catch 29 | function(_download_catch version destination_dir) 30 | message(STATUS "Downloading catch v${version}...") 31 | set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp) 32 | file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status) 33 | list(GET status 0 error) 34 | if(error) 35 | message(FATAL_ERROR "Could not download ${url}") 36 | endif() 37 | set(CATCH_INCLUDE_DIR "${destination_dir}" CACHE INTERNAL "") 38 | endfunction() 39 | 40 | # Look for catch locally 41 | find_path(CATCH_INCLUDE_DIR NAMES catch.hpp PATH_SUFFIXES catch) 42 | if(CATCH_INCLUDE_DIR) 43 | _get_catch_version() 44 | endif() 45 | 46 | # Download the header if it wasn't found or if it's outdated 47 | if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION}) 48 | if(DOWNLOAD_CATCH) 49 | _download_catch(${Catch_FIND_VERSION} "${PROJECT_BINARY_DIR}/catch/") 50 | _get_catch_version() 51 | else() 52 | set(CATCH_FOUND FALSE) 53 | return() 54 | endif() 55 | endif() 56 | 57 | set(CATCH_FOUND TRUE) 58 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/FindEigen3.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find Eigen3 lib 2 | # 3 | # This module supports requiring a minimum version, e.g. you can do 4 | # find_package(Eigen3 3.1.2) 5 | # to require version 3.1.2 or newer of Eigen3. 6 | # 7 | # Once done this will define 8 | # 9 | # EIGEN3_FOUND - system has eigen lib with correct version 10 | # EIGEN3_INCLUDE_DIR - the eigen include directory 11 | # EIGEN3_VERSION - eigen version 12 | 13 | # Copyright (c) 2006, 2007 Montel Laurent, 14 | # Copyright (c) 2008, 2009 Gael Guennebaud, 15 | # Copyright (c) 2009 Benoit Jacob 16 | # Redistribution and use is allowed according to the terms of the 2-clause BSD license. 17 | 18 | if(NOT Eigen3_FIND_VERSION) 19 | if(NOT Eigen3_FIND_VERSION_MAJOR) 20 | set(Eigen3_FIND_VERSION_MAJOR 2) 21 | endif(NOT Eigen3_FIND_VERSION_MAJOR) 22 | if(NOT Eigen3_FIND_VERSION_MINOR) 23 | set(Eigen3_FIND_VERSION_MINOR 91) 24 | endif(NOT Eigen3_FIND_VERSION_MINOR) 25 | if(NOT Eigen3_FIND_VERSION_PATCH) 26 | set(Eigen3_FIND_VERSION_PATCH 0) 27 | endif(NOT Eigen3_FIND_VERSION_PATCH) 28 | 29 | set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") 30 | endif(NOT Eigen3_FIND_VERSION) 31 | 32 | macro(_eigen3_check_version) 33 | file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) 34 | 35 | string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") 36 | set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") 37 | string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") 38 | set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") 39 | string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") 40 | set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") 41 | 42 | set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) 43 | if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) 44 | set(EIGEN3_VERSION_OK FALSE) 45 | else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) 46 | set(EIGEN3_VERSION_OK TRUE) 47 | endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) 48 | 49 | if(NOT EIGEN3_VERSION_OK) 50 | 51 | message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " 52 | "but at least version ${Eigen3_FIND_VERSION} is required") 53 | endif(NOT EIGEN3_VERSION_OK) 54 | endmacro(_eigen3_check_version) 55 | 56 | if (EIGEN3_INCLUDE_DIR) 57 | 58 | # in cache already 59 | _eigen3_check_version() 60 | set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) 61 | 62 | else (EIGEN3_INCLUDE_DIR) 63 | 64 | find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library 65 | PATHS 66 | ${CMAKE_INSTALL_PREFIX}/include 67 | ${KDE4_INCLUDE_DIR} 68 | PATH_SUFFIXES eigen3 eigen 69 | ) 70 | 71 | if(EIGEN3_INCLUDE_DIR) 72 | _eigen3_check_version() 73 | endif(EIGEN3_INCLUDE_DIR) 74 | 75 | include(FindPackageHandleStandardArgs) 76 | find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) 77 | 78 | mark_as_advanced(EIGEN3_INCLUDE_DIR) 79 | 80 | endif(EIGEN3_INCLUDE_DIR) 81 | 82 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/check-style.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to check include/test code for common pybind11 code style errors. 4 | # 5 | # This script currently checks for 6 | # 7 | # 1. use of tabs instead of spaces 8 | # 2. MSDOS-style CRLF endings 9 | # 3. trailing spaces 10 | # 4. missing space between keyword and parenthesis, e.g.: for(, if(, while( 11 | # 5. Missing space between right parenthesis and brace, e.g. 'for (...){' 12 | # 6. opening brace on its own line. It should always be on the same line as the 13 | # if/while/for/do statement. 14 | # 15 | # Invoke as: tools/check-style.sh 16 | # 17 | 18 | check_style_errors=0 19 | IFS=$'\n' 20 | 21 | found="$( GREP_COLORS='mt=41' GREP_COLOR='41' grep $'\t' include tests/*.{cpp,py,h} docs/*.rst -rn --color=always )" 22 | if [ -n "$found" ]; then 23 | # The mt=41 sets a red background for matched tabs: 24 | echo -e '\033[31;01mError: found tab characters in the following files:\033[0m' 25 | check_style_errors=1 26 | echo "$found" | sed -e 's/^/ /' 27 | fi 28 | 29 | 30 | found="$( grep -IUlr $'\r' include tests/*.{cpp,py,h} docs/*.rst --color=always )" 31 | if [ -n "$found" ]; then 32 | echo -e '\033[31;01mError: found CRLF characters in the following files:\033[0m' 33 | check_style_errors=1 34 | echo "$found" | sed -e 's/^/ /' 35 | fi 36 | 37 | found="$(GREP_COLORS='mt=41' GREP_COLOR='41' grep '[[:blank:]]\+$' include tests/*.{cpp,py,h} docs/*.rst -rn --color=always )" 38 | if [ -n "$found" ]; then 39 | # The mt=41 sets a red background for matched trailing spaces 40 | echo -e '\033[31;01mError: found trailing spaces in the following files:\033[0m' 41 | check_style_errors=1 42 | echo "$found" | sed -e 's/^/ /' 43 | fi 44 | 45 | found="$(grep '\<\(if\|for\|while\|catch\)(\|){' include tests/*.{cpp,h} -rn --color=always)" 46 | if [ -n "$found" ]; then 47 | echo -e '\033[31;01mError: found the following coding style problems:\033[0m' 48 | check_style_errors=1 49 | echo "$found" | sed -e 's/^/ /' 50 | fi 51 | 52 | found="$(awk ' 53 | function prefix(filename, lineno) { 54 | return " \033[35m" filename "\033[36m:\033[32m" lineno "\033[36m:\033[0m" 55 | } 56 | function mark(pattern, string) { sub(pattern, "\033[01;31m&\033[0m", string); return string } 57 | last && /^\s*{/ { 58 | print prefix(FILENAME, FNR-1) mark("\\)\\s*$", last) 59 | print prefix(FILENAME, FNR) mark("^\\s*{", $0) 60 | last="" 61 | } 62 | { last = /(if|for|while|catch|switch)\s*\(.*\)\s*$/ ? $0 : "" } 63 | ' $(find include -type f) tests/*.{cpp,h} docs/*.rst)" 64 | if [ -n "$found" ]; then 65 | check_style_errors=1 66 | echo -e '\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\033[0m' 67 | echo "$found" 68 | fi 69 | 70 | exit $check_style_errors 71 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/clang/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | *.pyc 4 | __pycache__ 5 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/clang/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | LLVM Release License 3 | ============================================================================== 4 | University of Illinois/NCSA 5 | Open Source License 6 | 7 | Copyright (c) 2007-2012 University of Illinois at Urbana-Champaign. 8 | All rights reserved. 9 | 10 | Developed by: 11 | 12 | LLVM Team 13 | 14 | University of Illinois at Urbana-Champaign 15 | 16 | http://llvm.org 17 | 18 | Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | this software and associated documentation files (the "Software"), to deal with 20 | the Software without restriction, including without limitation the rights to 21 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 22 | of the Software, and to permit persons to whom the Software is furnished to do 23 | so, subject to the following conditions: 24 | 25 | * Redistributions of source code must retain the above copyright notice, 26 | this list of conditions and the following disclaimers. 27 | 28 | * Redistributions in binary form must reproduce the above copyright notice, 29 | this list of conditions and the following disclaimers in the 30 | documentation and/or other materials provided with the distribution. 31 | 32 | * Neither the names of the LLVM Team, University of Illinois at 33 | Urbana-Champaign, nor the names of its contributors may be used to 34 | endorse or promote products derived from this Software without specific 35 | prior written permission. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 39 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 43 | SOFTWARE. 44 | 45 | ============================================================================== 46 | The LLVM software contains code written by third parties. Such software will 47 | have its own individual LICENSE.TXT file in the directory in which it appears. 48 | This file will describe the copyrights, license, and restrictions which apply 49 | to that code. 50 | 51 | The disclaimer of warranty in the University of Illinois Open Source License 52 | applies to all code in the LLVM Distribution, and nothing in any of the 53 | other licenses gives permission to use the names of the LLVM Team or the 54 | University of Illinois to endorse or promote products derived from this 55 | Software. 56 | 57 | The following pieces of software have additional or alternate copyrights, 58 | licenses, and/or restrictions: 59 | 60 | Program Directory 61 | ------- --------- 62 | 63 | 64 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/clang/README.md: -------------------------------------------------------------------------------- 1 | This is simply clang's Python bindings (clang.cindex) ported to Python 3. Please see http://llvm.org/svn/llvm-project/cfe/trunk/bindings/python/ for the original project. 2 | 3 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/clang/__init__.py: -------------------------------------------------------------------------------- 1 | #===- __init__.py - Clang Python Bindings --------------------*- python -*--===# 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file is distributed under the University of Illinois Open Source 6 | # License. See LICENSE.TXT for details. 7 | # 8 | #===------------------------------------------------------------------------===# 9 | 10 | r""" 11 | Clang Library Bindings 12 | ====================== 13 | 14 | This package provides access to the Clang compiler and libraries. 15 | 16 | The available modules are: 17 | 18 | cindex 19 | 20 | Bindings for the Clang indexing library. 21 | """ 22 | 23 | __all__ = ['cindex'] 24 | 25 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/clang/enumerations.py: -------------------------------------------------------------------------------- 1 | #===- enumerations.py - Python Enumerations ------------------*- python -*--===# 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file is distributed under the University of Illinois Open Source 6 | # License. See LICENSE.TXT for details. 7 | # 8 | #===------------------------------------------------------------------------===# 9 | 10 | """ 11 | Clang Enumerations 12 | ================== 13 | 14 | This module provides static definitions of enumerations that exist in libclang. 15 | 16 | Enumerations are typically defined as a list of tuples. The exported values are 17 | typically munged into other types or classes at module load time. 18 | 19 | All enumerations are centrally defined in this file so they are all grouped 20 | together and easier to audit. And, maybe even one day this file will be 21 | automatically generated by scanning the libclang headers! 22 | """ 23 | 24 | # Maps to CXTokenKind. Note that libclang maintains a separate set of token 25 | # enumerations from the C++ API. 26 | TokenKinds = [ 27 | ('PUNCTUATION', 0), 28 | ('KEYWORD', 1), 29 | ('IDENTIFIER', 2), 30 | ('LITERAL', 3), 31 | ('COMMENT', 4), 32 | ] 33 | 34 | __all__ = ['TokenKinds'] 35 | -------------------------------------------------------------------------------- /c_segment/pybind11/tools/libsize.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, division 2 | import os 3 | import sys 4 | 5 | # Internal build script for generating debugging test .so size. 6 | # Usage: 7 | # python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the 8 | # size in it, then overwrites save.txt with the new size for future runs. 9 | 10 | if len(sys.argv) != 3: 11 | sys.exit("Invalid arguments: usage: python libsize.py file.so save.txt") 12 | 13 | lib = sys.argv[1] 14 | save = sys.argv[2] 15 | 16 | if not os.path.exists(lib): 17 | sys.exit("Error: requested file ({}) does not exist".format(lib)) 18 | 19 | libsize = os.path.getsize(lib) 20 | 21 | print("------", os.path.basename(lib), "file size:", libsize, end='') 22 | 23 | if os.path.exists(save): 24 | with open(save) as sf: 25 | oldsize = int(sf.readline()) 26 | 27 | if oldsize > 0: 28 | change = libsize - oldsize 29 | if change == 0: 30 | print(" (no change)") 31 | else: 32 | print(" (change of {:+} bytes = {:+.2%})".format(change, change / oldsize)) 33 | else: 34 | print() 35 | 36 | with open(save, 'w') as sf: 37 | sf.write(str(libsize)) 38 | 39 | -------------------------------------------------------------------------------- /c_segment/segment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/c_segment/segment -------------------------------------------------------------------------------- /c_segment/segment-graph.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #ifndef SEGMENT_GRAPH 20 | #define SEGMENT_GRAPH 21 | 22 | #include 23 | #include 24 | #include "disjoint-set.h" 25 | 26 | // threshold function 27 | #define THRESHOLD(size, c) (c/size) 28 | 29 | typedef struct { 30 | float w; 31 | int a, b; 32 | } edge; 33 | 34 | bool operator<(const edge &a, const edge &b) { 35 | return a.w < b.w; 36 | } 37 | 38 | /* 39 | * Segment a graph 40 | * 41 | * Returns a disjoint-set forest representing the segmentation. 42 | * 43 | * num_vertices: number of vertices in graph. 44 | * num_edges: number of edges in graph 45 | * edges: array of edges. 46 | * c: constant for treshold function. 47 | */ 48 | universe *segment_graph(int num_vertices, int num_edges, edge *edges, 49 | float c) { 50 | // sort edges by weight 51 | std::sort(edges, edges + num_edges); 52 | 53 | // make a disjoint-set forest 54 | universe *u = new universe(num_vertices); 55 | 56 | // init thresholds 57 | float *threshold = new float[num_vertices]; 58 | for (int i = 0; i < num_vertices; i++) 59 | threshold[i] = THRESHOLD(1,c); 60 | 61 | // for each edge, in non-decreasing weight order... 62 | for (int i = 0; i < num_edges; i++) { 63 | edge *pedge = &edges[i]; 64 | 65 | // components conected by this edge 66 | int a = u->find(pedge->a); 67 | int b = u->find(pedge->b); 68 | if (a != b) { 69 | if ((pedge->w <= threshold[a]) && 70 | (pedge->w <= threshold[b])) { 71 | u->join(a, b); 72 | a = u->find(a); 73 | threshold[a] = pedge->w + THRESHOLD(u->size(a), c); 74 | } 75 | } 76 | } 77 | 78 | // free up 79 | delete threshold; 80 | return u; 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /c_segment/segment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2006 Pedro Felzenszwalb 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include "image.h" 23 | #include "misc.h" 24 | #include "pnmfile.h" 25 | #include "segment-image.h" 26 | 27 | int main(int argc, char **argv) { 28 | 29 | argc = 6; 30 | argv = new char*[6]; 31 | for(int i=0; i<6; i++){ 32 | argv[i] = new char[100]; 33 | } 34 | argv[0] = "/mnt/d/downloads/pybind11_examples/build/c_segment_test"; 35 | argv[1] = "0.83"; 36 | argv[2] = "450"; 37 | argv[3] = "334"; 38 | argv[4] = "/mnt/d/downloads/pybind11_examples/c_segment/002053.ppm"; 39 | argv[5] = "/mnt/d/downloads/pybind11_examples/c_segment/002053_out.ppm"; 40 | 41 | if (argc != 6) { 42 | fprintf(stderr, "usage: %s sigma k min input(ppm) output(ppm)\n", argv[0]); 43 | return 1; 44 | } 45 | 46 | float sigma = atof(argv[1]); 47 | float k = atof(argv[2]); 48 | int min_size = atoi(argv[3]); 49 | 50 | printf("loading input image.\n"); 51 | image *input = loadPPM(argv[4]); 52 | 53 | printf("processing\n"); 54 | int num_ccs; 55 | image *seg = segment_image(input, sigma, k, min_size, &num_ccs); 56 | savePPM(seg, argv[5]); 57 | 58 | printf("got %d components\n", num_ccs); 59 | printf("done! uff...thats hard work.\n"); 60 | 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /computeIntegralImageScores.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def compute_integral_img_scores(integral_img, windows): 5 | """ 6 | Computes the score of the windows wrt the integral_img 7 | :param integral_img: 8 | :param windows: (x1, y1, x2, y2) 9 | :return: 10 | """ 11 | windows = np.round(windows).astype(np.int) 12 | windows[windows == 0] = 1 13 | windows -= 1 # From matlab indices to numpy indices 14 | 15 | width = integral_img.shape[1] 16 | integral_img = integral_img.reshape(-1) 17 | # The -1 is to transform the matlab index to numpy index 18 | index1 = width * (windows[:, 3] + 1) + windows[:, 2] 19 | index2 = width * (windows[:, 1]) + windows[:, 0] - 1 20 | index3 = width * (windows[:, 3] + 1) + windows[:, 0] - 1 21 | index4 = width * (windows[:, 1]) + windows[:, 2] 22 | 23 | # Original matlab code: 24 | # integral_img = integral_img.T.reshape(-1) 25 | # height = integral_img.shape[0] 26 | # index1 = height * windows[:, 2] + (windows[:, 3] + 1) 27 | # index2 = height * (windows[:, 0] - 1) + windows[:, 1] 28 | # index3 = height * (windows[:, 0] - 1) + (windows[:, 3] + 1) 29 | # index4 = height * windows[:, 2] + windows[:, 1] 30 | 31 | score = integral_img[index1] + integral_img[index2] - integral_img[index3] - integral_img[index4] 32 | 33 | return score 34 | -------------------------------------------------------------------------------- /computeObjectnessHeatMap.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | 4 | 5 | def compute_objectness_heat_map(img, boxes): 6 | map = np.zeros((img.shape[0], img.shape[1])) 7 | for box in boxes: 8 | x1, y1, x2, y2 = box[:4].astype(np.int) 9 | score = box[4] 10 | map[y1:y2, x1:x2] += score 11 | 12 | plt.figure() 13 | 14 | plt.subplot(2, 1, 1).set_title('Input image') 15 | plt.imshow(img) 16 | plt.axis('off') 17 | 18 | plt.subplot(2, 1, 2).set_title('Objectness heat map') 19 | plt.imshow(map, cmap=plt.get_cmap('jet')) 20 | plt.axis('off') 21 | 22 | plt.show() 23 | -------------------------------------------------------------------------------- /computeQuantMatrix.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | 4 | 5 | def compute_quant_matrix(lab_img, bins): 6 | """ 7 | Compute the quantization matrix based on the 3-dimensional matrix lab_img 8 | :param lab_img: 9 | :param bins: 10 | :return: 11 | """ 12 | assert len(bins) == 3, 'Need 3 bins for quantization' 13 | 14 | L = lab_img[:, :, 0] 15 | a = lab_img[:, :, 1] 16 | b = lab_img[:, :, 2] 17 | 18 | ll = np.minimum(np.floor(L / (100 / bins[0])) + 1, bins[0]) 19 | aa = np.minimum(np.floor((a + 120) / (240 / bins[1])) + 1, bins[1]) 20 | bb = np.minimum(np.floor((b + 120) / (240 / bins[2])) + 1, bins[2]) 21 | 22 | Q = (ll - 1) * bins[1] * bins[2] + (aa - 1) * bins[2] + bb 23 | return Q -------------------------------------------------------------------------------- /defaultParams.py: -------------------------------------------------------------------------------- 1 | from easydict import EasyDict as edict 2 | import os 3 | import numpy as np 4 | 5 | 6 | def default_params(root_dir): 7 | params = edict() 8 | 9 | # params in general 10 | params.min_window_height = 10 11 | params.min_window_width = 10 12 | params.distribution_windows = 100000 13 | params.sampled_windows = 1000 14 | params.trainingImages = os.path.join(root_dir, 'Training/Images') 15 | params.trainingExamples = os.path.join(root_dir, 'Training/Images/Examples') 16 | params.imageType = 'jpg' 17 | params.data = os.path.join(root_dir, 'Data') 18 | params.yourData = os.path.join(root_dir, 'Data/yourData') 19 | params.pobj = 0.0797 20 | params.tempdir = os.path.join(root_dir, 'tmpdir') 21 | params.pascalThreshold = 0.5 22 | params.cues = ['MS', 'CC', 'SS'] # full objectness measure 23 | params.sampling = 'nms' # alternative sampling method - 'multinomial' 24 | 25 | # params for MS 26 | params.MS = edict() 27 | params.MS.name = 'Multiscale-Saliency' 28 | params.MS.colortype = 'rgb' 29 | params.MS.filtersize = 3 30 | params.MS.scale = np.array([16, 24, 32, 48, 64]) 31 | params.MS.theta = np.array([0.43, 0.32, 0.34, 0.35, 0.26]) 32 | params.MS.domain = np.tile(np.arange(0.01, 1.01, 0.01), (5, 1)) 33 | params.MS.sizeNeighborhood = 7 34 | params.MS.bincenters = np.arange(0, 501, 1) 35 | params.MS.numberBins = len(params.MS.bincenters) - 1 36 | 37 | # params for CC 38 | params.CC = edict() 39 | params.CC.name = 'Color-Contrast' 40 | params.CC.theta = 100 41 | params.CC.domain = np.arange(1, 201, 1) 42 | params.CC.quant = np.array([4, 8, 8]) 43 | params.CC.bincenters = np.arange(0, 2.01, 0.01) 44 | params.CC.numberBins = len(params.CC.bincenters) - 1 45 | 46 | # params for ED 47 | params.ED = edict() 48 | params.ED.name = 'Edge-Density' 49 | params.ED.theta = 17 50 | params.ED.domain = np.arange(1, 101, 1) 51 | params.ED.crop_size = 200 52 | params.ED.pixelDistance = 8 53 | params.ED.imageBorder = 0 54 | params.ED.bincenters = np.arange(0, 5.05, 0.05) 55 | params.ED.numberBins = len(params.ED.bincenters) - 1 56 | 57 | # params for SS 58 | params.SS = edict() 59 | params.SS.name = 'Superpixels-Straddling' 60 | params.SS.basis_sigma = 0.5 61 | params.SS.theta = 450 62 | params.SS.domain = np.arange(200, 2025, 25) 63 | params.SS.basis_min_area = 200 64 | params.SS.soft_dir = os.path.join(root_dir, 'segment') 65 | params.SS.pixelDistance = 8 66 | params.SS.imageBorder = 0.05 67 | params.SS.bincenters = np.arange(0, 1.01, 0.01) 68 | params.SS.numberBins = len(params.SS.bincenters) - 1 69 | 70 | return params 71 | -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | from runObjectness import run_objectness 2 | import cv2 3 | from defaultParams import default_params 4 | from drawBoxes import draw_boxes 5 | from computeObjectnessHeatMap import compute_objectness_heat_map 6 | import time 7 | 8 | 9 | img_example = cv2.imread('002053.jpg')[:, :, ::-1] 10 | params = default_params('.') 11 | # params.cues = ['SS'] 12 | 13 | tic = time.time() 14 | boxes = run_objectness(img_example, 10, params) 15 | toc = time.time() 16 | 17 | print("%f" % (toc - tic)) 18 | draw_boxes(img_example, boxes, base_color=(1, 0, 0)) 19 | compute_objectness_heat_map(img_example, boxes) 20 | -------------------------------------------------------------------------------- /drawBoxes.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | def draw_boxes(img, boxes, base_color=(1, 0, 0), line_width=3): 7 | base_color = np.array(base_color) 8 | boxes = boxes[np.argsort(-boxes[:, 4])] # Sort in descending order of score 9 | max_score = np.max(boxes[:, 4]) 10 | ax = plt.gca() 11 | ax.imshow(img) 12 | for box in boxes: 13 | xmin, ymin, xmax, ymax, score = box 14 | color = base_color * score / max_score 15 | rect = plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, linewidth=line_width, edgecolor=color, fill=False) 16 | ax.add_patch(rect) 17 | plt.axis('off') 18 | plt.show() 19 | -------------------------------------------------------------------------------- /integralHistSuperpixels.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | 4 | 5 | def integral_hist_superpixels(N): 6 | total_segms = np.max(N) + 1 # Segmentation id starts from 0 7 | height, width = N.shape 8 | 9 | integral_hist = np.zeros((height + 1, width + 1, total_segms)) 10 | 11 | for sid in range(total_segms): 12 | superpixel_map = (N == sid).astype(np.uint8) 13 | integral_hist[:, :, sid] = cv2.integral(superpixel_map) 14 | 15 | return integral_hist 16 | -------------------------------------------------------------------------------- /integrateBayes.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import mat4py 3 | from easydict import EasyDict as edict 4 | import os 5 | 6 | 7 | def integrate_bayes(cues, score, params): 8 | likelihood = [] 9 | for i, cue in enumerate(cues): 10 | if cue == 'MS': 11 | struct = mat4py.loadmat(os.path.join(params.data, 'MSlikelihood.mat')) 12 | likelihood.append(np.array(struct['likelihood'])) 13 | elif cue == 'CC': 14 | struct = mat4py.loadmat(os.path.join(params.data, 'CClikelihood.mat')) 15 | likelihood.append(np.array(struct['likelihood'])) 16 | elif cue == 'ED': 17 | struct = mat4py.loadmat(os.path.join(params.data, 'EDlikelihood.mat')) 18 | likelihood.append(np.array(struct['likelihood'])) 19 | elif cue == 'SS': 20 | struct = mat4py.loadmat(os.path.join(params.data, 'SSlikelihood.mat')) 21 | likelihood.append(np.array(struct['likelihood'])) 22 | else: 23 | raise Exception('Unknown cue') 24 | 25 | bin_number = [] 26 | for cue_id, cue in enumerate(cues): 27 | if cue == 'MS': 28 | bin_number.append(np.maximum(np.minimum(np.ceil(score[:, cue_id] + 0.5), params.MS.numberBins + 1), 1)) 29 | elif cue == 'CC': 30 | bin_number.append(np.maximum(np.minimum(np.ceil(score[:, cue_id] * 100 + 0.5), params.CC.numberBins + 1), 1)) 31 | elif cue == 'ED': 32 | bin_number.append(np.maximum(np.minimum(np.ceil(score[:, cue_id] * 2 + 0.5), params.ED.numberBins + 1), 1)) 33 | elif cue == 'SS': 34 | bin_number.append(np.maximum(np.minimum(np.ceil(score[:, cue_id] * 100 + 0.5), params.SS.numberBins + 1), 1)) 35 | else: 36 | raise Exception('Unknown cue') 37 | 38 | p_obj = params.pobj 39 | score_bayes = np.zeros(len(score)) 40 | bin_number = np.array(bin_number, dtype=np.int) 41 | bin_number -= 1 # From matlab index to numpy index 42 | 43 | for bb_id in range(len(score_bayes)): 44 | temp_pos = 1 45 | temp_neg = 1 46 | 47 | for cue_id in range(len(cues)): 48 | temp_pos *= likelihood[cue_id][0, bin_number[cue_id][bb_id]] 49 | temp_neg *= likelihood[cue_id][1, bin_number[cue_id][bb_id]] 50 | 51 | denominator = (temp_pos * p_obj + temp_neg * (1 - p_obj)) 52 | if denominator: 53 | score_bayes[bb_id] = temp_pos * p_obj / (temp_pos * p_obj + temp_neg * (1 - p_obj)) 54 | 55 | score_bayes += np.finfo(float).eps 56 | return score_bayes 57 | -------------------------------------------------------------------------------- /matlab_functions/fspecial.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | 4 | 5 | def fspecial(type, radius): 6 | if type == 'average': 7 | return np.ones((radius, radius), dtype=np.float) / (radius * radius) 8 | elif type == 'disk': 9 | crad = math.ceil(radius - 0.5) 10 | x, y = np.meshgrid(np.arange(-crad, crad + 1), np.arange(-crad, crad + 1)) 11 | 12 | maxxy = np.maximum(np.abs(x), np.abs(y)) 13 | minxy = np.minimum(np.abs(x), np.abs(y)) 14 | m1 = (radius ** 2 < (maxxy + 0.5) ** 2 + (minxy - 0.5) ** 2) * (minxy - 0.5) + \ 15 | (radius ** 2 >= (maxxy + 0.5) ** 2 + (minxy - 0.5) ** 2) * np.sqrt(radius ** 2 - (maxxy + 0.5) ** 2, dtype=np.complex) 16 | m2 = (radius ** 2 > (maxxy - 0.5) ** 2 + (minxy + 0.5) ** 2) * (minxy + 0.5) + \ 17 | (radius ** 2 <= (maxxy - 0.5) ** 2 + (minxy + 0.5) ** 2) * np.sqrt(radius ** 2 - (maxxy - 0.5) ** 2, dtype=np.complex) 18 | sgrid = (radius ** 2 * (0.5 * (np.arcsin(m2 / radius) - np.arcsin(m1 / radius)) + 0.25 * 19 | (np.sin(2 * np.arcsin(m2 / radius)) - np.sin(2 * np.arcsin(m1 / radius)))) - 20 | (maxxy - 0.5) * (m2 - m1) + (m1 - minxy + 0.5)) * \ 21 | ((((radius ** 2 < (maxxy + 0.5) ** 2 + (minxy + 0.5) ** 2) & (radius ** 2 > (maxxy - 0.5) ** 2 + (minxy - 0.5) ** 2)) | 22 | ((minxy == 0) & (maxxy - 0.5 < radius) & (maxxy + 0.5 >= radius)))) 23 | 24 | sgrid = sgrid + ((maxxy + 0.5) ** 2 + (minxy + 0.5) ** 2 < radius ** 2) 25 | sgrid[crad + 1, crad + 1] = min(np.pi * radius ** 2, np.pi / 2) 26 | if (crad > 0) and (radius > crad - 0.5) and (radius ** 2 < (crad - 0.5) ** 2 + 0.25): 27 | m1 = np.sqrt(radius ** 2 - (crad - 0.5) ** 2, dtype=np.complex) 28 | m1n = m1 / radius 29 | sg0 = 2 * (radius ** 2 * (0.5 * np.arcsin(m1n) + 0.25 * np.sin(2 * np.arcsin(m1n))) - m1 * (crad - 0.5)) 30 | sgrid[2 * crad + 1, crad + 1] = sg0 31 | sgrid[crad + 1, 2 * crad + 1] = sg0 32 | sgrid[crad + 1, 1] = sg0 33 | sgrid[1, crad + 1] = sg0 34 | sgrid[2 * crad, crad + 1] = sgrid[2 * crad, crad + 1] - sg0 35 | sgrid[crad + 1, 2 * crad] = sgrid[crad + 1, 2 * crad] - sg0 36 | sgrid[crad + 1, 2] = sgrid[crad + 1, 2] - sg0 37 | sgrid[2, crad + 1] = sgrid[2, crad + 1] - sg0 38 | 39 | sgrid[crad + 1, crad + 1] = min(sgrid[crad + 1, crad + 1], 1) 40 | h = sgrid / np.sum(sgrid[:]) 41 | return h.real 42 | 43 | 44 | if __name__ == "__main__": 45 | kernel = fspecial('disk', 5) 46 | print(kernel) 47 | -------------------------------------------------------------------------------- /matlab_functions/mat2gray.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def mat2gray(A): 5 | limits = np.array([np.min(A), np.max(A)], dtype=np.float) 6 | delta = limits[1] - limits[0] 7 | I = (A.astype(np.float) - limits[0]) / delta 8 | I = np.maximum(0, np.minimum(1, I)) # Make sure all values are between 0 and 1. 9 | return I -------------------------------------------------------------------------------- /mex_functions/NMS_sampling.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numba import jit 3 | 4 | 5 | @jit(nopython=True) 6 | def NMS_sampling(area, overlap, xmin, ymin, xmax, ymax, num_windows): 7 | ndx = np.ones(num_windows, dtype=np.int32) * -1 8 | total = len(xmin) 9 | visited = np.zeros(total, dtype=np.int32) 10 | 11 | ndx_not_visited = 0 12 | for w in range(num_windows): 13 | ndx[w] = ndx_not_visited 14 | visited[ndx_not_visited] = 1 15 | 16 | for j in range(ndx_not_visited + 1, total): 17 | xx1 = max(xmin[ndx_not_visited], xmin[j]) 18 | yy1 = max(ymin[ndx_not_visited], ymin[j]) 19 | xx2 = min(xmax[ndx_not_visited], xmax[j]) 20 | yy2 = min(ymax[ndx_not_visited], ymax[j]) 21 | 22 | width = xx2 - xx1 + 1 23 | height = yy2 - yy1 + 1 24 | 25 | if width > 0 and height > 0: 26 | ov = (width * height) / (area[ndx_not_visited] + area[j] - width * height) 27 | if ov > 0.5: 28 | visited[j] = 1 29 | 30 | while ndx_not_visited < total and visited[ndx_not_visited] > 0: 31 | ndx_not_visited += 1 32 | 33 | if ndx_not_visited == total: 34 | break 35 | 36 | return ndx, visited 37 | -------------------------------------------------------------------------------- /mex_functions/computeIntegralHistogram.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numba import jit 3 | import math 4 | import cv2 5 | 6 | 7 | @jit(nopython=True) 8 | def compute_integral_histogram(quant_matrix, height, width, prod_quant): 9 | # flatten_quant_matrix = quant_matrix.reshape(-1) 10 | int_hist = np.zeros(prod_quant * (height + 1) * (width + 1)) 11 | for i in range(1, height + 1): 12 | for j in range(1, width + 1): 13 | x1 = math.floor(quant_matrix[i - 1, j - 1]) 14 | int_hist[prod_quant * (j * (height + 1) + i) + x1 - 1] = 1 # corresponding bin has value=1 at location (i,j) 15 | 16 | for k in range(prod_quant): 17 | int_hist[prod_quant * (j * (height + 1) + i) + k] += int_hist[prod_quant * (j * (height + 1) + i - 1) + k] + int_hist[prod_quant * ((j - 1) * (height + 1) + i) + k] - int_hist[prod_quant * ((j - 1) * (height + 1) + i - 1) + k] 18 | 19 | # return int_hist.reshape((height + 1) * (width + 1), prod_quant).T # First row-major, then col-major 20 | return int_hist 21 | 22 | 23 | if __name__ == "__main__": 24 | quant_matrix = np.random.rand(270, 480) 25 | int_hist = compute_integral_histogram(quant_matrix, 270, 480, 256) 26 | pass 27 | -------------------------------------------------------------------------------- /mex_functions/computeScoreContrast.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numba import jit 3 | 4 | 5 | @jit(nopython=True) 6 | def compute_score_contrast(integral_histogram, height, width, xmin, ymin, xmax, ymax, thetaCC, prod_quant, num_windows): 7 | """ 8 | 9 | :param integral_histogram: Column-first major array, flatten from (prod_quant, (height + 1) * (width + 1)). 10 | :param height: 11 | :param width: 12 | :param xmin: 13 | :param ymin: 14 | :param xmax: 15 | :param ymax: 16 | :param thetaCC: 17 | :param prod_quant: 18 | :param num_windows: 19 | :return: 20 | """ 21 | # assert len(integral_histogram.shape) == 2, "integral_histogram must be a real double matrix" 22 | # assert integral_histogram.shape[1] == (height + 1) * (width + 1), "integral_histogram must be a real double matrix" 23 | # integral_histogram = integral_histogram.reshape(-1) 24 | 25 | contrast = np.zeros(num_windows) 26 | 27 | inside = np.zeros(prod_quant) 28 | outside = np.zeros(prod_quant) 29 | 30 | inside1 = np.zeros(prod_quant) 31 | outside1 = np.zeros(prod_quant) 32 | 33 | for w in range(num_windows): 34 | obj_width = xmax[w] - xmin[w] + 1 35 | obj_height = ymax[w] - ymin[w] + 1 36 | sum_inside = 0 37 | 38 | assert (obj_width > 0) and (obj_height > 0), "Error xmax - xmin <= 0 or ymax - ymin <= 0" 39 | 40 | maxmax = int(prod_quant * (xmax[w] * (height + 1) + ymax[w])) 41 | minmin = int(prod_quant * ((xmin[w] - 1) * (height + 1) + ymin[w] - 1)) 42 | maxmin = int(prod_quant * (xmax[w] * (height + 1) + ymin[w] - 1)) 43 | minmax = int(prod_quant * ((xmin[w] - 1) * (height + 1) + ymax[w])) 44 | 45 | # maxmax = int(prod_quant * (ymax[w] * (width + 1) + xmax[w])) 46 | # minmin = int(prod_quant * ((ymin[w] - 1) * (width + 1) + xmin[w] - 1)) 47 | # maxmin = int(prod_quant * ((ymin[w] - 1) * (width + 1) + xmax[w])) 48 | # minmax = int(prod_quant * ((ymax[w]) * (width + 1) + xmin[w] - 1)) 49 | 50 | for k in range(prod_quant): 51 | inside[k] = integral_histogram[maxmax + k] + integral_histogram[minmin + k] - integral_histogram[maxmin + k] - integral_histogram[minmax + k] 52 | sum_inside += inside[k] 53 | 54 | for k in range(prod_quant): 55 | if sum_inside: 56 | inside1[k] = inside[k] / sum_inside 57 | 58 | offset_width = float(obj_width) * thetaCC / 200. 59 | offset_height = float(obj_height) * thetaCC / 200. 60 | 61 | xmin_surr = round(max(xmin[w] - offset_width, 1)) 62 | xmax_surr = round(min(xmax[w] + offset_width, width)) 63 | ymin_surr = round(max(ymin[w] - offset_height, 1)) 64 | ymax_surr = round(min(ymax[w] + offset_height, height)) 65 | 66 | maxmax = int(prod_quant * (xmax_surr * (height + 1) + ymax_surr)) 67 | minmin = int(prod_quant * ((xmin_surr - 1) * (height + 1) + ymin_surr - 1)) 68 | maxmin = int(prod_quant * (xmax_surr * (height + 1) + ymin_surr - 1)) 69 | minmax = int(prod_quant * ((xmin_surr - 1) * (height + 1) + ymax_surr)) 70 | 71 | # maxmax = int(prod_quant * (ymax_surr * (width + 1) + xmax_surr)) 72 | # minmin = int(prod_quant * ((ymin_surr - 1) * (width + 1) + xmin_surr - 1)) 73 | # maxmin = int(prod_quant * ((ymax_surr - 1) * (width + 1) + xmin_surr)) 74 | # minmax = int(prod_quant * (ymax_surr * (width + 1) + xmin_surr - 1)) 75 | 76 | sum_outside = 0 77 | for k in range(prod_quant): 78 | outside[k] = integral_histogram[maxmax + k] + integral_histogram[minmin + k] - integral_histogram[maxmin + k] - integral_histogram[minmax + k] - inside[k] 79 | sum_outside += outside[k] 80 | 81 | for k in range(prod_quant): 82 | if sum_outside: 83 | outside1[k] = outside[k] / sum_outside 84 | if outside1[k] + inside1[k]: 85 | contrast[w] += (inside1[k] - outside1[k]) * (inside1[k] - outside1[k]) / (inside1[k] + outside1[k]) 86 | else: 87 | contrast[w] = 0 88 | 89 | return contrast 90 | -------------------------------------------------------------------------------- /mex_functions/scoreSampling.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numba import jit 3 | import random 4 | import math 5 | 6 | 7 | @jit(nopython=True) 8 | def score_sampling(score_vector, num_samples, option): 9 | if option == 0 and (num_samples > len(score_vector)): 10 | raise Exception("num_samples <= length score_vector (sampling without replacement)") 11 | 12 | index = np.zeros(num_samples, dtype=np.int32) 13 | cumsum = np.cumsum(score_vector) 14 | score_vector_copy = score_vector.copy() 15 | 16 | for i in range(num_samples): 17 | r = random.random() * cumsum[-1] 18 | minim = 0 19 | maxim = len(score_vector) - 1 20 | interval_length = maxim - minim + 1 21 | 22 | while interval_length > 2: 23 | middle = math.floor((minim + maxim) / 2) 24 | if cumsum[middle] > r: 25 | maxim = middle 26 | else: 27 | minim = middle 28 | 29 | interval_length = maxim - minim + 1 30 | 31 | if cumsum[minim] > r: 32 | index[i] = minim 33 | else: 34 | index[i] = maxim 35 | 36 | if option == 0: 37 | j = math.floor(index[i]) 38 | score_vector_copy[j] = 0 39 | cumsum[0] = score_vector_copy[0] 40 | for j in range(1, len(score_vector)): 41 | cumsum[j] = cumsum[j - 1] + score_vector_copy[j] 42 | 43 | # index += 1 44 | return index 45 | 46 | 47 | if __name__ == '__main__': 48 | score_vector = np.random.rand(1000) 49 | score_sampling(score_vector, 10, 1) 50 | -------------------------------------------------------------------------------- /mex_functions/slidingWindowComputeScore.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numba import jit 3 | 4 | 5 | @jit(nopython=True) 6 | def sliding_window_compute_score(saliency_map, scale, min_width, min_height, threshold, salmap_int, thrmap_int): 7 | score_scale = np.zeros(scale ** 4) 8 | image_area = scale * scale 9 | 10 | # salmap_int = salmap_int.reshape(-1) 11 | # thrmap_int = thrmap_int.reshape(-1) 12 | 13 | for xmin in range(1, scale - min_width + 2): 14 | for ymin in range(1, scale - min_height + 2): 15 | for xmax in range(xmin + min_width - 1, scale + 1): 16 | for ymax in range(ymin + min_height - 1, scale + 1): 17 | area = (xmax - xmin + 1) * (ymax - ymin + 1) 18 | aval = salmap_int[ymax, xmax] + salmap_int[ymin - 1, xmin - 1] - salmap_int[ymin - 1, xmax] - salmap_int[ymax, xmin - 1] 19 | athr = thrmap_int[ymax, xmax] + thrmap_int[ymin - 1, xmin - 1] - thrmap_int[ymin - 1, xmax] - thrmap_int[ymax, xmin - 1] 20 | # aval = salmap_int[(scale + 1) * (xmax - 1 + 1) + (ymax - 1 + 1)] + salmap_int[(scale + 1) * (xmin - 1) + (ymin - 1)] - \ 21 | # salmap_int[(scale + 1) * (xmax - 1 + 1) + (ymin - 1)] - salmap_int[(scale + 1) * (xmin - 1) + (ymax - 1 + 1)] 22 | # athr = thrmap_int[(scale + 1) * (xmax - 1 + 1) + (ymax - 1 + 1)] + thrmap_int[(scale + 1) * (xmin - 1) + (ymin - 1)] - \ 23 | # thrmap_int[(scale + 1) * (xmax - 1 + 1) + (ymin - 1)] - thrmap_int[(scale + 1) * (xmin - 1) + (ymax - 1 + 1)] 24 | score_scale[image_area * ((ymax - 1) * scale + xmax - 1) + ((ymin - 1) * scale + xmin - 1)] = (aval * athr) / area 25 | 26 | # return score_scale.reshape((scale * scale, scale * scale)) 27 | return score_scale -------------------------------------------------------------------------------- /nms_pascal.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from mex_functions.NMS_sampling import NMS_sampling 3 | 4 | 5 | def nms_pascal(boxes, overlap, max_windows=1000): 6 | """ 7 | Greedily select high-scoring detections and skip detections that are significantly covered by a previously selected 8 | detection. 9 | :param boxes: 10 | :param overlap: 11 | :param max_windows: 12 | :return: 13 | """ 14 | if len(boxes) == 0: 15 | return [] 16 | x1 = boxes[:, 0] 17 | y1 = boxes[:, 1] 18 | x2 = boxes[:, 2] 19 | y2 = boxes[:, 3] 20 | s = boxes[:, 4] 21 | area = (x2 - x1 + 1) * (y2 - y1 + 1) 22 | 23 | I = np.argsort(-s) 24 | pick, _ = NMS_sampling(area[I], overlap, x1[I], y1[I], x2[I], y2[I], max_windows) 25 | pick = pick[pick >= 0] 26 | top = boxes[I[pick], :] 27 | 28 | return top 29 | -------------------------------------------------------------------------------- /py_segment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/py_segment/__init__.py -------------------------------------------------------------------------------- /py_segment/graph.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, parent, rank=0, size=1): 3 | self.parent = parent 4 | self.rank = rank 5 | self.size = size 6 | 7 | def __repr__(self): 8 | return '(parent=%s, rank=%s, size=%s)' % (self.parent, self.rank, self.size) 9 | 10 | class Forest: 11 | def __init__(self, num_nodes): 12 | self.nodes = [Node(i) for i in range(num_nodes)] 13 | self.num_sets = num_nodes 14 | 15 | def size_of(self, i): 16 | return self.nodes[i].size 17 | 18 | def find(self, n): 19 | temp = n 20 | while temp != self.nodes[temp].parent: 21 | temp = self.nodes[temp].parent 22 | 23 | self.nodes[n].parent = temp 24 | return temp 25 | 26 | def merge(self, a, b): 27 | if self.nodes[a].rank > self.nodes[b].rank: 28 | self.nodes[b].parent = a 29 | self.nodes[a].size = self.nodes[a].size + self.nodes[b].size 30 | else: 31 | self.nodes[a].parent = b 32 | self.nodes[b].size = self.nodes[b].size + self.nodes[a].size 33 | 34 | if self.nodes[a].rank == self.nodes[b].rank: 35 | self.nodes[b].rank = self.nodes[b].rank + 1 36 | 37 | self.num_sets = self.num_sets - 1 38 | 39 | def print_nodes(self): 40 | for node in self.nodes: 41 | print(node) 42 | 43 | 44 | def create_edge(img, width, x, y, x1, y1, diff): 45 | vertex_id = lambda x, y: y * width + x 46 | w = diff(img, x, y, x1, y1) 47 | return (vertex_id(x, y), vertex_id(x1, y1), w) 48 | 49 | 50 | def build_graph(img, width, height, diff, neighborhood_8=False): 51 | graph_edges = [] 52 | for y in range(height): 53 | for x in range(width): 54 | if x > 0: 55 | graph_edges.append(create_edge(img, width, x, y, x - 1, y, diff)) 56 | 57 | if y > 0: 58 | graph_edges.append(create_edge(img, width, x, y, x, y - 1, diff)) 59 | 60 | if neighborhood_8: 61 | if x > 0 and y > 0: 62 | graph_edges.append(create_edge(img, width, x, y, x - 1, y - 1, diff)) 63 | 64 | if x > 0 and y < height - 1: 65 | graph_edges.append(create_edge(img, width, x, y, x - 1, y + 1, diff)) 66 | 67 | return graph_edges 68 | 69 | 70 | def remove_small_components(forest, graph, min_size): 71 | for edge in graph: 72 | a = forest.find(edge[0]) 73 | b = forest.find(edge[1]) 74 | 75 | if a != b and (forest.size_of(a) < min_size or forest.size_of(b) < min_size): 76 | forest.merge(a, b) 77 | 78 | return forest 79 | 80 | 81 | def segment_graph(graph_edges, num_nodes, const, min_size, threshold_func): 82 | # Step 1: initialization 83 | forest = Forest(num_nodes) 84 | weight = lambda edge: edge[2] 85 | sorted_graph = sorted(graph_edges, key=weight) 86 | threshold = [ threshold_func(1, const) for _ in range(num_nodes) ] 87 | 88 | # Step 2: merging 89 | for edge in sorted_graph: 90 | parent_a = forest.find(edge[0]) 91 | parent_b = forest.find(edge[1]) 92 | a_condition = weight(edge) <= threshold[parent_a] 93 | b_condition = weight(edge) <= threshold[parent_b] 94 | 95 | if parent_a != parent_b and a_condition and b_condition: 96 | forest.merge(parent_a, parent_b) 97 | a = forest.find(parent_a) 98 | threshold[a] = weight(edge) + threshold_func(forest.nodes[a].size, const) 99 | 100 | return remove_small_components(forest, sorted_graph, min_size) 101 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # python-objectness 2 | Python implementation of PAMI 2012 paper "[Measuring the Objectness of Image Windows](https://doi.org/10.1109/TPAMI.2012.28)" and CVPR 2010 paper "[What is an object ?](https://ieeexplore.ieee.org/document/5540226/)". 3 | 4 | This implementation is based on the [original matlab code](http://www.vision.ee.ethz.ch/~calvin). 5 | 6 | ## Results 7 | ![Python](results/my_impl/002053_comb_boxes.png) 8 | ![Python](results/my_impl/002053_comb_heatmap.png) 9 | 10 | Detailed comparisons to the original Matlab implementation can be found [here](results/readme.md). 11 | 12 | ## Get started 13 | 14 | 1. Clone this repository: 15 | 16 | ``` 17 | git clone https://github.com/RookieHong/python-objectness.git 18 | cd python-objectness 19 | ``` 20 | 21 | 2. Install the [requirements](#Requirements) below. 22 | 23 | 3. Run the demo and see the results: 24 | 25 | ``` 26 | python demo.py 27 | ``` 28 | 29 | 4. (Optional, but recommended) A python implementation of superpixels segmentation is used as default, you can do the following to use the official C++ implementation through [pybind11](https://github.com/pybind/pybind11) instead (faster and more accurate): 30 | 31 | ``` 32 | # Compile the python interface 33 | $ sudo apt install cmake # Install cmake 34 | $ cd c_segment 35 | $ mkdir build 36 | $ cd build 37 | $ cmake .. && make 38 | ``` 39 | 40 | Then, switch from py_segment to c_segment by modifying these two lines in [computeScores.py](computeScores.py): 41 | ``` 42 | # Comment the py_segment line and uncomment the c_segment line 43 | 44 | S = c_segment_img(img=img, sigma=sigma, k=k, min_area=min_area) # C segment 45 | # S = py_segment_img(img=img, sigma=sigma, neighbor=4, K=k, min_comp_size=min_area) # Python segment 46 | ``` 47 | 48 | 49 | ## Requirements 50 | - numpy 51 | - opencv-python 52 | - easydict 53 | - mat4py 54 | - numba 55 | 56 | ## Notes 57 | 58 | Because the implementation of many functions in MATLAB and numpy is different, the results might be slightly different from the original code. 59 | 60 | The superpixel computation code in `py-segment` folder is modified from a [python implementation](https://github.com/luisgabriel/image-segmentation), so this will also cause differences in code results. 61 | 62 | 63 | ## To-do 64 | 65 | - [ ] Simplify the indices to make them more readable. 66 | 67 | ## Citation 68 | 69 | If you find this repository useful, consider citing their paper: 70 | 71 | ``` 72 | @article{alexe2012measuring, 73 | title={Measuring the objectness of image windows}, 74 | author={Alexe, Bogdan and Deselaers, Thomas and Ferrari, Vittorio}, 75 | journal={IEEE transactions on pattern analysis and machine intelligence}, 76 | volume={34}, 77 | number={11}, 78 | pages={2189--2202}, 79 | year={2012}, 80 | publisher={IEEE} 81 | } 82 | ``` 83 | 84 | ``` 85 | @inproceedings{alexe2010object, 86 | title={What is an object?}, 87 | author={Alexe, Bogdan and Deselaers, Thomas and Ferrari, Vittorio}, 88 | booktitle={2010 IEEE computer society conference on computer vision and pattern recognition}, 89 | pages={73--80}, 90 | year={2010}, 91 | organization={IEEE} 92 | } 93 | ``` -------------------------------------------------------------------------------- /results/my_impl/002053_CC_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_CC_boxes.png -------------------------------------------------------------------------------- /results/my_impl/002053_CC_heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_CC_heatmap.png -------------------------------------------------------------------------------- /results/my_impl/002053_ED_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_ED_boxes.png -------------------------------------------------------------------------------- /results/my_impl/002053_ED_heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_ED_heatmap.png -------------------------------------------------------------------------------- /results/my_impl/002053_MS_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_MS_boxes.png -------------------------------------------------------------------------------- /results/my_impl/002053_MS_heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_MS_heatmap.png -------------------------------------------------------------------------------- /results/my_impl/002053_SS_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_SS_boxes.png -------------------------------------------------------------------------------- /results/my_impl/002053_SS_heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_SS_heatmap.png -------------------------------------------------------------------------------- /results/my_impl/002053_comb_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_comb_boxes.png -------------------------------------------------------------------------------- /results/my_impl/002053_comb_heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/my_impl/002053_comb_heatmap.png -------------------------------------------------------------------------------- /results/original/002053_CC_boxes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_CC_boxes.jpg -------------------------------------------------------------------------------- /results/original/002053_CC_heatmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_CC_heatmap.jpg -------------------------------------------------------------------------------- /results/original/002053_ED_boxes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_ED_boxes.jpg -------------------------------------------------------------------------------- /results/original/002053_ED_heatmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_ED_heatmap.jpg -------------------------------------------------------------------------------- /results/original/002053_MS_boxes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_MS_boxes.jpg -------------------------------------------------------------------------------- /results/original/002053_MS_heatmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_MS_heatmap.jpg -------------------------------------------------------------------------------- /results/original/002053_SS_boxes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_SS_boxes.jpg -------------------------------------------------------------------------------- /results/original/002053_SS_heatmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_SS_heatmap.jpg -------------------------------------------------------------------------------- /results/original/002053_comb_boxes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_comb_boxes.jpg -------------------------------------------------------------------------------- /results/original/002053_comb_heatmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RookieHong/python-objectness/02af4d090502e1a7269b23673709cfea75da09c9/results/original/002053_comb_heatmap.jpg -------------------------------------------------------------------------------- /results/readme.md: -------------------------------------------------------------------------------- 1 | # Comparisons of results 2 | 3 | 4 | ## Combination of cues: 5 | 6 | Original: 7 | 8 | ![Original](../results/original/002053_comb_boxes.jpg) 9 | ![Original](../results/original/002053_comb_heatmap.jpg) 10 | 11 | Python: 12 | 13 | ![Original](../results/my_impl/002053_comb_boxes.png) 14 | ![Original](../results/my_impl/002053_comb_heatmap.png) 15 | 16 | 17 | ## MS 18 | 19 | Original: 20 | 21 | ![Original](../results/original/002053_MS_boxes.jpg) 22 | ![Original](../results/original/002053_MS_heatmap.jpg) 23 | 24 | Python: 25 | 26 | ![Original](../results/my_impl/002053_MS_boxes.png) 27 | ![Original](../results/my_impl/002053_MS_heatmap.png) 28 | 29 | ## CC 30 | 31 | Original: 32 | 33 | ![Original](../results/original/002053_CC_boxes.jpg) 34 | ![Original](../results/original/002053_CC_heatmap.jpg) 35 | 36 | Python: 37 | 38 | ![Original](../results/my_impl/002053_CC_boxes.png) 39 | ![Original](../results/my_impl/002053_CC_heatmap.png) 40 | 41 | ## ED 42 | 43 | Original: 44 | 45 | ![Original](../results/original/002053_ED_boxes.jpg) 46 | ![Original](../results/original/002053_ED_heatmap.jpg) 47 | 48 | Python: 49 | 50 | ![Original](../results/my_impl/002053_ED_boxes.png) 51 | ![Original](../results/my_impl/002053_ED_heatmap.png) 52 | 53 | ## SS 54 | 55 | Original: 56 | 57 | ![Original](../results/original/002053_SS_boxes.jpg) 58 | ![Original](../results/original/002053_SS_heatmap.jpg) 59 | 60 | Python: 61 | 62 | ![Original](../results/my_impl/002053_SS_boxes.png) 63 | ![Original](../results/my_impl/002053_SS_heatmap.png) 64 | 65 | ## Speed 66 | 67 | This speed test is run on Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz with `002053.jpg` as input image. 68 | 69 | Original matlab implementation: 70 | 71 | | Cues | Time(s)| 72 | | ---- | ---- | 73 | | MS, CC, SS | 2.16| 74 | | MS | 0.88 | 75 | | CC | 1.53 | 76 | | SS | 2.69 | 77 | 78 | Numpy implementation: 79 | 80 | | Cues | Time(s)| 81 | | ---- | ---- | 82 | | MS, CC, SS | 5.94| 83 | | MS | 2.10 | 84 | | CC | 4.12 | 85 | | SS | 8.52 | 86 | 87 | PyTorch implementation: 88 | 89 | | Cues | Time(s)| 90 | | ---- | ---- | 91 | | MS, CC, SS | | 92 | | MS | | 93 | | CC | | 94 | | SS | 4.40 | -------------------------------------------------------------------------------- /retrieveCoordinates.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import math 3 | 4 | 5 | def retrieve_coordinates(index, scale): 6 | img_area = scale * scale 7 | index1 = index % img_area 8 | index2 = np.floor(index / img_area) 9 | 10 | x1 = index1 % scale 11 | y1 = np.floor(index1 / scale) 12 | 13 | x2 = index2 % scale 14 | y2 = np.floor(index2 / scale) 15 | 16 | return np.vstack([x1, y1, x2, y2]).transpose((1, 0)) 17 | -------------------------------------------------------------------------------- /rgb2lab.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | def rgb2lab(img): 7 | # function lab_img = RGB2Lab(rgb_img) 8 | # RGB2Lab takes matrices corresponding to Red, Green, and Blue, and 9 | # % transforms them into CIELab. This transform is based on ITU-R 10 | # % Recommendation BT.709 using the D65 white point reference. 11 | # % The error in transforming RGB -> Lab -> RGB is approximately 12 | # % 10^-5. RGB values can be either between 0 and 1 or between 0 and 255. 13 | # % By Mark Ruzon from C code by Yossi Rubner, 23 September 1997. 14 | # % Updated for MATLAB 5 28 January 1998. 15 | 16 | img = img.astype(np.float) 17 | R = img[:, :, 0] 18 | G = img[:, :, 1] 19 | B = img[:, :, 2] 20 | 21 | if (np.max(R) > 1.0) | (np.max(G) > 1.0) | (np.max(B) > 1.0): 22 | R /= 255 23 | G /= 255 24 | B /= 255 25 | 26 | H, W = R.shape 27 | s = H * W 28 | 29 | # Set a threshold 30 | T = 0.008856 31 | 32 | RGB = np.stack([R.reshape(-1), G.reshape(-1), B.reshape(-1)]) # (3, H * W) 33 | 34 | # RGB to XYZ 35 | MAT = np.array([[0.412453, 0.357580, 0.180423], 36 | [0.212671, 0.715160, 0.072169], 37 | [0.019334, 0.119193, 0.950227]]) 38 | XYZ = np.dot(MAT, RGB) 39 | 40 | X = XYZ[0, :] / 0.950456 41 | Y = XYZ[1, :] 42 | Z = XYZ[2, :] / 1.088754 43 | 44 | XT = X > T 45 | YT = Y > T 46 | ZT = Z > T 47 | 48 | fX = XT * X ** (1/3) + (~XT) * (7.787 * X + 16/116) 49 | 50 | # Compute L 51 | Y3 = Y ** (1/3) 52 | fY = YT * Y3 + (~YT) * (7.787 * Y + 16/116) 53 | L = YT * (116 * Y3 - 16.0) + (~YT) * (903.3 * Y) 54 | 55 | fZ = ZT * Z ** (1/3) + (~ZT) * (7.787 * Z + 16/116) 56 | 57 | # Compute a and b 58 | a = 500 * (fX - fY) 59 | b = 200 * (fY - fZ) 60 | 61 | L = L.reshape(H, W) 62 | a = a.reshape(H, W) 63 | b = b.reshape(H, W) 64 | 65 | L = np.stack([L, a, b]).transpose((1, 2, 0)) 66 | return L 67 | 68 | 69 | if __name__ == "__main__": 70 | img = cv2.imread('test_imgs/Bolt2_0116.jpg')[:, :, ::-1] 71 | lab_img = rgb2lab(img) 72 | plt.imshow(lab_img) 73 | plt.show() 74 | -------------------------------------------------------------------------------- /runObjectness.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from computeScores import compute_scores 3 | from integrateBayes import integrate_bayes 4 | from nms_pascal import nms_pascal 5 | from mex_functions.scoreSampling import score_sampling 6 | 7 | 8 | def run_objectness(img, num_samples, params): 9 | 10 | if len(params.cues) == 1: # Single cue 11 | distribution_boxes = compute_scores(img, params.cues[0], params) 12 | if params.sampling == 'nms': # NMS sampling 13 | if len(distribution_boxes) > params.distribution_windows: 14 | index_samples = score_sampling(distribution_boxes[:, 4], params.distribution_windows, 1) 15 | distribution_boxes = distribution_boxes[index_samples] 16 | 17 | boxes = nms_pascal(distribution_boxes, 0.5, num_samples) 18 | 19 | elif params.sampling == 'multinomial': # Multinomial sampling 20 | # Sample from the distribution of the scores 21 | index_samples = score_sampling(distribution_boxes[:, -1], num_samples, 1) 22 | boxes = distribution_boxes[index_samples] 23 | 24 | else: 25 | raise Exception('Sampling procedure unknown') 26 | 27 | return boxes 28 | 29 | else: # Combination of cues 30 | assert 'MS' in params.cues, "ERROR: combinations have to include MS" 31 | assert len(np.unique(params.cues)) == len(params.cues), "ERROR: repeated cues in the combination" 32 | 33 | distribution_boxes = compute_scores(img, 'MS', params) 34 | # rearrange the cues such that 'MS' is the first cue 35 | if params.cues[0] != 'MS': 36 | for i, cue in enumerate(params.cues): 37 | if cue == 'MS': 38 | params.cues[i] = params.cues[0] 39 | break 40 | params.cues[0] = 'MS' 41 | 42 | score = np.zeros((len(distribution_boxes), len(params.cues))) 43 | score[:, 0] = distribution_boxes[:, -1] # MS score in first column 44 | windows = distribution_boxes[:, :4] # (N, 4) - (x1, y1, x2, y2) 45 | for idx in range(1, len(params.cues)): 46 | temp = compute_scores(img, params.cues[idx], params, windows) 47 | score[:, idx] = temp[:, -1] 48 | score_bayes = integrate_bayes(params.cues, score, params) 49 | 50 | if params.sampling == 'nms': 51 | distribution_boxes[:, 4] = score_bayes 52 | boxes = nms_pascal(distribution_boxes, 0.5, num_samples) 53 | 54 | elif params.sampling == 'multinomial': 55 | index_samples = score_sampling(score_bayes, num_samples, 1) 56 | boxes = np.hstack([windows[index_samples], score_bayes[index_samples]]) 57 | 58 | else: 59 | raise Exception('Sampling procedure unknown') 60 | 61 | return boxes 62 | -------------------------------------------------------------------------------- /segmentArea.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from easydict import EasyDict as edict 3 | 4 | 5 | def segment_area(N): 6 | segms = { 7 | 'coords': [], 8 | 'area': [] 9 | } 10 | 11 | tot_segms = np.max(N) + 1 # Segmentation id starts from 0 12 | for sid in range(tot_segms): 13 | cols, rows = np.where(N == sid) 14 | segms['coords'].append(np.vstack([cols, rows])) 15 | segms['area'].append(len(cols)) 16 | 17 | return segms 18 | -------------------------------------------------------------------------------- /windowComputeScores.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def window_compute_score(windows, scale, salmap_int, thrmap_int): 5 | score_scale = np.zeros(len(windows)) 6 | image_area = scale * scale 7 | 8 | windows = windows.astype(np.int) 9 | xmin = windows[:, 0] 10 | ymin = windows[:, 1] 11 | xmax = windows[:, 2] 12 | ymax = windows[:, 3] 13 | 14 | area = (xmax - xmin + 1) * (ymax - ymin + 1) 15 | aval = salmap_int[ymax, xmax] + salmap_int[ymin - 1, xmin - 1] - salmap_int[ymin - 1, xmax] - salmap_int[ymax, xmin - 1] 16 | athr = thrmap_int[ymax, xmax] + thrmap_int[ymin - 1, xmin - 1] - thrmap_int[ymin - 1, xmax] - thrmap_int[ymax, xmin - 1] 17 | # score_scale[image_area * ((ymax - 1) * scale + xmax - 1) + ((ymin - 1) * scale + xmin - 1)] = (aval * athr) / area 18 | score_scale = (aval * athr) / area 19 | 20 | return score_scale --------------------------------------------------------------------------------