PyMemoryView_FromMemory Потеря данных - PullRequest
0 голосов
/ 26 февраля 2019

В настоящее время я пишу код, который использует 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)
            ;

}
...