В настоящее время я пишу код, который использует boost.python
.Я хочу преобразовать std::vector<unsigned char>
в похожий на байты объект Python (мне просто нужно предоставить данные Python).Конвертер, который я написал, выглядит следующим образом
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <stdio.h>
#include <iostream>
#include <vector>
struct vector_to_bytes{
static PyObject* convert(std::vector<unsigned char> const &vec){
std::printf("Converter Called\n");
const unsigned char * p=&vec[0];
for (char c:vec){
std::printf("%x",c);
}
std::printf("\n");
return PyMemoryView_FromMemory((char *)p,vec.size(),PyBUF_READ);
}
};
Однако, когда я пытаюсь распечатать байты из Python с помощью memoryview.tobytes().hex()
и сравнить его с выводом из кода C ++, некоторая информация теряется.
Таким образом, вывод из C ++ выглядит следующим образом (усеченные данные)
ffffffffffffffd8ffffffffffffffe00104a4649460110010100ffffffffffffffdb043064565466567768a10aa99a14efc1017141818171416161a1d251f1a1b231c
И из Python (усеченные данные)
ffd8ffe000104a46494600010100000100010000ffdb00430006040506050406060506070706080a100a0a09090a140e0f0c1017141818171416161a1d251f1a1b231c
Итак, все ff
s из C ++были заменены одним ff
, но оба результата так или иначе начинают выстраиваться в 10171418
, что для меня не имеет никакого смысла.
Я чувствую, что что-то пошло не так с приведением типов от const unsigned char *
до char *
, но я не знаю, как это исправить.
Система: MacOS 10.13.6
Python 3.7.0
Повышение 1.69.0
C ++ 14
РЕДАКТИРОВАТЬ
В приведенном выше разделе показана только та часть, которая, на мой взгляд, была актуальной.Полный код здесь:
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/overloads.hpp>
#include <string>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <vector>
class VideoStream {
protected:
cv::Mat frame;
cv::Size resolution;
int quality;
int id;
void captureFrame() {
this->caps >> frame;
};
virtual void processFrame() {
cv::resize(frame, frame, resolution);
}
public:
cv::VideoCapture caps;
VideoStream(int i, int rx, int ry, int quality) {
this->resolution = cv::Size(rx, ry);
#if defined(__linux__)
this->caps = cv::VideoCapture(i+1,cv::CAP_V4L);
#else
this->caps = cv::VideoCapture(i);
#endif
this->id = i;
this->quality=quality;
if (!caps.isOpened())
std::printf("Video capture for cam %d failed", i);
};
~VideoStream() {
caps.release();
}
cv::Mat getFrame() {
captureFrame();
processFrame();
return this->frame;
}
std::vector<unsigned char> getCompressedFrame() {
std::vector<uchar> buf;
captureFrame();
processFrame();
cv::imencode(".jpg", frame, buf, std::vector<int>{
cv::IMWRITE_JPEG_QUALITY, quality,
cv::IMWRITE_JPEG_OPTIMIZE, 1,
});
return buf;
}
void setResolution(int width) {
this->resolution = cv::Size(width, width/1.5);
}
int getHeight(){
return resolution.height;
}
int getWidth(){
return resolution.width;
}
void setQuality(int q){
this->quality=q;
}
int getQuality(){
return quality;
}
int getId(){
return id;
}
};
struct vector_to_bytes{
static PyObject* convert(std::vector<unsigned char> const &vec){
std::printf("Converter Called\n");
const unsigned char * p=&vec[0];
for (char c:vec){
std::printf("%x",c);
}
std::printf("\n");
return PyMemoryView_FromMemory((char *)p,vec.size(),PyBUF_READ);
}
};
BOOST_PYTHON_MODULE(video_frame){
using namespace boost::python;
to_python_converter<std::vector<unsigned char>,vector_to_bytes>();
class_<VideoStream>("VideoStream",init<int,int,int,int>())
.def("getCompressedFrame",&VideoStream::getCompressedFrame)
.def("setQuality",&VideoStream::setQuality,args("quality"))
.def("setResolution",&VideoStream::setResolution,args("width"))
.def("getWidth",&VideoStream::getWidth)
.def("getHeight",&VideoStream::getHeight)
.def("getQuality",&VideoStream::getQuality)
.def("getId",&VideoStream::getId)
;
}