Abbiamo avuto lo stesso compito in uno dei nostri progetti.
Per ottenere il modello di sfondo, creiamo semplicemente una classe BackgroundModel, acquisiamo il primo (diciamo) 50 fotogrammi e calcoliamo il fotogramma medio per evitare errori di pixel nel modello di sfondo.
Ad esempio, se si ottiene un'immagine in scala di grigi a 8 bit (CV_8UC1) dalla fotocamera, si inizializza il modello con CV_16UC1 per evitare il ritaglio.
cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0));
Ora, in attesa dei primi telai per calcolare il vostro modello, basta aggiungere ogni fotogramma al modello e contare il numero di frame ricevuti.
void addFrame(cv::Mat frame) {
cv::Mat convertedFrame;
frame.convertTo(convertedFrame, CV_16UC1);
cv::add(convertedFrame, model, model);
if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50
createMask();
}
}
La funzione createMask() calcola il frame medio che usiamo per il modello.
void createMask() {
cv::convertScaleAbs(model, mask, 1.0/learnedFrames);
mask.convertTo(mask, CV_8UC1);
}
Ora, è sufficiente inviare tutti i fotogrammi il percorso attraverso la classe BackgroundModel a una funzione di sottrazione(). Se il risultato è un cv :: Mat vuoto, la maschera viene comunque calcolata. Altrimenti, ottieni una cornice sottratta.
cv::Mat subtract(cv::Mat frame) {
cv::Mat result;
if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50
cv::subtract(frame, mask, result);
}
else {
addFrame(frame);
}
return result;
}
Ultimo ma non meno importante, è possibile utilizzare somma scalare (const Mat & MTX) per calcolare la somma dei pixel e decidere se si tratta di una cornice con le luci su di esso.
Grazie mille ping (",) – user854576
@ user854576 Se questa è una risposta corretta, si dovrebbe essere gentili e accettarlo. Vedere [questa pagina] (http://stackoverflow.com/faq#howtoask) nel FAQ come accettare le risposte. –