Índice
2. Reconhecimento de carro - algoritmo de remoção de fundo (KNN/MOG2)
3. Conte o número de fluxos de tráfego
Introdução ao Projeto
Este projeto utiliza principalmente métodos de visão tradicionais para detectar o tráfego na faixa e pode identificar com mais precisão o número de veículos na faixa. Devido às limitações dos próprios algoritmos de visão tradicionais, também haverá imprecisões no reconhecimento.
processo geral
Sem mais delongas, vamos falar primeiro das ideias e ir direto para o fluxograma.
Aqui, todos os parâmetros e variáveis predefinidos são chamados coletivamente de “macro”, e então cada quadro de imagem reconhecido é processado e, finalmente, a renderização ideal é obtida.
As renderizações são as seguintes:
ambiente de depuração
- Caderno Jupyter (Anaconda)
- Pitão 3.9.12
- OpenCv 4.5.5
Fluxo do Projeto
1. Pré-processamento
#灰度
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#高斯去噪
blur=cv2.GaussianBlur(frame,(5,5),5)
mask=removebg.apply(blur)
#腐蚀
erode=cv2.erode(mask,kernel,iterations=2))#iteration=n 迭代n次
#膨胀
dilate=cv2.dilate(erode,kernel,iterations=2
#cv2.imshow("x",dilate)
dst=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
2. Reconhecimento de carro - algoritmo de remoção de fundo (KNN/MOG2)
Vamos primeiro apresentar o algoritmo KNN (porque o algoritmo usado desta vez é KNN)
O princípio de implementação do algoritmo de classificação do vizinho mais próximo KNN: para determinar a categoria de uma amostra desconhecida, todas as amostras de categorias conhecidas são usadas como referência, a distância entre a amostra desconhecida e todas as amostras conhecidas é calculada e as K amostras conhecidas mais próximos da amostra desconhecida são selecionados. , de acordo com a regra de votação majoritária, a amostra desconhecida e as K amostras vizinhas mais próximas são classificadas na mesma categoria.
No Opencv, o algoritmo KNN foi encapsulado, para que possamos chamá-lo diretamente.
#KNN算法去背景
removebg=cv2.createBackgroundSubtractorKNN()
MOG2 é um algoritmo de segmentação de primeiro plano/fundo baseado em uma mistura de modelos gaussianos. Os pixels de fundo são modelados usando uma mistura de K (K = 3 ou 5) distribuições gaussianas. Use o tempo em que essas cores estão presentes (durante todo o vídeo) como pesos para a mistura. A cor de fundo geralmente dura mais e é mais estática. Esta função possui alguns parâmetros opcionais, como o tempo de modelagem da cena, o número de componentes da mistura gaussiana, limites, etc. Defina todos eles com os valores padrão. Então, ao longo do vídeo, precisamos usar backgroundsubtractor.apply() para obter a máscara de primeiro plano. Os objetos em movimento serão marcados em branco e o fundo será marcado em preto. O método de uso é o mesmo acima, então não entrarei em detalhes aqui.
3. Conte o número de fluxos de tráfego
O método utilizado nesta estatística é: encontrar o ponto central da moldura retangular. Quando o ponto passa pela linha reta definida antecipadamente, o número de veículos +1
Função para calcular o ponto central:
def center(x,y,w,h):
x1=int(w/2)
y1=int(h/2)
cx=x+x1
cy=y+y1
A parte do código para contar o fluxo de tráfego:
cpoint=center(x,y,w,h)
cars.append(cpoint)#将中心点储存到cars数组中
for (x,y) in cars:
if(y>lineHeight-7 and y<lineHeight+7):
Car_nums +=1
cars.remove((x,y))
print(Car_nums)
Finalmente, após algum processamento simples, o projeto foi realizado.
fim
Código fonte anexado:
import cv2
import numpy as np
lineHeight=550
#穿过直线的车的数量
Car_nums=0
#储存中心坐标的数组
cars=[]
#KNN算法去背景
removebg=cv2.createBackgroundSubtractorKNN()
def center(x,y,w,h):
x1=int(w/2)
y1=int(h/2)
cx=x+x1
cy=y+y1
return cx,cy
video=cv2.VideoCapture('D://video.mp4')
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
while True:
ret,frame=video.read()
if(ret!=0):
#灰度
cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#高斯去噪
blur=cv2.GaussianBlur(frame,(5,5),5)
mask=removebg.apply(blur)
#腐蚀
erode=cv2.erode(mask,kernel,iterations=2))#iteration=n 迭代n次
#膨胀
dilate=cv2.dilate(erode,kernel,iterations=2
#cv2.imshow("x",dilate)
dst=cv2.morphologyEx(dilate,cv2.MORPH_CLOSE,kernel)
#cv2.imshow("x1",dst)
#画出检测线
cv2.line(frame,(10,lineHeight),(1400,lineHeight),(255,0,0),2)
counts,h=cv2.findContours(dst,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#遍历所有轮廓
for(i,c) in enumerate(counts):
(x,y,w,h)=cv2.boundingRect(c)
if((w<=90) and (h<=90)):
continue
if(y<66):
continue
#将有效的车绘制出来
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
cpoint=center(x,y,w,h)
cars.append(cpoint)#将中心点储存到cars数组中
for (x,y) in cars:
if(y>lineHeight-7 and y<lineHeight+7):
Car_nums +=1
cars.remove((x,y))
print(Car_nums)
cv2.putText(frame,"Cars nums:"+str(Car_nums),(500,60),cv2.FONT_HERSHEY_DUPLEX,1,(255,0,0))
cv2.imshow("video",frame)
key=cv2.waitKey(1)
if(key==27):
break
video.release()
cv2.destroyAllWindows()
Em anexo está o material de vídeo de teste:
Link: https://pan.baidu.com/s/1u_hjCtL3FR6FzeEVQar7wg?pwd=2Y1p
Código de extração: 2Y1p
Um fluxograma mais vívido: