Skip to content

Real-time people counting with computer vision — single or multi-camera, YOLOv8 tracking, Flask streaming, and GUI for scalable monitoring. Contagem de pessoas em tempo real com visão computacional — suporte a uma ou várias câmeras, rastreamento com YOLOv8, streaming via Flask e GUI para monitoramento escalável.

License

Notifications You must be signed in to change notification settings

AugustoNP/CV_LP_project

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

CV_LP_project

Python OpenCV YOLOv8 Tkinter Threading

Note: All IP addresses, passwords, and camera information have been anonymized to protect sensitive data.


Table of Contents


English

Overview

This repository contains a series of computer vision scripts designed to count people in real-time across one or multiple cameras. The project evolved from basic frame difference detection to YOLO-based tracking, timer-enabled snapshots, Flask video streaming, and finally a multi-camera GUI people counter.

Back to Top


1. Simple Difference-Based Detection

Highlights:

  • Extremely lightweight; runs on low-power devices.
  • Detects moving objects without complex models.
  • Allows quick prototyping.

Example Workflow:

first_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
first_frame = cv2.GaussianBlur(first_frame, (21, 21), 0)

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)

delta = cv2.absdiff(first_frame, gray)
thresh = cv2.threshold(delta, 50, 255, cv2.THRESH_BINARY)[1]

contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    if cv2.contourArea(c) > min_area:
        cx = int((x + x + w) / 2)
        if cx > line_x: count_exit += 1

Lessons Learned:

  • Sensitive to lighting changes and shadows.
  • Thresholds and minimum contour area require tuning.
  • Simple and effective for testing but not robust for multi-camera setups.

Full script | Back to Top


2. YOLO Single Camera People Counter

Highlights:

  • Real-time object detection using YOLOv8 nano.
  • Persistent tracking IDs prevent double-counting.
  • Simple vertical line counting.
  • Can save snapshots of detected people crossing the line.

Example Workflow:

ret, frame = cap.read()
results = model.track(frame, persist=True, classes=[0])

for track_id, box in zip(results[0].boxes.id, results[0].boxes.xyxy):
    x1, y1, x2, y2 = box
    center_x = (x1 + x2) // 2

if prev_x < line_x and curr_x >= line_x:
    out_count += 1

Lessons Learned:

  • YOLO improves detection accuracy over simple frame differencing.
  • Centroid tracking is essential to maintain correct counts.
  • Single-camera setup is easier for testing; multi-camera setups require further integration.

Full script | Back to Top


3. YOLO Timer-Based People Counter

Highlights:

  • Adds timers for each detected person using Python threading.
  • Snapshots saved automatically when timer expires.
  • Handles multiple people concurrently without freezing the video feed.

Example Workflow:

threading.Thread(target=countdown, args=(15, track_id)).start()

def countdown(seconds, track_id):
    time.sleep(seconds)
    save_snapshot(track_id)

Lessons Learned:

  • Threading ensures the main video feed is not blocked.
  • Timer-based snapshots allow automated capture of events.
  • Concurrent snapshot saving must be handled carefully.

Full script | Back to Top


4. Flask Video Stream

Highlights:

  • Streams video from USB cameras over HTTP.
  • Accessible from any device on the network.
  • Works best for lightweight single-camera monitoring.

Example Workflow:

camera = cv2.VideoCapture(0)
ret, frame = camera.read()

ret, buffer = cv2.imencode('.jpg', frame)
yield (b'--frame\r\n'
       b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

Lessons Learned:

  • Flask provides a simple interface for live streaming.
  • Frame encoding must be efficient for smooth playback.

Full script | Back to Top


5. Multi-Camera GUI People Counter

Highlights:

  • Dynamic camera selection via GUI.
  • Threaded updates for smooth GUI operation.
  • Real-time tracking and counting with YOLO.
  • Highly scalable; cameras stored in a dictionary.
  • Modular structure: GUI, detection, tracking, threading.

Example Workflow:

selectcam("LavaBotas")
threading.Thread(target=start_feed).start()

if prev_x < line_x and curr_x >= line_x:
    out_count += 1

Cam_dict = {"adm": "Ti", "prod": "LavaBotas", "new_area": "NewCameraIP"}
video_label.config(image=ImageTk.PhotoImage(Image.fromarray(frame)))

Lessons Learned:

  • Threading ensures smooth video updates and responsive GUI.
  • Persistent IDs maintain accurate counting.
  • Modular camera dictionary allows easy addition of new cameras.
  • Multi-camera architecture is key to scaling from a single feed to multiple areas.

Full script | Back to Top


Português

Visão Geral

Este repositório contém uma série de scripts de visão computacional projetados para contar pessoas em tempo real em uma ou várias câmeras. O projeto evoluiu da detecção básica por diferença de quadros ao rastreamento com YOLO, snapshots com temporizador, streaming de vídeo com Flask e, finalmente, um contador de pessoas GUI multi-câmera.

Voltar ao Topo


1. Detecção Baseada em Diferença Simples

Destaques:

  • Extremamente leve; roda em dispositivos de baixo consumo.
  • Detecta objetos em movimento sem modelos complexos.
  • Permite prototipagem rápida.

Exemplo de Fluxo:

first_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
first_frame = cv2.GaussianBlur(first_frame, (21, 21), 0)

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)

