Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python + Matlab Wrapper #1

Open
kornerc opened this issue Mar 26, 2015 · 8 comments
Open

Python + Matlab Wrapper #1

kornerc opened this issue Mar 26, 2015 · 8 comments

Comments

@kornerc
Copy link
Contributor

kornerc commented Mar 26, 2015

Hi Georg.

I'm planning to write a Python wrapper for this library.
It would be nice if you could provide a nice c-api for your library. It's also straightforward for a Matlab wrapper.

The c-api may look similar to this

// cwrapper.h

#ifndef WRAPPER_H
#define WRAPPER_H

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include <stdlib.h>

typedef void* cmt_Cmt;

cmt_Cmt cmt_new();
void cmt_del(cmt_Cmt cmt);
void cmt_initialize(cmt_Cmt cmt,
  unsigned char* im_gray, size_t rows, size_t cols,
  int rect_x, int rect_y, int rect_w, int rect_h);
// ...

#ifdef __cplusplus
}
#endif // __cplusplus

#endif /* WRAPPER_H */
// cwrapper.cpp
#include "cwrapper.h"

#include <opencv2/core/core.hpp>

#include "CMT.h"

using cmt::CMT;
using namespace cv;

cmt_Cmt cmt_new() {
    CMT* cmt = new CMT();
    return cmt;
}

void cmt_del(cmt_Cmt cmt) {
    CMT* cmt_cpp = static_cast<CMT*>(cmt);
    delete cmt_cpp;
}

void cmt_initialize(cmt_Cmt cmt,
  unsigned char* im_gray, size_t rows, size_t cols,
  int rect_x, int rect_y, int rect_w, int rect_h) {
    CMT* cmt_cpp = static_cast<CMT*>(cmt);

    Mat image = Mat(rows, cols, CV_8UC1, im_gray);
    Rect rect(rect_x, rect_y, rect_w, rect_h);

    cmt_cpp.initialize(image, rect);

    // ...
}

// ...

BR Clemens

@kornerc
Copy link
Contributor Author

kornerc commented Mar 26, 2015

Here is a small example how I'm planning to program the bridge between Numpy (Python side) and OpenCV (C++ side)

# CMakeLists.txt
project(wrapper)

cmake_minimum_required(VERSION 2.6)

option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." ON)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

find_package(OpenCV REQUIRED)
link_directories(${OpenCV_LIB_DIR})

add_library(wrapper wrapper.cpp)
target_link_libraries(wrapper ${OpenCV_LIBS})
// wrapper.h
#ifndef WRAPPER_H
#define WRAPPER_H

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include <stdlib.h>

void array_to_mat(unsigned char* data, size_t rows, size_t cols);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // WRAPPER_H
// wrapper.cpp
#include "wrapper.h"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;

void array_to_mat(unsigned char* data, size_t rows, size_t cols) {
    Mat image = Mat(rows, cols, CV_8UC1, data);
    namedWindow("Image", WINDOW_AUTOSIZE);
    imshow("Image", image);
    waitKey(0);
}
# pywrapper.py

import numpy as np
import ctypes as ct
import cv2

_libwrapper = np.ctypeslib.load_library('libwrapper', '.')

_libwrapper.array_to_mat.argtypes = [np.ctypeslib.ndpointer(dtype=np.uint8),
        ct.c_size_t,
        ct.c_size_t]
_libwrapper.array_to_mat.restype = None

def array_to_mat(image):
    image = image.astype(np.uint8)
    shape = image.shape
    _libwrapper.array_to_mat(image, shape[0], shape[1])

if __name__ == '__main__':
    image = cv2.imread('test.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)
    array_to_mat(image)

@gnebehay
Copy link
Owner

Initial version is here: 7099a01

@soulslicer
Copy link

good day, may I know the progress of your Python wrapper?

@kornerc
Copy link
Contributor Author

kornerc commented Sep 7, 2015

There is a branch called wrapper with the python code. Just compile the library as usual and put pycmt.py to the binaries, that's it. The basic functions are wrapped, but it's not possible to change any parameters yet. My recommendation is to use the original python program CMT for now.

@soulslicer
Copy link

Yes, but the original python code doesn't seem to be as performant as CppCMT. That is, the tracking is not as robust on by datasets, with alot of outlier keypoints that seem to skew the ROI computed. I think some algorithm changes were probably implemented on CppMT

Also, I will try the Wrapper branch. Are there any changes in CppMT? I notice this branch is 6 months old. Can I grab pycmt, compile master branch then place the wrapper in the new one?

@soulslicer
Copy link

Can I request for some direction on how I may modify your CMakeLists.txt to build a single shared library called libcmt?

@soulslicer
Copy link

I used the following line to generate the static library file (in osx it creates libcmt.dylib)
add_library(cmt STATIC CMT.cpp common.cpp gui.cpp Consensus.cpp Fusion.cpp Matcher.cpp Tracker.cpp fastcluster/fastcluster.cpp)

But when I use the pycmt.py, I get this error:
Traceback (most recent call last):
File "pycmt.py", line 8, in
_libccmt.newCMT.argtypes = None
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/init.py", line 378, in getattr
func = self.getitem(name)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/init.py", line 383, in getitem
func = self._FuncPtr((name_or_ordinal, self))

@kornerc
Copy link
Contributor Author

kornerc commented Sep 18, 2015

I'm sorry, but it's not possible to use the python-wrapper with the static libcmt library. It has to be a shared one.
The wrapper uses ctypes for wrapping:
ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.

tesYolan added a commit to tesYolan/CppMT that referenced this issue Jul 14, 2016
Update to latest configuration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants