2011-12-26 21 views
6

Attualmente sto provando a migrare un po 'di codice legacy da iPhone ad Android. Questo codice usa la libreria OpenCV per fare un po 'di elaborazione delle immagini. Nel complesso va bene, ma mi sono bloccato su una riga di codice non ho idea di come può essere convertito in codice Java:Conversione di codice OpenCV da 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 domanda è - quello che dovrebbe essere usato al posto del + = operatore in Java codice per aggiungere un oggetto scalare a un Mat?

+0

Puoi mostrarci cosa hai, dove esattamente (in Java) sei bloccato? – MByD

+0

+ = è un operatore accettabile per le primitive, ma non per gli oggetti. Probabilmente dovrai scrivere un metodo che faccia l'add per l'oggetto. – Kylar

+0

Il codice C++ aggiunge uno scalare a un oggetto Mat. In Java ho creato sia oggetti scalari che mat ma non riesco a trovare un metodo per aggiungere Scalar a Mat.La classe Core in JavaCV contiene un metodo statico add (Mat, Mat, Mat), ma consente solo di aggiungere due Mat – Anton

risposta

5

Nota: prendere questa risposta con un grano di sale, non ho completamente testato questo;)

OPTION1:

Il modo più diretto, e se si sono solo andando a elaborare pochi pixel, è utilizzando your_mat.put (riga, col, dati) e your_mat.get (riga, col).

Poiché il metodo put() non accetta Scalar oggetti come il parametro dei dati, è necessario convertire il Scalar a qualcosa che put() accetta.

Quindi se il tuo Scalar è (1,2,3) forse un array int int [] scalare = {1,2,3}; dovrebbe fare il trucco.

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); 

OPZIONE2:

Ma il metodo consigliato, per un sacco di elaborazione dei pixel, è prima convertire un Mat a una primitiva Java, processo primitivo e poi riconvertirlo in Mat. Questo per evitare troppe chiamate JNI, questo metodo esegue 2 chiamate JNI mentre il primo ne crea uno per put/get.

Java primitivo tipo di matrice corrispondente dipende dal tipo di Mat:

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

Quindi il codice sarà qualcosa di simile:

// 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 

OPZIONE 3:

Ok quelle soluzioni sono piuttosto brutte, questa non è la più efficace ma è un po 'meno brutta, in un modo 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 

Ora che ci penso opzione 3 è molto simile a opzione 2, se Converters lavoro di OpenCV simile internamente come il opzione di 2 di conversione.

+0

Anche se questa risposta non è più rilevante, la accetterò perché sembra essere corretta e completa – Anton

+1

Sì, ho notato in seguito che la domanda era un po 'vecchia. Ma il problema è ancora abbastanza comune oggi per i nuovi utenti di opencv. AFAIK queste opzioni sono attualmente le migliori scelte per iterare attraverso pixel in java. –