2012-10-02 22 views
6

necesito leer una imagen con OpenCV, obtener su tamaño y enviarlo a un servidor por lo que procesa la imagen y darle de nuevo a mí el extraída caracteristicas.tienda un cv :: Mat en una matriz de bytes para la transferencia de datos a un servidor

He estado pensando en usar un vector<byte>, pero no entiendo cómo copiar los datos a un cv :: Mat. Quiero que sea rápido, así que estoy tratando de acceder a los datos con un puntero, pero tengo una excepción de tiempo de ejecución. Tengo algo como esto.

Mat image = imread((path + "name.jpg"), 0); 
vector<byte> v_char; 
for(int i = 0; i < image.rows; i++) 
    { 
     for(int j = 0; j < image.cols; j++) 
     { 
      v_char.push_back(*(uchar*)(image.data+ i + j));    

     }   
    } 
  • ¿Cuál es el mejor enfoque para esta tarea?

Respuesta

7

acceso directo es una buena idea, ya que es el más rápido de OpenCV, pero se echa en falta el paso y que es probablemente la razón por la cual se rompe el programa. La siguiente línea es incorrecto:

v_char.push_back(*(uchar*)(image.data+ i + j)); 

Usted no tiene que incrementar i, hay que incrementar i + image.step. Será de esta manera:

Mat image = imread((path + "name.jpg"), 0); 
vector<byte> v_char; 
for(int i = 0; i < image.rows; i++) 
    { 
     for(int j = 0; j < image.cols; j++) 
     { 
      v_char.push_back(*(uchar*)(image.data+ i*image.step + j));    

     }   
    } 
1

No entiendo perfectamente por qué es necesario utilizar un vector, pero si es realmente necesario recomiendo que hagas un establecimiento de memoria simple:

vector<byte> v_char(image.width * image.height); //Allocating the vector with the same size of the matrix 
memcpy(v_char.data(), image.data, v_char.size() * sizeof(byte)); 
5

La mejora en La respuesta de Jav_Rock es cómo lo haría.

Mat image = ...; 
vector<byte> v_char(image.rows * image.cols); 

for (int i = 0; i < image.rows; i++) 
    memcpy(&v_char[i * image.cols], image.data + i * image.step, image.cols); 

EDIT: inicialización por el constructor asignará espacio suficiente para evitar la reasignación adicional, pero también fijará todos los elementos en el vector al valor por defecto (0). El siguiente código evita esta inicialización adicional.

Mat image = ...; 
vector<byte> v_char; 
v_char.reserve(image.rows * image.cols); 

for (int i = 0; i < image.rows; i++) 
{ 
    int segment_start = image.data + i * image.step; 
    v_char.insert(v_char.end(), segment_start, segment_start + image.cols); 
} 
+1

Claro, me gusta esta manera mejor –

+0

¿Por qué necesita el para hacer el establecimiento de memoria? ¿Por qué no simplemente copiar toda la memoria? –

+3

Porque en el caso general Mat :: step es diferente de Mat :: cols. Esto le permite, por ejemplo, recortar la matriz sin reorganizar realmente los bytes. Puede hacer una submatriz que haga referencia a una ventana a otra matriz, sin copiar datos. Y cuando cambias una celda en la submatriz, realmente cambias una celda en la matriz original, a la que la submatriz solo hace referencia. – Dialecticus

4

Has recibido excelentes respuestas hasta el momento, pero este no es tu problema principal. Lo que probablemente quiere hacer antes de enviar una imagen a un servidor es compresa ella.

Por lo tanto, eche un vistazo a cv::imencode() sobre cómo comprimirlo, y cv::imdecode() para transformarlo a una matriz OpenCV en el servidor. simplemente presione el imencode ouptut a un socket y listo.

Cuestiones relacionadas