পাইথন - ভিডিও ফ্রেমগুলি এক্সট্র্যাক্ট এবং সেভ করা


133

সুতরাং আমি এই টিউটোরিয়ালটি অনুসরণ করেছি তবে এটি কিছুই করার মতো বলে মনে হচ্ছে না। কেবল কিছুই না। এটি কয়েক সেকেন্ড অপেক্ষা করে এবং প্রোগ্রামটি বন্ধ করে দেয়। এই কোডটিতে কী ভুল?

import cv2
vidcap = cv2.VideoCapture('Compton.mp4')
success,image = vidcap.read()
count = 0
success = True
while success:
  success,image = vidcap.read()
  cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file
  if cv2.waitKey(10) == 27:                     # exit if Escape is hit
      break
  count += 1

এছাড়াও, মন্তব্যে এটি বলে যে এটি ফ্রেমগুলি 1000 এর মধ্যে সীমাবদ্ধ করে? কেন?

সম্পাদনা: আমি success = Trueপ্রথমে চেষ্টা করেছিলাম কিন্তু তাতে কোন লাভ হয়নি। এটি কেবল এমন একটি চিত্র তৈরি করেছে যা 0 বাইট ছিল।


1
এর মান কী success?
101

2
মান কী ? টাইপ বুলিয়ান হতে পারে, কিন্তু এটা Trueবা False?
That1Guy

1
হ্যাঁ, তবে আপনার মান কী? এটি ভুল হতে পারে যে ক্ষেত্রে আপনার প্রোগ্রামটি "কয়েক সেকেন্ড অপেক্ষা করে" বন্ধ হয়ে যাবে। অন্য কথায়, print successকোথাও যুক্ত করুন।
101

1
জোর করে বোঝা যায় না success; যদি এটি মিথ্যা হয় তবে এর অর্থ ভিডিও পঠন কোনও কারণে ব্যর্থ হয়েছে। আপনার প্রথমে সেই বিটটি কাজ করা দরকার।
101

1
আপনার রেড ব্যর্থ হচ্ছে। টিউটোরিয়ালের নির্দেশ অনুসারে আপনি কি পাইথন এবং ffmpeg দিয়ে ওপেনসিভি তৈরি করেছেন? brew install opencv --python27 --ffmpegআপনি যদি পাইথনের ভিন্ন সংস্করণ ব্যবহার করেন তবে এটির আপনার সংস্করণে পরিবর্তন করতে হবে।
Knells

উত্তর:


226

থেকে এখানে এই ডাউনলোড ভিডিও তাই আমরা পরীক্ষার জন্য একই ভিডিও ফাইল আছে। আপনার অজগর কোডের একই ডিরেক্টরিতে এমপি 4 ফাইল রয়েছে তা নিশ্চিত করুন। তারপরে একই ডিরেক্টরি থেকে পাইথন ইন্টারপ্রেটার চালানোর বিষয়টিও নিশ্চিত করুন।

তারপরে কোডটি সংশোধন করুন, খালি waitKeyযা সময় নষ্ট করে একটি উইন্ডো ছাড়া এটি কীবোর্ড ইভেন্টগুলি ক্যাপচার করতে পারে না। successএটি ফ্রেমগুলি সফলভাবে পড়ছে তা নিশ্চিত করার জন্য আমরা মানটি মুদ্রণ করি ।

import cv2
vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4')
success,image = vidcap.read()
count = 0
while success:
  cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file      
  success,image = vidcap.read()
  print('Read a new frame: ', success)
  count += 1

কিভাবে যে যায়?


4
এটি একটি খালি JPEG ফাইল সংরক্ষণ করে, এবং এটি ফেরৎRead a new frame: False

3
তার মানে ওপেনসিভি ভিডিওটি পড়তে পারে না। সম্ভবত এটি ffmpeg অ্যাক্সেস করতে পারে না। আপনি কোন ওএস ব্যবহার করছেন?
আগুন


3
গুগল আপনার ওপেনকভির নির্দিষ্ট সংস্করণটির জন্য নির্দেশাবলী এবং উইন্ডোজে কীভাবে ffmpeg এবং ওপেনসিভি পাইথন কাজ করবেন তা সম্পর্কে সুনির্দিষ্টভাবে অনুসরণ করুন।
আগুন

