有人可以帮助opencv实时视频无法调整大小吗?

问题描述 投票:0回答:1

我有这段代码,应该使用二进制图像来帮助我在特定位置绘制方框,然后拍摄实时视频源,然后检测这些方框中的变化,我之前一直在使用剪辑进行测试,它与剪辑完美配合,但是每当我使用实时视频时,都会出现此错误:

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()

我诚实地尝试了很多东西,但我是一个业余编码员,但我需要这个项目

python opencv computer-vision
1个回答
0
投票

好吧,我修复了那些可能遇到同样问题的人,我只需要限制分辨率叹息......

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
© www.soinside.com 2019 - 2024. All rights reserved.