2011-12-26 26 views
6

Actualmente estoy tratando de migrar un poco de código heredado de iPhone a Android. Este código usa la biblioteca OpenCV para hacer un poco de procesamiento de imágenes. En general va bien, pero estoy atascado en una línea de código no tengo ni idea de cómo se puede convertir en código Java:Conversión de código OpenCV de C++ a Java

Scalar dMean; 
Scalar scalar; 
std::vector<Mat> channels; 
split(mat, channels); 
for(int i=0; i<3; ++i) { 
    channels[i] += dMean[i]; 
} 

La pregunta es - lo que debe ser utilizado en lugar del operador + = en Java código para agregar un objeto escalar a una estera?

+0

¿Puede mostrarnos qué tiene, dónde exactamente (en Java) está atascado? – MByD

+0

+ = es un operador aceptable para primitivas, pero no para objetos. Probablemente tendrá que escribir un método que haga el agregado para el objeto. – Kylar

+0

El código de C++ agrega Scalar a un objeto Mat. En Java, he creado objetos Scalar y Mat, pero no puedo encontrar un método para agregar Scalar a Mat.La clase Core en JavaCV contiene un método estático add (Mat, Mat, Mat), pero solo le permite agregar dos Mat's – Anton

Respuesta

5

Nota: tomar esta respuesta con un grano de sal, no he probado plenamente esta;)

OPCION1:

La forma más directa, y si sólo va a procese unos pocos píxeles, utilizando su_mat.put (fila, col, datos) y your_mat.get (row, col).

Debido a que el método de put() no acepta Scalar objetos como el parámetro de datos, usted tiene que convertir la Scalar a algo que put() acepta.

Así que si su Scalar es (1,2,3) tal vez una matriz int int [] escalar = {1,2,3}; debería hacer el truco.

int[] scalar = ... // convert from Scalar object 

// assuming the result of get() is an int[], sum both arrays: 
int[] data = your_mat.get(row, col) + scalar // <- pseudo-code alert :D 

your_mat.put(row, col, data); 

OPCION2:

Pero la forma recomendada, para una gran cantidad de procesamiento de píxeles, es convertir primero un Mat a un primitivo Java, el proceso primitivo y luego convertirlo de nuevo a Mat. Esto es para evitar demasiadas llamadas JNI, este método hace 2 llamadas JNI mientras que el primero hace una por cada entrada/recepción.

El correspondiente Java primitivo tipo de matriz depende del tipo Mat:

CV_8U and CV_8S -> byte[]; 
CV_16U and CV_16S -> short[]; 
CV_32S -> int[]; 
CV_32F -> float[]; 
CV_64F-> double[]; 

Así que el código será algo como esto:

// assuming Mat it's of CV_32S type 
int buff[] = new int[your_mat.total() * your_mat.channels()]; 

your_mat.get(0, 0, buff); 

// buff is now Mat converted to int[] 

your_mat.put(0, 0, buff); // after processing buff, convert it back to Mat type 

OPCIÓN 3:

Ok por lo esas soluciones son bastante feas, esta no es la más efectiva, pero es un poco menos fea, de una manera Java:

List<Integer> scalarList = ... // your conversion from a Scalar to a List 
List<Integer> channelsList = new ArrayList<Integer>(); 

Converters.Mat_to_vector_int(channels, channelsList); // this is an existing OpenCV4Android converter 

// process channelsList and scalarList, store in channelsList 

channels = Converters.vector_int_to_Mat(channelsList); // after processing, convert it back to Mat type 

Ahora que lo pienso opción 3 es bastante similar a la opción 2 , si Converters trabajo de OpenCV similares internamente como el opción de conversión 2.

+0

Aunque esta respuesta ya no es relevante, la aceptaré porque parece correcta y completa – Anton

+1

Sí, noté más tarde que la pregunta era un poco antigua. Pero el problema todavía es bastante común hoy en día para los nuevos usuarios de opencv. AFAIK estas opciones son actualmente las mejores opciones para iterar a través de píxeles en java. –