3
সুতরাং আমি এই প্রশ্নটি সামঞ্জস্যের সাথে আমার সমস্যার সমাধান করতে ব্যবহার করেছি। আমাকে ওপেনসিভি_ফাম্পেজি ৩০০.ডিলিতে ডিএলএল নামকরণ করতে হয়েছিল (যেহেতু ওপেনসিভি 2-এর পাইথন-ইনস্টলেশনটি 3.0.0.0 ছিল)। আমি এটিকে আমার পাইথন ডিরেক্টরিতে রেখেছি (সি: \ পাইথন 27)। আমার ffmpeg বা ওপেনকভির উইন্ডোজ সংস্করণ ইনস্টল করার দরকার নেই, তবে আমার ওপেনসিভি সহ যে ডিএলএল রয়েছে তা দরকার ছিল না, তবে এর পরে আমি বাকী ওপেনসিভিটি মুছে ফেললাম। যাইহোক, আমি এটি উত্তর হিসাবে নির্বাচন করব, তবে যে কেউ এটি পড়তে হবে অবশ্যই এই এসএসএনটিআইএল ডিএলএল সম্পর্কে জানতে হবে।

37

কিছুটা ভিন্ন ক্ষেত্রে এই প্রশ্নের (ও @ ব্যবহারকারী 2700065 দ্বারা উত্তর) প্রসারিত করার জন্য, যদি কেউ প্রতিটি ফ্রেমটি বের করতে না চায় তবে প্রতি সেকেন্ডে ফ্রেম বের করতে চায়। সুতরাং 1 মিনিটের ভিডিও 60 ফ্রেম (চিত্র) দেবে।

import sys
import argparse

import cv2
print(cv2.__version__)

def extractImages(pathIn, pathOut):
    count = 0
    vidcap = cv2.VideoCapture(pathIn)
    success,image = vidcap.read()
    success = True
    while success:
        vidcap.set(cv2.CAP_PROP_POS_MSEC,(count*1000))    # added this line 
        success,image = vidcap.read()
        print ('Read a new frame: ', success)
        cv2.imwrite( pathOut + "\\frame%d.jpg" % count, image)     # save frame as JPEG file
        count = count + 1

if __name__=="__main__":
    a = argparse.ArgumentParser()
    a.add_argument("--pathIn", help="path to video")
    a.add_argument("--pathOut", help="path to images")
    args = a.parse_args()
    print(args)
    extractImages(args.pathIn, args.pathOut)

আমি ব্যবহার করছি opencv-2.4.9, সুতরাং পরিবর্তে cv2.CAP_PROP_POS_MSECআমাকে ব্যবহার করতে হয়েছিলcv2.cv.CAP_PROP_POS_MSEC
প্রতীক কুমার

1
আমি কীভাবে কোডটি পরিবর্তন করতে পারি যদি আমি প্রতি 5 সেকেন্ডে ফ্রেম চাই?
সৌম্য বোড়াল

1
@ সৌম্যবোরালcount = count + 5
ভূষণ বাবর

@ ভূষণবাবার cv2.imwrite()লুপের cv2.imread()আগে যেহেতু ফোন করেছিলেন সেদিকে কী উচিত হবে না ?
mLstudent33

@ mLstudent33 দুঃখিত, আপনাকে পাবেন না, দয়া করে বিস্তারিত বলুন।
ভূষণ বাবর

12

এটি জিএস শকড থেকে পাইথন ৩.x এর পূর্ববর্তী উত্তরের একটি টুইট, আমি এটি মন্তব্যটিতে পোস্ট করব, তবে যথেষ্ট সুনাম নেই

import sys
import argparse

import cv2
print(cv2.__version__)

def extractImages(pathIn, pathOut):
    vidcap = cv2.VideoCapture(pathIn)
    success,image = vidcap.read()
    count = 0
    success = True
    while success:
      success,image = vidcap.read()
      print ('Read a new frame: ', success)
      cv2.imwrite( pathOut + "\\frame%d.jpg" % count, image)     # save frame as JPEG file
      count += 1

if __name__=="__main__":
    print("aba")
    a = argparse.ArgumentParser()
    a.add_argument("--pathIn", help="path to video")
    a.add_argument("--pathOut", help="path to images")
    args = a.parse_args()
    print(args)
    extractImages(args.pathIn, args.pathOut)

11

এটি ফাংশন যা বেশিরভাগ ভিডিও ফর্ম্যাটগুলিকে ভিডিওতে থাকা ফ্রেমের সংখ্যায় রূপান্তর করবে। এটা তোলে উপর কাজ করে Python3দিয়েOpenCV 3+

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

if __name__=="__main__":

    input_loc = '/path/to/video/00009.MTS'
    output_loc = '/path/to/output/frames/'
    video_to_frames(input_loc, output_loc)

এটি সমর্থন .mtsও স্বাভাবিক ফাইলের মত .mp4এবং .avi। চেষ্টা করা হয়েছে এবং .mtsফাইল পরীক্ষা করা হয়েছে । একটি যাদুমন্ত্র মত কাজ করে.


