使用cv::Mat的Boost Python包装器和OpenCv参数错误 我有一个C++类,我用Boost Python包了。< /P>
其中一个类方法包含两个使用cv::Mat的Boost Python包装器和OpenCv参数错误 我有一个C++类,我用Boost Python包了。< /P>,c++,python,boost,opencv,boost-python,C++,Python,Boost,Opencv,Boost Python,其中一个类方法包含两个cv::Mats,如下所示: MyClass::do_something(cv::Mat input, cv::Mat output) python提供的功能包括上述方法、构造函数和一些打印方法 初始化和打印方法(用于调试)在C++和Python包装器中都很好: obj = MyClass(arg1, arg2, arg3) obj.print_things() 这些调用成功完成 我遇到了do_something()调用的问题(在Python绑定中,它在C++中成功完成
cv::Mat
s,如下所示:
MyClass::do_something(cv::Mat input, cv::Mat output)
python提供的功能包括上述方法、构造函数和一些打印方法
初始化和打印方法(用于调试)在C++和Python包装器中都很好:
obj = MyClass(arg1, arg2, arg3)
obj.print_things()
这些调用成功完成
我遇到了do_something()
调用的问题(在Python绑定中,它在C++中成功完成):
我在执行上述python代码时遇到的错误是:
Boost.Python.ArgumentError: Python argument types in
MyClass.do_something(MyClass, cv2.cv.cvmat, cv2.cv.cvmat)
did not match C++ signature:
do_something(MyClass {lvalue}, cv::Mat, cv::Mat)
cv2.cv.Mat和cv::Mat之间是否存在差异?我有OpenCV 2.3.1和2.4,它们都带有Boost Python绑定
如果相关,下面是我的Boost包装器的外观:
#include <boost/python.hpp>
#include "MyClass.h"
#include <cv.h>
using namespace boost::python;
BOOST_PYTHON_MODULE(libmyclass) {
class_<MyClass>("MyClass", init<std::string, std::string, std::string>())
.def("print_things", &MyClass::print_things)
.def("do_something", &MyClass::do_something)
;
}
#包括
#包括“MyClass.h”
#包括
使用名称空间boost::python;
BOOST_PYTHON_模块(libmyclass){
类(“MyClass”,init())
.def(“打印内容”&MyClass::打印内容)
.def(“do_something”,&MyClass::do_something)
;
}
Boost python不会自动将cv2.cv.Mat(python中)转换为cv::Mat(C++)
你需要声明你的C++方法来获取一个Booost::对象*,并在C++中有额外的代码将对象转换成CV::Mat。 下面是我为包装STASM活动形状模型库所做的一个示例
#ifndef ASMSearcher_HPP
#define ASMSearcher_HPP
#include <string>
#include <boost/python.hpp>
#include <opencv2/core/core.hpp>
class ASMSearcher;
/*
* Wrapper around STASM ASMSearcher class so that we don't mix boost python code into the STASM library.
*/
struct memtrack_t {
PyObject_HEAD
void *ptr;
Py_ssize_t size;
};
struct cvmat_t
{
PyObject_HEAD
CvMat *a;
PyObject *data;
size_t offset;
};
struct iplimage_t {
PyObject_HEAD
IplImage *a;
PyObject *data;
size_t offset;
};
namespace bp = boost::python;
class Stasm
{
public:
Stasm();
Stasm(const std::string &conf_file0, const std::string &conf_file1);
~Stasm();
bp::list detect(bp::object image, const std::string &conf_file0="",
const std::string &conf_file1="");
private:
ASMSearcher *asmLandmarksSearcher;
cv::Mat convertObj2Mat(bp::object image);
cv::Mat convert_from_cviplimage(PyObject *o,const char *name);
cv::Mat convert_from_cvmat(PyObject *o, const char* name);
};
#endif
#include "stasm.hpp"
#include "stasm_ocv.hpp"
#include <opencv2/highgui/highgui.hpp>
Stasm::Stasm()
{
asmLandmarksSearcher = NULL;
}
Stasm::~Stasm()
{
if (asmLandmarksSearcher != NULL)
delete asmLandmarksSearcher;
}
Stasm::Stasm(const std::string &conf_file0, const std::string &conf_file1)
{
asmLandmarksSearcher = new ASMSearcher(conf_file0, conf_file1);
}
/*Detect asm facial landmarks in image*/
bp::list Stasm::detect(bp::object image,
const std::string &conf_file0,
const std::string &conf_file1)
{
const char *file0 = conf_file0 == "" ? NULL : conf_file0.c_str();
const char *file1 = conf_file1 == "" ? NULL : conf_file1.c_str();
// Convert pyobject to IplImage/Mat etc.
cv::Mat img = convertObj2Mat(image);
bool isColor = img.channels() == 3 ? true : false;
int nlandmarks;
int landmarks[500]; // space for x,y coords of up to 250 landmarks
asmLandmarksSearcher->search(&nlandmarks, landmarks,
"image_name", (const char*)img.data, img.cols, img.rows,
isColor /* is_color */, file0 /* conf_file0 */, file1 /* conf_file1 */);
//isColor /* is_color */, NULL /* conf_file0 */, NULL /* conf_file1 */);
// Convert landmarks to python list object
bp::list pyLandmarks;
for (int i = 0; i < 2*nlandmarks; i++)
pyLandmarks.append(landmarks[i]);
return pyLandmarks;
}
cv::Mat Stasm::convert_from_cvmat(PyObject *o, const char* name)
{
cv::Mat dest;
cvmat_t *m = (cvmat_t*)o;
void *buffer;
Py_ssize_t buffer_len;
m->a->refcount = NULL;
if (m->data && PyString_Check(m->data))
{
assert(cvGetErrStatus() == 0);
char *ptr = PyString_AsString(m->data) + m->offset;
cvSetData(m->a, ptr, m->a->step);
assert(cvGetErrStatus() == 0);
dest = m->a;
}
else if (m->data && PyObject_AsWriteBuffer(m->data, &buffer, &buffer_len) == 0)
{
cvSetData(m->a, (void*)((char*)buffer + m->offset), m->a->step);
assert(cvGetErrStatus() == 0);
dest = m->a;
}
else
{
printf("CvMat argument '%s' has no data", name);
//failmsg("CvMat argument '%s' has no data", name);
}
return dest;
}
cv::Mat Stasm::convert_from_cviplimage(PyObject *o,const char *name)
{
cv::Mat dest;
iplimage_t *ipl = (iplimage_t*)o;
void *buffer;
Py_ssize_t buffer_len;
if (PyString_Check(ipl->data)) {
cvSetData(ipl->a, PyString_AsString(ipl->data) + ipl->offset, ipl->a->widthStep);
assert(cvGetErrStatus() == 0);
dest = ipl->a;
} else if (ipl->data && PyObject_AsWriteBuffer(ipl->data, &buffer, &buffer_len) == 0) {
cvSetData(ipl->a, (void*)((char*)buffer + ipl->offset), ipl->a->widthStep);
assert(cvGetErrStatus() == 0);
dest = ipl->a;
} else {
printf("IplImage argument '%s' has no data", name);
}
return dest;
}
cv::Mat Stasm::convertObj2Mat(bp::object image)
{
if(strcmp(image.ptr()->ob_type->tp_name,"cv2.cv.iplimage") == 0)
{
return convert_from_cviplimage(image.ptr(),image.ptr()->ob_type->tp_name);
}
else
return convert_from_cvmat(image.ptr(), image.ptr()->ob_type->tp_name);
}
对不起,我没有时间清理代码。请注意,您需要调用cv2.cv.fromarray(numpy\u数组)使其工作。我仍在试图找出如何直接将numpy数组传递给pythonboost。如果你已经弄明白了,请告诉我:)
顺便说一句,我应该补充一点,转换boost对象和opencv的IplImage和Mat的代码取自opencv的源代码。您好,我遵循了您的说明,得到的错误是mydll.Track(cv2.cv.fromary(frame))argument错误:argument 1::不知道如何转换参数1您可以给出一些提示吗。我试了很多,但我已经找不到了。你能帮忙吗。在C++中,我需要额外添加什么吗?我写了一个简单的C++代码,这里是@ USER 27 7765,看一看我的另一篇文章以获得更完整的说明:希望这有帮助。
#ifndef ASMSearcher_HPP
#define ASMSearcher_HPP
#include <string>
#include <boost/python.hpp>
#include <opencv2/core/core.hpp>
class ASMSearcher;
/*
* Wrapper around STASM ASMSearcher class so that we don't mix boost python code into the STASM library.
*/
struct memtrack_t {
PyObject_HEAD
void *ptr;
Py_ssize_t size;
};
struct cvmat_t
{
PyObject_HEAD
CvMat *a;
PyObject *data;
size_t offset;
};
struct iplimage_t {
PyObject_HEAD
IplImage *a;
PyObject *data;
size_t offset;
};
namespace bp = boost::python;
class Stasm
{
public:
Stasm();
Stasm(const std::string &conf_file0, const std::string &conf_file1);
~Stasm();
bp::list detect(bp::object image, const std::string &conf_file0="",
const std::string &conf_file1="");
private:
ASMSearcher *asmLandmarksSearcher;
cv::Mat convertObj2Mat(bp::object image);
cv::Mat convert_from_cviplimage(PyObject *o,const char *name);
cv::Mat convert_from_cvmat(PyObject *o, const char* name);
};
#endif
#include "stasm.hpp"
#include "stasm_ocv.hpp"
#include <opencv2/highgui/highgui.hpp>
Stasm::Stasm()
{
asmLandmarksSearcher = NULL;
}
Stasm::~Stasm()
{
if (asmLandmarksSearcher != NULL)
delete asmLandmarksSearcher;
}
Stasm::Stasm(const std::string &conf_file0, const std::string &conf_file1)
{
asmLandmarksSearcher = new ASMSearcher(conf_file0, conf_file1);
}
/*Detect asm facial landmarks in image*/
bp::list Stasm::detect(bp::object image,
const std::string &conf_file0,
const std::string &conf_file1)
{
const char *file0 = conf_file0 == "" ? NULL : conf_file0.c_str();
const char *file1 = conf_file1 == "" ? NULL : conf_file1.c_str();
// Convert pyobject to IplImage/Mat etc.
cv::Mat img = convertObj2Mat(image);
bool isColor = img.channels() == 3 ? true : false;
int nlandmarks;
int landmarks[500]; // space for x,y coords of up to 250 landmarks
asmLandmarksSearcher->search(&nlandmarks, landmarks,
"image_name", (const char*)img.data, img.cols, img.rows,
isColor /* is_color */, file0 /* conf_file0 */, file1 /* conf_file1 */);
//isColor /* is_color */, NULL /* conf_file0 */, NULL /* conf_file1 */);
// Convert landmarks to python list object
bp::list pyLandmarks;
for (int i = 0; i < 2*nlandmarks; i++)
pyLandmarks.append(landmarks[i]);
return pyLandmarks;
}
cv::Mat Stasm::convert_from_cvmat(PyObject *o, const char* name)
{
cv::Mat dest;
cvmat_t *m = (cvmat_t*)o;
void *buffer;
Py_ssize_t buffer_len;
m->a->refcount = NULL;
if (m->data && PyString_Check(m->data))
{
assert(cvGetErrStatus() == 0);
char *ptr = PyString_AsString(m->data) + m->offset;
cvSetData(m->a, ptr, m->a->step);
assert(cvGetErrStatus() == 0);
dest = m->a;
}
else if (m->data && PyObject_AsWriteBuffer(m->data, &buffer, &buffer_len) == 0)
{
cvSetData(m->a, (void*)((char*)buffer + m->offset), m->a->step);
assert(cvGetErrStatus() == 0);
dest = m->a;
}
else
{
printf("CvMat argument '%s' has no data", name);
//failmsg("CvMat argument '%s' has no data", name);
}
return dest;
}
cv::Mat Stasm::convert_from_cviplimage(PyObject *o,const char *name)
{
cv::Mat dest;
iplimage_t *ipl = (iplimage_t*)o;
void *buffer;
Py_ssize_t buffer_len;
if (PyString_Check(ipl->data)) {
cvSetData(ipl->a, PyString_AsString(ipl->data) + ipl->offset, ipl->a->widthStep);
assert(cvGetErrStatus() == 0);
dest = ipl->a;
} else if (ipl->data && PyObject_AsWriteBuffer(ipl->data, &buffer, &buffer_len) == 0) {
cvSetData(ipl->a, (void*)((char*)buffer + ipl->offset), ipl->a->widthStep);
assert(cvGetErrStatus() == 0);
dest = ipl->a;
} else {
printf("IplImage argument '%s' has no data", name);
}
return dest;
}
cv::Mat Stasm::convertObj2Mat(bp::object image)
{
if(strcmp(image.ptr()->ob_type->tp_name,"cv2.cv.iplimage") == 0)
{
return convert_from_cviplimage(image.ptr(),image.ptr()->ob_type->tp_name);
}
else
return convert_from_cvmat(image.ptr(), image.ptr()->ob_type->tp_name);
}
#!/usr/bin/env python
import cv2
import pystasm
import numpy as np
import sys
DEFAULT_TEST_IMAGE = "428.jpg"
def getFacePointsMapping():
mapping = {}
fhd = open('mapping2.txt')
line = fhd.readline()
a = line.split()
for i, n in enumerate(a):
mapping[int(n)] = i
return mapping
def drawFaceKeypoints(img, landmarks):
mapping = getFacePointsMapping()
numpyLandmarks = np.asarray(landmarks)
numLandmarks = len(landmarks) / 2
numpyLandmarks = numpyLandmarks.reshape(numLandmarks, -1)
for i in range(0, len(landmarks) - 1, 2):
pt = (landmarks[i], landmarks[i+1])
#cv2.polylines(img, [numpyLandmarks], False, (0, 255, 0))
number = mapping[i/2]
cv2.circle(img, pt, 3, (255, 0, 0), cv2.cv.CV_FILLED)
cv2.putText(img, str(number), pt, cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 0, 255))
return img
def getFacePointsMapping():
mapping = []
fhd = open('mapping2.txt')
line = fhd.readline()
a = line.split()
for n in a:
mapping.append(n)
return mapping
def main():
asmsearcher = pystasm.Stasm('mu-68-1d.conf', 'mu-76-2d.conf')
if len(sys.argv) == 2:
imagename = sys.argv[1]
else:
imagename = DEFAULT_TEST_IMAGE
# Detect facial keypoints in image
img = cv2.imread(imagename)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
landmarks = asmsearcher.detect(cv2.cv.fromarray(img))
img = drawFaceKeypoints(img, landmarks)
#numpyLandmarks = np.asarray(landmarks)
#numLandmarks = len(landmarks) / 2
#numpyLandmarks = numpyLandmarks.reshape(numLandmarks, -1)
#for i in range(0, len(landmarks) - 1, 2):
# pt = (landmarks[i], landmarks[i+1])
# #cv2.polylines(img, [numpyLandmarks], False, (0, 255, 0))
# number = mapping[i/2]
# cv2.circle(img, pt, 3, (255, 0, 0), cv2.cv.CV_FILLED)
# cv2.putText(img, str(number), pt, cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 0, 255))
cv2.imshow("test", img)
cv2.waitKey()
if __name__ == '__main__':
main()