基于OpenCV(Python)利用两张高速公路图像统计车辆数量的实现步骤咨询
Got it, let's break this down step by step—using your empty highway image as a clean background reference is a perfect approach to isolate vehicles, and it's straightforward with OpenCV in Python. Here's exactly how to implement this:
First, we'll load both images and convert them to grayscale (color isn't necessary for this task, and grayscale reduces computational load). We'll also make sure they're the exact same size—if they aren't, you'll need to resize one to match the other first.
import cv2 import numpy as np # Load images background = cv2.imread('empty_highway.jpg') target = cv2.imread('with_cars_highway.jpg') # Convert to grayscale gray_bg = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY) gray_target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY) # Optional: Resize if images are different sizes (adjust dimensions as needed) # gray_bg = cv2.resize(gray_bg, (width, height)) # gray_target = cv2.resize(gray_target, (width, height))
The core idea here is that any pixel difference between the empty highway and the image with cars should correspond to a vehicle. We'll use absolute difference to get these regions, then apply thresholding to turn them into a binary (black/white) image where white pixels represent potential vehicles. We'll also use morphological operations to clean up small noise spots.
# Compute absolute difference between the two grayscale images diff = cv2.absdiff(gray_bg, gray_target) # Apply threshold to get a binary image _, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY) # Use morphological operations to remove noise (adjust kernel size based on your images) kernel = np.ones((5,5), np.uint8) cleaned = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) cleaned = cv2.morphologyEx(cleaned, cv2.MORPH_OPEN, kernel)
Note: The threshold value (30 here) might need adjustment—if you're getting too much noise, increase it; if you're missing vehicles, decrease it.
Now we'll find contours in the cleaned binary image. Each contour represents a potential vehicle, but we'll filter out tiny contours (which are leftover noise) by checking their area. Finally, we'll count the valid contours and optionally draw bounding boxes around them to visualize the result.
# Find contours in the cleaned image contours, _ = cv2.findContours(cleaned, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Count valid vehicles (filter out small contours) vehicle_count = 0 for contour in contours: area = cv2.contourArea(contour) # Adjust this area threshold based on your image's scale (e.g., 500 might be too big/small) if area > 500: vehicle_count += 1 # Optional: Draw bounding box around the vehicle x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(target, (x, y), (x+w, y+h), (0, 255, 0), 2) # Print the result print(f"Total vehicles detected: {vehicle_count}") # Display the result image with bounding boxes cv2.imshow('Vehicles Detected', target) cv2.waitKey(0) cv2.destroyAllWindows()
- Lighting Consistency: This method works best if both images were taken under similar lighting conditions (same time of day, no sudden shadows). If lighting differs a lot, you might need to add a preprocessing step like histogram equalization to normalize brightness.
- Contour Area Threshold: Play around with the area value (500 in the example) to match your image—larger vehicles will need a higher threshold, smaller ones a lower one.
- Morphological Kernels: Adjust the kernel size (5x5 here) if noise is still present or if vehicle edges are being erased.
内容的提问来源于stack exchange,提问作者Uzay Ayden