8

ভিডিওতে ফ্রেমগুলিকে কীভাবে রূপান্তর করা যায় সে সম্পর্কে অনেক গবেষণা করার পরে আমি এই ফাংশনটি তৈরি করেছি আশা করি এটি সহায়তা করবে। আমাদের এটির জন্য ওপেনসিভি প্রয়োজন:

import cv2
import numpy as np
import os

def frames_to_video(inputpath,outputpath,fps):
   image_array = []
   files = [f for f in os.listdir(inputpath) if isfile(join(inputpath, f))]
   files.sort(key = lambda x: int(x[5:-4]))
   for i in range(len(files)):
       img = cv2.imread(inputpath + files[i])
       size =  (img.shape[1],img.shape[0])
       img = cv2.resize(img,size)
       image_array.append(img)
   fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
   out = cv2.VideoWriter(outputpath,fourcc, fps, size)
   for i in range(len(image_array)):
       out.write(image_array[i])
   out.release()


inputpath = 'folder path'
outpath =  'video file path/video.mp4'
fps = 29
frames_to_video(inputpath,outpath,fps)

আপনার নিজস্ব স্থানীয় অবস্থান অনুযায়ী fps (প্রতি সেকেন্ড ফ্রেম), ইনপুট ফোল্ডার পাথ এবং আউটপুট ফোল্ডারের পাথের মান পরিবর্তন করুন


ফাইল.সর্ট (কী = ল্যাম্বদা এক্স: ইন (এক্স [5: -4])) উপরে লাইন যুক্ত করা হচ্ছে যা স্ট্রিং নয় বরং সংখ্যা অনুসারে ফ্রেমগুলি সাজানোর জন্য সহায়তা করে: প্রাথমিকভাবে ফ্রেম 1.jpg অনুসরণ করেছিল ফ্রেম 10.jpg ফ্রেম 2.jpg নয়, উপরের লাইনটি এতে নম্বর অনুসারে ফাইলগুলি সাজায়।
পূজা শর্মা

3
ভিডিও থেকে ফ্রেমে প্রশ্ন ছিল
সন্তোষ ধইপুলে চন্দ্রকান্ত

কোনও কারণে ভিডিওটি আমার জন্য সংরক্ষণ করা হচ্ছে না
রক্ষা

7

পূর্ববর্তী উত্তরগুলি প্রথম ফ্রেমটি হারিয়েছে। এবং ইমেজগুলি ফোল্ডারে রেখে ভাল লাগবে।

# create a folder to store extracted images
import os
folder = 'test'  
os.mkdir(folder)
# use opencv to do the job
import cv2
print(cv2.__version__)  # my version is 3.1.0
vidcap = cv2.VideoCapture('test_video.mp4')
count = 0
while True:
    success,image = vidcap.read()
    if not success:
        break
    cv2.imwrite(os.path.join(folder,"frame{:d}.jpg".format(count)), image)     # save frame as JPEG file
    count += 1
print("{} images are extacted in {}.".format(count,folder))

উপায় দ্বারা, আপনি ভিএলসি দ্বারা ফ্রেম ইঁদুর ই পরীক্ষা করতে পারেন । উইন্ডোগুলিতে যান -> মিডিয়া তথ্য -> কোডেক বিশদ


নিষ্কাশন করার সময় ফ্রেমের হার বাড়ানোর কোনও উপায় আছে কি?
প্রতীক খাদলোয়া

না। যখন কোনও ভিডিও তৈরি হয় তখন ফ্রেমের হার স্থির হয়। আপনি এর চেয়ে বেশি উত্তোলন করতে পারবেন না।
ইউচাও জিয়াং

কি আশ্চর্য উত্তর। আমার জন্য নিখুঁতভাবে কাজ করেছেন। কোডটিতে লুপটি টুইঙ্ক করার কোনও উপায় থাকবে যাতে আমি কেবলমাত্র একটি নির্দিষ্ট পরিসর থেকে ফ্রেম পেতে পারি, যেমন ফ্রেম 120 - 160? ধন্যবাদ!
বোভেন লিউ

আপনি যে ফ্রেমগুলি বের করতে চান তা নির্দিষ্ট করতে আপনি পরিবর্তনশীল কাউন্টটি ব্যবহার করতে পারেন।
ইউচাও জিয়াং

আমি ভিডিওটি থেকে নিষ্কাশন করতে চাইলে আমাকে কী করতে হবে বলুন ভিডিওর সূচনা হতে শুরু করে ভিডিওর শেষ পর্যন্ত সময় মতো নিখরচায় অবস্থান করা 15 ফ্রেমগুলি বলুন? আমি ব্যবহার করতে হবে জানতে পেরেছি cv.CAP_PROP_POS_AVI_RATIO, কিন্তু কিভাবে জানি না। tnx
নেস্ট্যাক

