Notas de estudio de opencv 9: modelado de fondo + estimación de flujo óptico

Modelado de fondo

método de diferencia de cuadros

Dado que el objetivo en la escena se está moviendo, la posición de la imagen del objetivo en diferentes cuadros de imagen es diferente. Este tipo de algoritmo realiza una operación de diferencia en dos cuadros consecutivos de imágenes en el tiempo. Los píxeles correspondientes a diferentes cuadros se restan para determinar el valor absoluto de la diferencia en escala de grises. Cuando el valor absoluto excede un cierto umbral, se puede determinar que es un objetivo en movimiento, logrando así la función de detección del objetivo.

título

El método de diferencia de cuadros es muy simple, pero introducirá problemas de ruido y agujeros.

Modelo de mezcla gaussiana

Antes de la detección de primer plano, primero se entrena el fondo y se utiliza un modelo de mezcla gaussiana para simular cada fondo de la imagen. El número de mezclas gaussianas para cada fondo puede ser adaptativo. Luego, en la fase de prueba, se realiza la coincidencia de GMM en los nuevos píxeles. Si el valor del píxel puede coincidir con uno de los gaussianos, se considera el fondo; de lo contrario, se considera el primer plano. Dado que el modelo GMM se actualiza y aprende continuamente durante todo el proceso, tiene cierto grado de solidez ante entornos dinámicos. Finalmente, se lograron buenos resultados al realizar la detección de primer plano sobre un fondo dinámico con ramas balanceándose.

Los cambios de píxeles en el vídeo deben ajustarse a la distribución gaussiana.

título

La distribución real del fondo debe ser una mezcla de múltiples distribuciones gaussianas, y cada modelo gaussiano también puede tener pesos.

título

Método de aprendizaje del modelo gaussiano mixto
  • 1. Primero inicialice cada parámetro de la matriz del modelo gaussiano.

  • 2. Tome imágenes de datos de cuadros T en el video para entrenar el modelo de mezcla gaussiana. Después de obtener el primer píxel, utilícelo como la primera distribución gaussiana.

  • 3. Cuando el valor del píxel llegue más tarde, compárelo con el valor medio del gaussiano anterior. Si el valor del punto del píxel está dentro de 3 veces la varianza del valor medio del modelo, pertenece a la distribución y sus parámetros se actualizan. .

  • 4. Si el siguiente píxel que viene no satisface la distribución gaussiana actual, utilícelo para crear una nueva distribución gaussiana.

Método de prueba del modelo de mezcla gaussiana

En la fase de prueba, el valor del nuevo píxel se compara con cada valor medio en el modelo de mezcla gaussiana. Si la diferencia es entre 2 veces la varianza, se considera el fondo, de lo contrario se considera el primer plano. Asigne el valor de primer plano a 255 y el valor de fondo a 0. Esto forma una imagen binaria en primer plano.

título

import numpy as np
import cv2

#经典的测试视频
cap = cv2.VideoCapture('test.avi')
#形态学操作需要使用,用于去除噪音
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
#创建混合高斯模型用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()

while(True):
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    #形态学开运算去噪点
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    #寻找视频中的轮廓
    im, contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for c in contours:
        #计算各轮廓的周长
        perimeter = cv2.arcLength(c,True)
        if perimeter > 188:
            #找到一个直矩形(不会旋转)
            x,y,w,h = cv2.boundingRect(c)
            #画出这个矩形
            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)    

    cv2.imshow('frame',frame)
    cv2.imshow('fgmask', fgmask)
    k = cv2.waitKey(150) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()


Por favor agregue la descripción de la imagen.

Estimación del flujo óptico.

El flujo óptico es la "velocidad instantánea" del movimiento de píxeles de un objeto que se mueve espacialmente en el plano de imágenes de observación. Según las características del vector de velocidad de cada píxel, la imagen se puede analizar dinámicamente, como el seguimiento del objetivo.

  • Brillo constante: el brillo de un mismo punto no cambiará con el cambio de hora.

  • Pequeño movimiento: los cambios en el tiempo no causarán cambios drásticos en la posición. Solo en el caso de pequeños movimientos se pueden usar los cambios en la escala de grises causados ​​por los cambios de posición de la unidad entre los fotogramas anteriores y posteriores para aproximar la derivada parcial de la escala de grises a la posición.

  • Consistencia espacial: los puntos adyacentes en una escena también son puntos adyacentes cuando se proyectan sobre la imagen, y los puntos adyacentes tienen la misma velocidad. Debido a que sólo existe una restricción de ecuación básica del método de flujo óptico y la velocidad requerida en las direcciones x e y, existen dos variables desconocidas. Por lo tanto, es necesario resolver n múltiples ecuaciones seguidas.

título

título

Algoritmo de Lucas-Kanade

título

¿Cómo resolver un sistema de ecuaciones? Parece que un píxel no es suficiente ¿Qué otras características existen durante el movimiento de los objetos? (Los puntos de esquina son reversibles, por lo que los puntos característicos utilizan puntos de esquina)

título

cv2.calcOpticalFlowPyrLK():

parámetro:

  • prevImagen imagen del cuadro anterior

  • siguienteImagen imagen del cuadro actual

  • vector de punto de característica prevPts que se va a rastrear

  • winSize el tamaño de la ventana de búsqueda

  • maxLevel El número máximo de niveles de pirámide.

devolver:

  • nextPts vector de punto de característica de seguimiento de salida

  • estado Si se encuentra el punto característico, el estado si se encuentra es 1, si no se encuentra, el estado es 0

import numpy as np
import cv2

cap = cv2.VideoCapture('test.avi')

# 角点检测所需参数
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7)

# lucas kanade参数
lk_params = dict( winSize  = (15,15),
                  maxLevel = 2)

# 随机颜色条
color = np.random.randint(0,255,(100,3))

# 拿到第一帧图像
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 返回所有检测特征点,需要输入图像,角点最大数量(效率),品质因子(特征值越大的越好,来筛选)
# 距离相当于这区间有比这个角点强的,就不要这个弱的了
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)

# 创建一个mask
mask = np.zeros_like(old_frame)

while(True):
    ret,frame = cap.read()
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 需要传入前一帧和当前图像以及前一帧检测到的角点
    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)

    # st=1表示
    good_new = p1[st==1]
    good_old = p0[st==1]

    # 绘制轨迹
    for i,(new,old) in enumerate(zip(good_new,good_old)):
        a,b = new.ravel()
        c,d = old.ravel()
        mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
        frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
    img = cv2.add(frame,mask)

    cv2.imshow('frame',img)
    k = cv2.waitKey(150) & 0xff
    if k == 27:
        break

    # 更新
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1,1,2)

cv2.destroyAllWindows()
cap.release()

Por favor agregue la descripción de la imagen.

referencia

1. [Las mejores recomendaciones de cursos OpenCV del sitio 2021B] Un conjunto completo de cursos OpenCV desde el inicio hasta la práctica

Supongo que te gusta

Origin blog.csdn.net/weixin_41756645/article/details/125614922
Recomendado
Clasificación