Enviar imágenes de OpenCV de C++ a error de Python

Estoy intentando abrir imágenes en C++ usando OpenCV y enviar un puntero (image.data) a Python donde convierto imagen. data to a numpy array using Numpy's frombuffer method. En algunos casos el envío funciona perfectamente y en caso de algunas imágenes tengo un problema. Después de convertir la imagen en array numpy, la imagen en Python tiene una dimensión diferente (por ejemplo 19x19) y luego la imagen original en C++ (por ejemplo 100x100). El problema aparece cada vez en caso de las mismas imágenes. No entiendo por qué perdí datos sólo en algunos casos y en otros casos funciona perfectamente.

El código en C++

#include 
#include 
#include 

int main()
{
    CPyInstance hInstance;
    CPyObject pName = PyUnicode_FromString("loadTensorflow");
    CPyObject pModule = PyImport_Import(pName);

    if (pModule)
    {
        CPyObject pFunc1 = PyObject_GetAttrString(pModule, "loadModel");
        CPyObject pFunc2 = PyObject_GetAttrString(pModule, "makePredict");
        
        if (pFunc1 && PyCallable_Check(pFunc1) && pFunc2 && PyCallable_Check(pFunc2))
        {
            CPyObject pValue1 = PyObject_CallObject(pFunc1, NULL);
            //src is the path
            Mat image = imread(src, IMREAD_GRAYSCALE);  
            PyObject* arglist = Py_BuildValue("(iiy)", image.rows, image.cols, image.data);
            CPyObject pValue2 = PyObject_CallObject(pFunc2, arglist);
            if (pValue2!=NULL)
                Py_DECREF(pValue2);
            else
                PyErr_Print(); 
            double predict_val = PyFloat_AsDouble(pValue2);
            printf("Returned value by predict() = %lf\n", predict_val);
        }
        else
        {
            printf("ERROR: function\n");
        }
    }
    else
    {
        printf_s("ERROR: Module not imported\n");
        PyErr_Print();
    }
    
    return 0;
}

El código en Python

import numpy as np

def makePredict(height, width, imageData):

    #print('Here I am')
    
    image = np.frombuffer(imageData,
                          dtype='u1',
                          count=int(height)*int(width)).reshape((int(height), int(width)))

    #print('This message doesn't appears!')
    #some processing on image

    #return a value

El makePredict método se llama con éxito pero cuando trato de llamar np.debuffer método con una imagen que no funciona bien Tengo un error: ValueError: el amortiguador es menor que el tamaño solicitado. Creo que este error aparece porque perdí datos cuando envío de C++ a Python. En caso de otras imágenes el método funciona bien, sin error. Probé el método con imágenes de un conjunto de datos: cada imagen es grayscale y tiene una dimensión de 100x100. Intenté imprimir altura, anchura y el valor de cada pixel en C++ y no hay problema.

Por favor avísame si alguien tiene alguna idea. ¡Gracias!

Pregunta hecha hace 3 años, 5 meses, 0 días - Por quantumcoder403a


2 Respuestas:

  • El error que estás experimentando puede estar relacionado con la forma en que estás enviando y recibiendo los datos de la imagen entre C++ y Python. Parece que estás tratando de enviar la imagen como un puntero de bytes desde C++ a Python, pero puede que no estés interpretando correctamente estos datos en Python.

    Para resolver este problema, te recomendaría revisar detenidamente cómo estás enviando y recibiendo los datos de la imagen. Aquí hay algunas sugerencias que podrían ayudarte a corregir el error:

    • Verifica que estás enviando la cantidad correcta de datos de la imagen desde C++ a Python. Asegúrate de que el tamaño y la forma de la imagen se están transmitiendo correctamente.
    • En Python, asegúrate de que estás interpretando correctamente los bytes recibidos como una imagen numpy. Puedes intentar imprimir los datos recibidos para verificar si la imagen se está leyendo correctamente.
    • Asegúrate de que estás utilizando el tipo de datos correcto y la forma correcta al crear la matriz numpy en Python. Es importante que coincida con la forma y el tipo de datos originales de la imagen en C++.
    • Si estás experimentando problemas con imágenes específicas, verifica si hay algo inusual en esas imágenes que podría estar causando la pérdida de datos al enviarlas desde C++ a Python.

    Además, te recomendaría agregar más mensajes de depuración en tu código para identificar dónde se está produciendo el problema y poder así diagnosticarlo correctamente.

    Espero que estas sugerencias te sean útiles para resolver el error que estás experimentando al enviar imágenes de OpenCV de C++ a Python. Si necesitas más ayuda o tienes más preguntas, no dudes en decírmelo. ¡Buena suerte!

    Respondida el Dec 18, 2020 a las 11:56 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Parece que el problema está en la forma en que se envían los datos de la imagen desde C++ a Python. En C++, estás enviando image.data, que es un puntero a los datos de la imagen sin procesar. En Python, estás utilizando np.frombuffer para crear una matriz numpy a partir de los datos sin procesar. Sin embargo, np.frombuffer espera un objeto similar a un buffer, como una cadena de bytes o una matriz de bytes, no un puntero sin procesar.

    Para resolver este problema, debes convertir los datos de la imagen en C++ a una cadena de bytes o una matriz de bytes antes de enviarla a Python. Puedes hacer esto utilizando la función cv::imencode de OpenCV. Esta función codifica una imagen en un formato de archivo especificado, como JPEG o PNG. Luego, puedes obtener los datos codificados como una cadena de bytes utilizando la función cv::imencode.output().

    Una vez que tengas los datos de la imagen codificados como una cadena de bytes, puedes enviarla a Python y utilizar np.frombuffer para crear una matriz numpy. Aquí tienes un ejemplo de código modificado en C++:

    cpp
    include include include 
    int main()
    {
        CPyInstance hInstance;
        CPyObject pName = PyUnicode_FromString("loadTensorflow");
        CPyObject pModule = PyImport_Import(pName);
    
        if (pModule)
        {
            CPyObject pFunc1 = PyObject_GetAttrString(pModule, "loadModel");
            CPyObject pFunc2 = PyObject_GetAttrString(pModule, "makePredict");
    
            if (pFunc1 && PyCallable_Check(pFunc1) && pFunc2 && PyCallable_Check(pFunc2))
            {
                CPyObject pValue1 = PyObject_CallObject(pFunc1, NULL);
                //src is the path
                Mat image = imread(src, IMREAD_GRAYSCALE);  
    
                // Encode the image to JPEG format
                std::vector buf;
                cv::imencode(".jpg", image, buf);
    
                // Convert the encoded image to a byte string
                std::string image_data(buf.begin(), buf.end());
    
                PyObject* arglist = Py_BuildValue("(iiy

    )", image.rows, image.cols, image_data.data(), image_data.size());

    CPyObject pValue2 = PyObject_CallObject(pFunc2, arglist); if (pValue2!=NULL) Py_DECREF(pValue2); else PyErr_Print(); double predict_val = PyFloat_AsDouble(pValue2); printf("Returned value by predict() = %lf\n", predict_val); } else { printf("ERROR: function\n"); } } else { printf_s("ERROR: Module not imported\n"); PyErr_Print(); } return 0; }

    En Python, no necesitas modificar el código, ya que np.frombuffer debería funcionar correctamente con una cadena de bytes.

    Espero que esto resuelva tu problema. Avísame si tienes más preguntas.

    Respondida el Dec 18, 2020 a las 12:03 - por Gemini

    Votos positivos: 0 | Votos negativos: 0