You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Raspberry Pi 3+Pi Camera+OpenCV的顶视人数统计技术求助

Fixing Pi Camera Integration for Your OpenCV People Counting Project

Got it, let's get your Pi Camera working with that people counting code instead of the USB camera. There are two solid approaches here—one using the official modern Picamera2 library (recommended for new Raspberry Pi OS versions) and another that lets you keep using your existing cv2.VideoCapture logic with a quick system tweak.

The old picamera library is no longer maintained, so Picamera2 is the official replacement for Python 3.7+. It plays nicely with OpenCV and gives better performance for Pi Camera.

Step 1: Install Dependencies

First, install the required packages:

sudo apt update && sudo apt install -y python3-picamera2 python3-opencv python3-numpy

Step 2: Modify Your Code

Replace the USB camera initialization and frame reading logic with this Picamera2 setup. Here's your full updated code:

import argparse
import datetime
import imutils
import math
import cv2
import numpy as np
from picamera2 import Picamera2  # Add this import

width = 800
textIn = 0
textOut = 0

def testIntersectionIn(x, y):
    res = -450 * x + 400 * y + 157500
    if((res >= -550) and (res < 550)):
        print (str(res))
        return True
    return False

def testIntersectionOut(x, y):
    res = -450 * x + 400 * y + 180000
    if ((res >= -550) and (res <= 550)):
        print (str(res))
        return True
    return False

# Initialize Picamera2 instead of cv2.VideoCapture
picam2 = Picamera2()
# Configure resolution (match your resize width, keep aspect ratio)
picam2.configure(picam2.create_preview_configuration(main={"format": 'RGB888', "size": (width, int(width*0.75))}))
picam2.start()

firstFrame = None

while True:
    # Capture frame from Pi Camera (returns RGB format)
    frame = picam2.capture_array()
    # Convert RGB to BGR (OpenCV's default format)
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    
    text = "Unoccupied"

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

    if firstFrame is None:
        firstFrame = gray
        continue

    frameDelta = cv2.absdiff(firstFrame, gray)
    thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
    thresh = cv2.dilate(thresh, None, iterations=2)
    _, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    for c in cnts:
        if cv2.contourArea(c) < 12000:
            continue
        (x, y, w, h) = cv2.boundingRect(c)
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.line(frame, (width // 2, 0), (width, 450), (250, 0, 1), 2) #blue line
        cv2.line(frame, (width // 2 - 50, 0), (width - 50, 450), (0, 0, 255), 2)#red line
        rectagleCenterPont = ((x + x + w) //2, (y + y + h) //2)
        cv2.circle(frame, rectagleCenterPont, 1, (0, 0, 255), 5)
        if(testIntersectionIn((x + x + w) // 2, (y + y + h) // 2)):
            textIn += 1
        if(testIntersectionOut((x + x + w) // 2, (y + y + h) // 2)):
            textOut += 1

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    cv2.putText(frame, "In: {}".format(str(textIn)), (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
    cv2.putText(frame, "Out: {}".format(str(textOut)), (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
    cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"), (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.35, (0, 0, 255), 1)
    cv2.imshow("Security Feed", frame)

# Cleanup Picamera2 instead of camera.release()
picam2.stop()
cv2.destroyAllWindows()

Key Notes:

  • Make sure you've enabled the Camera interface in raspi-config (go to Interface Options > Camera and select "Yes").
  • The resolution configuration matches your width=800 setting to avoid unnecessary resizing overhead.

Option 2: Emulate Pi Camera as a V4L2 Video Device

If you want to keep using your original cv2.VideoCapture(0) line without major code changes, you can map the Pi Camera to a virtual video device.

Step 1: Load the V4L2 Module

Run this command to load the module temporarily:

sudo modprobe bcm2835-v4l2

Step 2: Make It Permanent (Load on Boot)

Add the module to your system's startup modules:

echo "bcm2835-v4l2" | sudo tee -a /etc/modules

Step 3: Reboot and Test

Restart your Pi, then check if the video device exists:

ls /dev/video*

You should see /dev/video0 listed. Now you can use your original code, but add these lines right after initializing the camera to set the resolution (improves performance):

camera = cv2.VideoCapture(0)
# Set resolution to match your resize width
camera.set(cv2.CAP_PROP_FRAME_WIDTH, width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, int(width*0.75))

Key Notes:

  • This method works but can have lower performance than Picamera2, especially at higher resolutions.
  • If you get permission errors, add your user to the video group:
    sudo usermod -aG video $USER
    
    Log out and back in for the change to take effect.

Quick Debug Tips

  • If the camera doesn't work, double-check raspi-config to ensure the Camera interface is enabled.
  • For Picamera2, if you see color issues, confirm you're converting RGB to BGR (OpenCV expects BGR by default).
  • Adjust the cv2.contourArea(c) < 12000 threshold if you're getting false detections—tweak it based on your camera's field of view.

内容的提问来源于stack exchange,提问作者Uraforclain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:36:49