Sto lavorando a un progetto di robotica utilizzando un telefono Android come processore principale e la fotocamera per rilevare il movimento. Ho ricevuto il Android binary package from OpenCV e l'ho installato correttamente. Posso acquisire immagini usando la fotocamera nativa OpenCV e visualizzarle sullo schermo. Sto avendo problemi usando la classe di sottrazione dello sfondo, però. Posso creare un nuovo oggetto BackgroundSubtractorMOG nel costruttore, ma quando cerco di eseguire il codice qui sotto, forza l'uscita ottengo l'errore "Solo immagini a 8 e 3 canali a 8 bit sono supportate in BackgroundSubtractorMOG" dal codice nativo. Ho provato a cambiare Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA in Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB, e quindi non forza forzare la chiusura, ma tutto quello che ottengo è una schermata nera. Sono abbastanza sicuro che bmp è ancora nullo con FRAME_RGB, perché lo schermo rimane nero, e il contatore fps che stavo disegnando subito dopo la bitmap (rimosso dal codice postato di seguito per chiarezza e come passaggio per la risoluzione dei problemi) non viene visualizzato.OpenCV Android Background Sottrazione
Abbiamo esaminato il codice OpenCV C++ per questa funzione (line 388 here), e l'errore di tipo di immagine si verifica se il tipo di immagine non è CV_8UC1 o CV_8UC3, quindi provato usando l'CvType.CV_8UC3 java invece di Highgui. CV_CAP_ANDROID_COLOR_FRAME_RGBA in capture.retrieve(), ma forza chiusa e ho ottenuto un errore "Formato frame di output non supportato".
Immagino di avere appena avuto un problema di conversione di tipo, ma non riesco a capire per la vita di me dove i tipi di immagini specifiche di Android di OpenCV si adattano ai loro normali tipi di immagini documentati. Qualsiasi aiuto sarebbe apprezzato.
Le variabili:
private SurfaceHolder mHolder;
private VideoCapture mCamera;
private Mat mRgba;
private Mat mFGMask;
private BackgroundSubtractorMOG mBGSub;
corsa di mia SurfaceView() funzione:
public void run() {
Bitmap bmp = null;
synchronized (this) {
if (mCamera == null)
break;
if (!mCamera.grab()) {
Log.e(TAG, "mCamera.grab() failed");
break;
}
processFrame(mCamera);
bmp = Bitmap.createBitmap(mFGMask.cols(), mFGMask.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mFGMask, bmp);
}
if (bmp != null) {
Canvas canvas = mHolder.lockCanvas();
if (canvas != null) {
canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth())/2, (canvas.getHeight() - bmp.getHeight())/2, null);
mHolder.unlockCanvasAndPost(canvas);
}
bmp.recycle();
}
}
La funzione processFrame() fa riferimento nel run():
protected void processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
mBGSub.apply(mRgba, mFGMask);
}
Edit:
La soluzione che ha finito per lavorare:
protected void processFrame(VideoCapture capture) {
capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGB);
//GREY_FRAME also works and exhibits better performance
//capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_GREY_FRAME);
mBGSub.apply(mRgba, mFGMask, 0.1);
Imgproc.cvtColor(mFGMask, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
}
Questo mi avvicina. La sintassi esatta per la versione java è: 'Imgproc.cvtColor (mRgba, rgb, Imgproc.COLOR_RGBA2RGB);' per il primo convert, e il secondo non è necessario (non sto facendo nulla con l'immagine grezza dopo la sottrazione). Ora, ottengo uno schermo nero (nessuna forza chiusa). Se cambio il formato bitmap in Bitmap.Config.RGB_565, ottengo il mio contatore FPS, quindi so che è in esecuzione, ma è ancora uno schermo nero. Grazie per avermi fatto un po 'più avanti, però. – RedPeasant
@RedPeasant Grazie per le informazioni sulla sintassi corretta. Ho aggiornato la mia risposta per includerla. La fotocamera è in movimento e lo schermo è ancora nero? – mevatron
@RedPeasant Ho aggiornato la mia risposta per includere ulteriori informazioni su 'BackgroundSubtractorMOG'. – mevatron