delta = cv2.absdiff(first_frame, gray)
thresh = cv2.threshold(delta, 50, 255, cv2.THRESH_BINARY)[1]

contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    if cv2.contourArea(c) > min_area:
        cx = int((x + x + w) / 2)
        if cx > line_x: count_exit += 1

Lições Aprendidas:

  • Sensível a mudanças de iluminação e sombras.
  • Limiares e área mínima de contorno exigem ajuste.
  • Simples e eficaz, mas não robusto para multi-câmeras.

Script completo | Voltar ao Topo


2. Contador de Pessoas YOLO em Câmera Única

Destaques:

  • Detecção em tempo real com YOLOv8 nano.
  • IDs persistentes evitam dupla contagem.
  • Contagem simples com linha vertical.
  • Possibilidade de snapshots automáticos.

Exemplo de Fluxo:

ret, frame = cap.read()
results = model.track(frame, persist=True, classes=[0])

for track_id, box in zip(results[0].boxes.id, results[0].boxes.xyxy):
    x1, y1, x2, y2 = box
    center_x = (x1 + x2) // 2

if prev_x < line_x and curr_x >= line_x:
    out_count += 1

Lições Aprendidas:

  • YOLO aumenta a precisão em relação à diferença de quadros.
  • Rastreamento por centróides é essencial para contagens corretas.
  • Configuração de uma câmera é mais simples; multi-câmera requer integração adicional.

Script completo | Voltar ao Topo


3. Contador de Pessoas YOLO com Temporizador

Destaques:

  • Adiciona temporizadores para cada pessoa usando threading do Python.
  • Snapshots salvos automaticamente ao expirar o temporizador.
  • Rastreia múltiplas pessoas simultaneamente sem travar o feed de vídeo.

Exemplo de Fluxo:

threading.Thread(target=countdown, args=(15, track_id)).start()

def countdown(seconds, track_id):
    time.sleep(seconds)
    save_snapshot(track_id)

Lições Aprendidas:

  • Threading evita travamento do feed principal.
  • Snapshots automatizam a captura de eventos.
  • Salvar simultaneamente exige cuidado.

Script completo | Voltar ao Topo


4. Streaming de Vídeo com Flask

Destaques:

  • Transmite vídeo de câmeras USB via HTTP.
  • Acessível pela rede via navegador.
  • Ideal para monitoramento leve de uma única câmera.

Exemplo de Fluxo:

camera = cv2.VideoCapture(0)
ret, frame = camera.read()

ret, buffer = cv2.imencode('.jpg', frame)
yield (b'--frame\r\n'
       b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

Lições Aprendidas:

  • Flask fornece streaming ao vivo de forma simples.
  • Codificação eficiente mantém reprodução fluida.

Script completo | Voltar ao Topo


5. Contador de Pessoas GUI Multi-Câmera

Destaques:

  • GUI permite seleção dinâmica de câmeras.
  • Atualizações em threads para operação suave.
  • Rastreamento e contagem em tempo real com YOLO.
  • Altamente escalável; câmeras armazenadas em um dicionário.
  • Estrutura modular: GUI, detecção, rastreamento, threading.

Exemplo de Fluxo:

selectcam("LavaBotas")
threading.Thread(target=start_feed).start()

if prev_x < line_x and curr_x >= line_x:
    out_count += 1

Cam_dict = {"adm": "Ti", "prod": "LavaBotas", "new_area": "NewCameraIP"}
video_label.config(image=ImageTk.PhotoImage(Image.fromarray(frame)))

Lições Aprendidas:

  • Threading garante atualizações suaves.
  • IDs persistentes mantêm contagens precisas.
  • Dicionário modular simplifica adicionar câmeras.
  • Arquitetura multi-câmera escalável.

Script completo | Voltar ao Topo

About

Real-time people counting with computer vision — single or multi-camera, YOLOv8 tracking, Flask streaming, and GUI for scalable monitoring. Contagem de pessoas em tempo real com visão computacional — suporte a uma ou várias câmeras, rastreamento com YOLOv8, streaming via Flask e GUI para monitoramento escalável.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages