i'm trying to read videos with OpenCv python, but for some videos i can't do so, and i don't now why, or how to fix it (knowing that i can see the video on my pc )
here's the code i'm using :
# importing libraries
import cv2
video_path = 'C:/Videos/abc.avi'
cap = cv2.VideoCapture(video_path)
if (cap.isOpened() == False):
print("Error opening video")
while (cap.isOpened()):
ret, frame = cap.read()
if ret == True:
cv2.imshow('Frame', frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
How can i fix this, and make it work ?
i'm working on :
python version : 3.10.0 and openCv version : 4.7.0.68
Related
i cannot open or play any mp4 files that i uploaded on jupyter notebook. Beside that i cannot open any files with opencv. Here its an example code:
doc = cv2.VideoCapture("hero.mp4") #just a name of mp4 file that i uploaded on notebook
if cap.isOpened() == False:
print("the video cannot opened!")
while cap.isOpened() == True:
ret,frame = cap.read()
if ret == True:
cv2.imshow("frame",frame)
if waitKey(1) & 0xFF == ord("b"):
break
else:
break
cap.release()
cv2.destroyAllWindows()
I tried to open any video file using opencv on Jupyter notebook. But when i run this code the output is " The video cannot opened! "
Could y'all help me?
Thanks.
Given its link, I'd like to capture an online video (say from YouTube) for further processing without downloading it on the disk. What I mean by this is that I'd like to load it directly to memory whenever possible. According to these links:
http://answers.opencv.org/question/24012/reading-video-stream-from-ip-camera-in-opencv-java/#24013
http://answers.opencv.org/question/24154/how-to-using-opencv-api-get-web-video-stream/#24156
http://answers.opencv.org/question/133/how-do-i-access-an-ip-camera/
https://pypi.org/project/pafy/
it should be doable. My attempt looks like this:
import cv2
import pafy
vid = pafy.new("https://www.youtube.com/watch?v=QuELiw8tbx8")
vid_cap = cv2.VideoCapture()
vid_cap.open(vid.getbest(preftype="webm").url)
However it fails with an error
(python:12925): GLib-GObject-CRITICAL **: 14:48:56.168: g_object_set: assertion 'G_IS_OBJECT (object)' failed
False
How can I achieve my goal using python?
You can achieve this by using youtube-dl and ffmpeg:
Install the latest version of youtube-dl.
Then do sudo pip install --upgrade youtube_dl
Build ffmpeg with HTTPS support. You can do this by turning on the --enable-gnutls option.
Once the installations are complete, it's time to test the youtube-dl in terminal. We'll be using this youtube video for testing.
First we get the list of formats available for this video:
youtube-dl --list-formats https://www.youtube.com/watch?v=HECa3bAFAYk
Select a format code of your choice. I want the 144p resolution so I select 160.
Next we get the video url for our format of choice by:
youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk
https://r3---sn-4g5e6nz7.googlevideo.com/videoplayback?clen=184077&aitags=133%2C134%2C160%2C242%2C243%2C278&fvip=3&requiressl=yes&signature=5D21FFD906226C7680B26ACEF996B78B6A31F7C9.31B1115DB13F096AA5968DB2838E22A0D6A2EDCB&source=youtube&mn=sn-4g5e6nz7%2Csn-h0jeen7y&xtags=tx%3D9486108&itag=160&mime=video%2Fmp4&mt=1529091799&ms=au%2Conr&ei=XxckW-73GNCogQfqrryQAg&expire=1529113535&mm=31%2C26&c=WEB&keepalive=yes&id=o-AJExEG49WtIUkrF7OikaaGBCfKntDl75xCoO5_9cL-eP&ip=95.91.202.147&sparams=aitags%2Cclen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cxtags%2Cexpire&key=yt6&lmt=1526699176943888&dur=25.375&pl=22&gir=yes&mv=m&initcwndbps=1155000&ipbits=0&ratebypass=yes
Finally we can play this video url in either ffplay or vlc. But instead of copying and pasting, we can do this in one command:
ffplay -i $(youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk)
Now that we have confirmed that youtube-dl and ffmpeg works, we can write a Python script to process the frames in OpenCV. See this link for more Python options.
import cv2
import numpy as np
import youtube_dl
if __name__ == '__main__':
video_url = 'https://www.youtube.com/watch?v=HECa3bAFAYkq'
ydl_opts = {}
# create youtube-dl object
ydl = youtube_dl.YoutubeDL(ydl_opts)
# set video url, extract video information
info_dict = ydl.extract_info(video_url, download=False)
# get video formats available
formats = info_dict.get('formats',None)
for f in formats:
# I want the lowest resolution, so I set resolution as 144p
if f.get('format_note',None) == '144p':
#get the video url
url = f.get('url',None)
# open url with opencv
cap = cv2.VideoCapture(url)
# check if url was opened
if not cap.isOpened():
print('video not opened')
exit(-1)
while True:
# read frame
ret, frame = cap.read()
# check if frame is empty
if not ret:
break
# display frame
cv2.imshow('frame', frame)
if cv2.waitKey(30)&0xFF == ord('q'):
break
# release VideoCapture
cap.release()
cv2.destroyAllWindows()
First of all Update youtube-dl using the command pip install -U youtube-dl
Then use my VidGear Python Library, then automates the pipelining of YouTube Video using its URL address only. Here's a complete python example:
For VidGear v0.1.9 below:
# import libraries
from vidgear.gears import CamGear
import cv2
stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', y_tube = True, logging=True).start() # YouTube Video URL as input
# infinite loop
while True:
frame = stream.read()
# read frames
# check if frame is None
if frame is None:
#if True break the infinite loop
break
# do something with frame here
cv2.imshow("Output Frame", frame)
# Show output window
key = cv2.waitKey(1) & 0xFF
# check for 'q' key-press
if key == ord("q"):
#if 'q' key-pressed break out
break
cv2.destroyAllWindows()
# close output window
# safely close video stream.
stream.stop()
For VidGear v0.2.0 and above: (y_tube changed to stream_mode)
# import libraries
from vidgear.gears import CamGear
import cv2
stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', stream_mode = True, logging=True).start() # YouTube Video URL as input
# infinite loop
while True:
frame = stream.read()
# read frames
# check if frame is None
if frame is None:
#if True break the infinite loop
break
# do something with frame here
cv2.imshow("Output Frame", frame)
# Show output window
key = cv2.waitKey(1) & 0xFF
# check for 'q' key-press
if key == ord("q"):
#if 'q' key-pressed break out
break
cv2.destroyAllWindows()
# close output window
# safely close video stream.
stream.stop()
Code Source
If still get some error, raise an issue here in its GitHub repo.
Using pafy you can have a more elegant solution:
import cv2
import pafy
url = "https://www.youtube.com/watch?v=NKpuX_yzdYs"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
capture = cv2.VideoCapture()
capture.open(best.url)
success,image = capture.read()
while success:
cv2.imshow('frame', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
success,image = capture.read()
cv2.destroyAllWindows()
capture.release()
I want to highlight the issue I faced while running was a open-cv version problem, I was using OpenCV 3.4.x and the video feed was exiting before being read into the while loop, so, i upgraded my open cv to "opencv-contrib-python== 4.2.0.34".
Given its link, I'd like to capture an online video (say from YouTube) for further processing without downloading it on the disk. What I mean by this is that I'd like to load it directly to memory whenever possible. According to these links:
http://answers.opencv.org/question/24012/reading-video-stream-from-ip-camera-in-opencv-java/#24013
http://answers.opencv.org/question/24154/how-to-using-opencv-api-get-web-video-stream/#24156
http://answers.opencv.org/question/133/how-do-i-access-an-ip-camera/
https://pypi.org/project/pafy/
it should be doable. My attempt looks like this:
import cv2
import pafy
vid = pafy.new("https://www.youtube.com/watch?v=QuELiw8tbx8")
vid_cap = cv2.VideoCapture()
vid_cap.open(vid.getbest(preftype="webm").url)
However it fails with an error
(python:12925): GLib-GObject-CRITICAL **: 14:48:56.168: g_object_set: assertion 'G_IS_OBJECT (object)' failed
False
How can I achieve my goal using python?
You can achieve this by using youtube-dl and ffmpeg:
Install the latest version of youtube-dl.
Then do sudo pip install --upgrade youtube_dl
Build ffmpeg with HTTPS support. You can do this by turning on the --enable-gnutls option.
Once the installations are complete, it's time to test the youtube-dl in terminal. We'll be using this youtube video for testing.
First we get the list of formats available for this video:
youtube-dl --list-formats https://www.youtube.com/watch?v=HECa3bAFAYk
Select a format code of your choice. I want the 144p resolution so I select 160.
Next we get the video url for our format of choice by:
youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk
https://r3---sn-4g5e6nz7.googlevideo.com/videoplayback?clen=184077&aitags=133%2C134%2C160%2C242%2C243%2C278&fvip=3&requiressl=yes&signature=5D21FFD906226C7680B26ACEF996B78B6A31F7C9.31B1115DB13F096AA5968DB2838E22A0D6A2EDCB&source=youtube&mn=sn-4g5e6nz7%2Csn-h0jeen7y&xtags=tx%3D9486108&itag=160&mime=video%2Fmp4&mt=1529091799&ms=au%2Conr&ei=XxckW-73GNCogQfqrryQAg&expire=1529113535&mm=31%2C26&c=WEB&keepalive=yes&id=o-AJExEG49WtIUkrF7OikaaGBCfKntDl75xCoO5_9cL-eP&ip=95.91.202.147&sparams=aitags%2Cclen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cxtags%2Cexpire&key=yt6&lmt=1526699176943888&dur=25.375&pl=22&gir=yes&mv=m&initcwndbps=1155000&ipbits=0&ratebypass=yes
Finally we can play this video url in either ffplay or vlc. But instead of copying and pasting, we can do this in one command:
ffplay -i $(youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk)
Now that we have confirmed that youtube-dl and ffmpeg works, we can write a Python script to process the frames in OpenCV. See this link for more Python options.
import cv2
import numpy as np
import youtube_dl
if __name__ == '__main__':
video_url = 'https://www.youtube.com/watch?v=HECa3bAFAYkq'
ydl_opts = {}
# create youtube-dl object
ydl = youtube_dl.YoutubeDL(ydl_opts)
# set video url, extract video information
info_dict = ydl.extract_info(video_url, download=False)
# get video formats available
formats = info_dict.get('formats',None)
for f in formats:
# I want the lowest resolution, so I set resolution as 144p
if f.get('format_note',None) == '144p':
#get the video url
url = f.get('url',None)
# open url with opencv
cap = cv2.VideoCapture(url)
# check if url was opened
if not cap.isOpened():
print('video not opened')
exit(-1)
while True:
# read frame
ret, frame = cap.read()
# check if frame is empty
if not ret:
break
# display frame
cv2.imshow('frame', frame)
if cv2.waitKey(30)&0xFF == ord('q'):
break
# release VideoCapture
cap.release()
cv2.destroyAllWindows()
First of all Update youtube-dl using the command pip install -U youtube-dl
Then use my VidGear Python Library, then automates the pipelining of YouTube Video using its URL address only. Here's a complete python example:
For VidGear v0.1.9 below:
# import libraries
from vidgear.gears import CamGear
import cv2
stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', y_tube = True, logging=True).start() # YouTube Video URL as input
# infinite loop
while True:
frame = stream.read()
# read frames
# check if frame is None
if frame is None:
#if True break the infinite loop
break
# do something with frame here
cv2.imshow("Output Frame", frame)
# Show output window
key = cv2.waitKey(1) & 0xFF
# check for 'q' key-press
if key == ord("q"):
#if 'q' key-pressed break out
break
cv2.destroyAllWindows()
# close output window
# safely close video stream.
stream.stop()
For VidGear v0.2.0 and above: (y_tube changed to stream_mode)
# import libraries
from vidgear.gears import CamGear
import cv2
stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', stream_mode = True, logging=True).start() # YouTube Video URL as input
# infinite loop
while True:
frame = stream.read()
# read frames
# check if frame is None
if frame is None:
#if True break the infinite loop
break
# do something with frame here
cv2.imshow("Output Frame", frame)
# Show output window
key = cv2.waitKey(1) & 0xFF
# check for 'q' key-press
if key == ord("q"):
#if 'q' key-pressed break out
break
cv2.destroyAllWindows()
# close output window
# safely close video stream.
stream.stop()
Code Source
If still get some error, raise an issue here in its GitHub repo.
Using pafy you can have a more elegant solution:
import cv2
import pafy
url = "https://www.youtube.com/watch?v=NKpuX_yzdYs"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
capture = cv2.VideoCapture()
capture.open(best.url)
success,image = capture.read()
while success:
cv2.imshow('frame', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
success,image = capture.read()
cv2.destroyAllWindows()
capture.release()
I want to highlight the issue I faced while running was a open-cv version problem, I was using OpenCV 3.4.x and the video feed was exiting before being read into the while loop, so, i upgraded my open cv to "opencv-contrib-python== 4.2.0.34".
import numpy as np
import cv2
cap = cv2.VideoCapture("1.mp4")
while(cap.isOpened()):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Its throwing error
libv4l2: error getting capabilities: Inappropriate ioctl for device
VIDEOIO ERROR: V4L: device 1.mp4: Unable to query number of channels
after compiling.
I have a Windows 7 SP1 64 Bit machine with open cv2.4.9 installed and python 2.7.6 installed.
I use pre compiled version of opencv
The following code works perfectly for me
import cv2.cv as cv
import time
cv.NamedWindow("camera", 0)
capture = cv.CaptureFromCAM(0)
while True:
img = cv.QueryFrame(capture)
cv.ShowImage("camera", img)
if cv.WaitKey(10) == 27:
break
cv.DestroyAllWindows()
Now when I try to use this code
import cv2
import numpy as np
cam = cv2.VideoCapture(0)
s, img = cam.read()
winName = "Movement Indicator"
cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE)
while s:
cv2.imshow( winName,img )
s, img = cam.read()
key = cv2.waitKey(10)
if key == 27:
cv2.destroyWindow(winName)
break
print "Goodbye"
The window is opened , the camera is initialized (as camera lights are on) , but nothing is displayed and the window closes and the program exits.
WHERE am I going wrong??
QUESTION 2
Can any one also suggest me how to capture live video stream from my Linux machine 192.168.1.3 . The stream is being generated by ffmpeg.
The video stream can be opened in web browser. But I want to capture it with opencv and python.