Как я могу обнаружить черные рамки в Opencv с помощью Python

#python-3.x #opencv

#python-3.x #opencv

Вопрос:

У меня есть проект о данных из broadcasting.Я написал разделение видео на фрейм для python. Но я просто выясняю, что было бы лучше, если бы я мог снимать кадр видео только между черными кадрами.Возможно ли это? Я делюсь своим кодом;

 import cv2
import time
import os

def video_to_frames(input_loc, output_loc):
"""Function to extract frames from input video file
and save them as separate frames in an output directory.
Args:
    input_loc: Input video file.
    output_loc: Output directory to save the frames.
Returns:
    None
"""
try:
    os.mkdir(output_loc)
except OSError:
    pass
# Log the time
time_start = time.time()
# Start capturing the feed
cap = cv2.VideoCapture(input_loc)
# Find the number of frames
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
print ("Number of frames: ", video_length)
count = 0
print ("Converting video..n")
# Start converting the video
while cap.isOpened():
    # Extract the frame
    ret, frame = cap.read()
    # Write the results back to output location.
    cv2.imwrite(output_loc   "/%#05d.jpg" % (count 1), frame)
    count = count   1
    # If there are no more frames left
    if (count > (video_length-1)):
        # Log the time again
        time_end = time.time()
        # Release the feed
        cap.release()
        # Print stats
        print ("Done extracting frames.n%d frames extracted" % count)
        print ("It took %d seconds forconversion." % (time_end-time_start))
        break

input_loc = 'try.mp4'
output_loc = 'try/'
video_to_frames(input_loc, output_loc)
  

Ответ №1:

Поскольку изображения в OpenCV (или в вашем случае фреймы) представлены в виде массива numpy, их можно усреднить для низких значений (которые представляют черные рамки).

 import numpy as np

# converts the frame to gray scale for easier computation
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

if np.average(gray) < 20:
    # skips an iteration, so the frame isn't saved
    continue
  

В данном случае 20 это пороговое значение, используемое для «черных изображений». Если у вас есть более светлые, вы можете увеличить эту константу. Следовательно, ваш общий код должен выглядеть примерно так:

 import cv2
import numpy as np
import time
import os


def video_to_frames(input_loc, output_loc):
"""Function to extract frames from input video file
and save them as separate frames in an output directory.
Args:
    input_loc: Input video file.
    output_loc: Output directory to save the frames.
Returns:
    None
"""
try:
    os.mkdir(output_loc)
except OSError:
    pass


# Log the time
time_start = time.time()
# Start capturing the feed
cap = cv2.VideoCapture(input_loc)

# Find the number of frames
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
print("Number of frames: ", video_length)
count = 0

print("Converting video..n")
# Start converting the video
while cap.isOpened():
    # Extract the frame
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    if np.average(gray) < 20:
        # skips an iteration, so the frame isn't saved
        continue

    # Write the results back to output location.
    cv2.imwrite(output_loc   "/%#05d.jpg" % (count 1), frame)
    count = count   1

    # If there are no more frames left
    if count > video_length-1:
        # Log the time again
        time_end = time.time()
        # Release the feed
        cap.release()
        # Print stats
        print("Done extracting frames.n%d frames extracted" % count)
        print("It took %d seconds forconversion." % (time_end-time_start))
        break

input_loc = 'try.mp4'
output_loc = 'try/'
video_to_frames(input_loc, output_loc)

  

Ответ №2:

В моем случае у меня было несколько кадров с большей частью черного цвета, но не полностью черного. Они все еще были помечены как черные рамки np.average(image) < 20 . Вместо этого я использовал np.max(image) < 20 , который в моем случае сработал довольно хорошо. Как сказал Комрон, 20, возможно, потребуется скорректировать для вашего варианта использования.