7

এই কোডটি ভিডিও থেকে ফ্রেমগুলি বের করে এবং ফ্রেমগুলি .jpg ফোমেটে সংরক্ষণ করে

import cv2
import numpy as np
import os

# set video file path of input video with name and extension
vid = cv2.VideoCapture('VideoPath')


if not os.path.exists('images'):
    os.makedirs('images')

#for frame identity
index = 0
while(True):
    # Extract images
    ret, frame = vid.read()
    # end of frames
    if not ret: 
        break
    # Saves images
    name = './images/frame' + str(index) + '.jpg'
    print ('Creating...' + name)
    cv2.imwrite(name, frame)

    # next frame
    index += 1

4

আমি অ্যানাকোন্ডার স্পাইডার সফটওয়্যারটির মাধ্যমে পাইথন ব্যবহার করছি। @ গশকড দ্বারা এই থ্রেডের প্রশ্নের তালিকাভুক্ত মূল কোডটি ব্যবহার করে কোডটি কাজ করে না (পাইথন এমপি 4 ফাইলটি পড়বে না)। সুতরাং আমি ওপেনসিভি 3.2 ডাউনলোড করেছি এবং "ওপেনসিভি_ফম্প্পেগ 320.dll" এবং "ওপেনসিভি_ফ্যাম্পেজি 320_64.dll" অন "ফোল্ডার" থেকে অনুলিপি করেছি। আমি এই উভয় dll ফাইল আনাকোনাকার "Dlls" ফোল্ডারে আটকালাম।

অ্যানাকোন্ডায় একটি "প্যাকস" ফোল্ডারও রয়েছে ... আমি অ্যানাকোন্ডা "প্যাকস" ফোল্ডারে যে ডাউনলোড করেছি তা পুরো "ওপেনসিভি 3.2" ফোল্ডারটি অনুলিপি করে আটকিয়েছি।

অবশেষে, অ্যানাকোন্ডার একটি "লাইব্রেরি" ফোল্ডার রয়েছে যার একটি "বিন" সাবফোল্ডার রয়েছে। আমি এই ফোল্ডারে "opencv_ffmpeg320.dll" এবং "opencv_ffmpeg320_64.dll" ফাইলগুলি পেস্ট করেছি।

স্পাইডার বন্ধ এবং পুনরায় চালু করার পরে কোডটি কাজ করেছিল। তিনটি পদ্ধতির মধ্যে কোনটি কাজ করেছে তা আমি নিশ্চিত নই এবং আমি ফিরে গিয়ে এটি বের করতে খুব অলস। তবে এটি কাজ করে, চিয়ার্স!


4

এই ফাংশনটি 1 এফপিএস সহ ভিডিও থেকে চিত্রগুলি বের করে, এটি শেষ ফ্রেমে চিহ্নিত করে এবং পড়া বন্ধ করে দেয়:

import cv2
import numpy as np

def extract_image_one_fps(video_source_path):

    vidcap = cv2.VideoCapture(video_source_path)
    count = 0
    success = True
    while success:
      vidcap.set(cv2.CAP_PROP_POS_MSEC,(count*1000))      
      success,image = vidcap.read()

      ## Stop when last frame is identified
      image_last = cv2.imread("frame{}.png".format(count-1))
      if np.array_equal(image,image_last):
          break

      cv2.imwrite("frame%d.png" % count, image)     # save frame as PNG file
      print '{}.sec reading a new frame: {} '.format(count,success)
      count += 1

0

নিম্নলিখিত স্ক্রিপ্ট ফোল্ডারে সমস্ত ভিডিওর প্রতি অর্ধেক সেকেন্ডে ফ্রেমগুলি বের করবে। (অজগর 3.7 এ কাজ করে)

import cv2
import os
listing = os.listdir(r'D:/Images/AllVideos')
count=1
for vid in listing:
    vid = r"D:/Images/AllVideos/"+vid
    vidcap = cv2.VideoCapture(vid)
    def getFrame(sec):
        vidcap.set(cv2.CAP_PROP_POS_MSEC,sec*1000)
        hasFrames,image = vidcap.read()
        if hasFrames:
            cv2.imwrite("D:/Images/Frames/image"+str(count)+".jpg", image) # Save frame as JPG file
        return hasFrames
    sec = 0
    frameRate = 0.5 # Change this number to 1 for each 1 second
    
    success = getFrame(sec)
    while success:
        count = count + 1
        sec = sec + frameRate
        sec = round(sec, 2)
        success = getFrame(sec)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.