我有这段代码,应该使用二进制图像来帮助我在特定位置绘制方框,然后拍摄实时视频源,然后检测这些方框中的变化,我之前一直在使用剪辑进行测试,它与剪辑完美配合,但是每当我使用实时视频时,都会出现此错误:
File "xxxxx\mainnew.py", line 147, in <module>
spot_status = empty_or_not(spot_crop,reference_image)
File "xxxxx\mainnew.py", line 32, in empty_or_not
reference_resized = cv2.resize(reference_image, (spot_bgr.shape[1], spot_bgr.shape[0]))
cv2.error: OpenCV(4.9.0) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\resize.cpp:4155: error: (-215:Assertion failed) inv_scale_x > 0 in function 'cv::resize'
my code
import cv2
import numpy as np
from scipy.spatial import distance
import requests
import time
from skimage.metrics import structural_similarity as compare_ssim
EMPTY = True
NOT_EMPTY = False
def get_parking_spots_bboxes(connected_components):
(totalLabels, label_ids, values, centroid) = connected_components
slots = []
coef = 1
for i in range(1, totalLabels):
# Now extract the coordinate points
x1 = int(values[i, cv2.CC_STAT_LEFT] * coef)
y1 = int(values[i, cv2.CC_STAT_TOP] * coef)
w = int(values[i, cv2.CC_STAT_WIDTH] * coef)
h = int(values[i, cv2.CC_STAT_HEIGHT] * coef)
slots.append([x1, y1, w, h])
return slots
def empty_or_not(spot_bgr, reference_image, threshold=0.45):
# Resize reference image to match the dimensions of spot_bgr
reference_resized = cv2.resize(reference_image, (spot_bgr.shape[1], spot_bgr.shape[0]))
# Convert spot_bgr to grayscale
spot_gray = cv2.cvtColor(spot_bgr, cv2.COLOR_BGR2GRAY)
# Convert reference_resized to grayscale
reference_gray = cv2.cvtColor(reference_resized, cv2.COLOR_BGR2GRAY)
# Compute the Structural Similarity Index (SSI) between the two images
# This index measures the similarity between two images, with 1 being a perfect match
(score, _) = compare_ssim(spot_gray, reference_gray, full=True)
# If the SSI score is above the threshold, consider the spot as not empty
if score >= threshold:
return EMPTY
else:
return NOT_EMPTY
# Function to calculate the absolute difference between two images
def calc_diff(im1, im2):
return np.abs(np.mean(im1) - np.mean(im2))
# Function to fetch coordinates mapping from an API endpoint
def fetch_coordinates_mapping(api_url):
try:
response = requests.get(api_url)
response.raise_for_status() # Raise an exception for HTTP errors
mapping_index = response.json()
return mapping_index
except requests.exceptions.RequestException as e:
print('There was a problem with the fetch operation:', e)
return None
# Paths to mask image and video file
mask_path = './mask_train_binary.png'
video_path = './samples/train_video.mp4'
reference_image = cv2.imread('./refrence.png')
#samples/WIN_20240417_12_35_47_Pro.mp4
# Read the mask image as a grayscale image
mask = cv2.imread(mask_path, 0)
# Initialize video capture object using the video filez
cap = cv2.VideoCapture(video_path)
# Use connected components analysis to identify parking spots in the mask image
connected_components = cv2.connectedComponentsWithStats(mask, 4, cv2.CV_32S)
spots = get_parking_spots_bboxes(connected_components)
# Assign IDs to parking spots based on their bounding boxes
spot_ids = {tuple(spot): idx for idx, spot in enumerate(spots)}
# Initialize lists to store parking spots status and differences between frames
spots_status = [None for _ in spots]
diffs = [None for _ in spots]
# Initialize previous frame variable
previous_frame = None
# Initialize given coordinates for the location
x_given = 0
y_given = 0
# Coordinates mapping for parking spots
coordinates_mapping = {
0: (0, 0),
1: (300, 0),
2: (600, 0),
3: (900, 0),
4: (1200, 0)
}
# API key for sending data
send_key = "xxxxxxx"
# Initialize frame number, ret variable, and processing step
frame_nmr = 0
ret = True
step = 30
# Initialize previous closest spot ID
prev_closest_spot_id = None
# Initialize last fetch time for coordinates
last_fetch_time = time.time() - 2
# Main loop for processing frames
while ret:
ret, frame = cap.read() # Read a frame from the video feed
cv2.circle(frame, (x_given, y_given), 30, 0, -1) # Draw a circle at given coordinates
# Fetch coordinates every 2 seconds
if time.time() - last_fetch_time >= 2:
x_given, y_given = coordinates_mapping[fetch_coordinates_mapping('http://cmdcamp.nl/iot/get/xxxxxx')]
last_fetch_time = time.time()
# Calculate differences between consecutive frames
if frame_nmr % step == 0 and previous_frame is not None:
for spot_indx, spot in enumerate(spots):
x1, y1, w, h = spot
spot_crop = frame[y1:y1 + h, x1:x1 + w, :]
diffs[spot_indx] = calc_diff(spot_crop, previous_frame[y1:y1 + h, x1:x1 + w, :])
# Update parking spots status based on the differences
if frame_nmr % step == 0:
if previous_frame is None:
arr_ = range(len(spots))
else:
arr_ = [j for j in np.argsort(diffs) if diffs[j] / np.amax(diffs) > 0.4]
for spot_indx in arr_:
spot = spots[spot_indx]
x1, y1, w, h = spot
spot_crop = frame[y1:y1 + h, x1:x1 + w, :]
spot_status = empty_or_not(spot_crop,reference_image)
spots_status[spot_indx] = spot_status
# Store the current frame as the previous frame for the next iteration
if frame_nmr % step == 0:
previous_frame = frame.copy()
# Given location
given_location = (x_given, y_given)
# Filter available spots and find the closest one to the given location
available_spots = [(spot_ids[tuple(spots[i])], spots[i]) for i, status in enumerate(spots_status) if status]
closest_spot_id = None
min_distance = float('inf')
for spot_id, spot in available_spots:
x1, y1, w, h = spot
spot_center = (x1 + w // 2, y1 + h // 2)
dist = distance.euclidean(given_location, spot_center)
if dist < min_distance:
min_distance = dist
closest_spot_id = spot_id
print("Closest available spot ID:", closest_spot_id)
# Check if the closest spot ID has changed and send data to the API
if closest_spot_id != prev_closest_spot_id:
if closest_spot_id is not None:
input_value = closest_spot_id
send_url = f"http://www.cmdcamp.nl/iot/send/{send_key}/{input_value}"
try:
response = requests.get(send_url)
response.raise_for_status() # Raise an exception for HTTP errors
data = response.json()
prev_closest_spot_id = closest_spot_id
except requests.exceptions.RequestException as e:
print('There was a problem with the fetch operation:', e)
# Draw rectangles for parking spots and a circle for the given location on the frame
for spot_indx, spot in enumerate(spots):
spot_status = spots_status[spot_indx]
x1, y1, w, h = spot
spot_id = spot_ids[tuple(spot)]
if spot_status:
frame = cv2.rectangle(frame, (x1, y1), (x1 + w, y1 + h), (0, 255, 0), 2)
else:
frame = cv2.rectangle(frame, (x1, y1), (x1 + w, y1 + h), (0, 0, 255), 2)
if spot_id == closest_spot_id:
cv2.circle(frame, (x1 + w // 2, y1 + h // 2), 20, (255, 192, 203), -1)
# Display the processed frame
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
cv2.imshow('frame', frame)
# Check for key press to exit the loop
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# Increment frame number
frame_nmr += 1
# Release video capture object and close all OpenCV windows
cap.release()
cv2.destroyAllWindows()
我诚实地尝试了很多东西,但我是一个业余编码员,但我需要这个项目
好吧,我修复了那些可能遇到同样问题的人,我只需要限制分辨率叹息......
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)