Detect media resolution change in video - python

I tried to search in SO but could not find.I want to iterate video file frame by frame and want to detect if there is any point when resolution of two consecutive frame changes. The desired functionality in pseudocode:
resolution1 = videoFile[0]->resolution
resolution2 = 0;
for frame in videoFile[1:]:
resolution2 = frame->resolution
if (resolution1 != resolution2):
print 'Changes occured'
else:
resolution1 = resolution2
Please give me the name of a library to implement them, I have tried and read documentation of OpenCV and PiCamera.
Thanks in advance

You should use OpenCV to iterate through each frame. This should print "Changes occured" whenever the video changes resolution:
import cv2
capture1 = cv2.VideoCapture('videoname') #Open the video
ret, frame = capture1.read() #Read the first frame
resolution1 = frame.shape #Get resolution
while capture1.isOpened():
ret, frame = capture1.read() #Read the next frame
if ret == False or frame == None:
break #Quit if video ends
resolution2 = frame.shape #Get the new resolution
if resolution1 != resolution2:
print 'Changes occured'
#Change resolution1 to resolution2 so that the new resolutions are
#compared with resolution2, not resolution1.
resolution1 = resolution2

Related

When using VideoWriter in opencv-python the output video length is 0

I'm trying to read a video, put some shapes on it and write it out using opencv-python (using VideoWriter class):
def Mask_info(path):
"""This function will mask the information part of the video"""
video = cv.VideoCapture(path)
framenum = video.get(cv.CAP_PROP_FRAME_COUNT)
fps = video.get(cv.CAP_PROP_FPS)
fourcc = cv.VideoWriter_fourcc(*"vp09")
width = int(video.get(cv.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv.CAP_PROP_FRAME_HEIGHT))
size = (width,height)
if (video.isOpened ==False ):
print("Error while reading the file.")
result = cv.VideoWriter("masked_video.mp4",fourcc,fps,size)
while(True):
isTrue,frame = video.read()
cv.rectangle(frame,(65,0),(255,10),(0,0,0),-1)
cv.rectangle(frame,(394,0),(571,10),(0,0,0),-1)
if isTrue == True:
result.write(frame)
cv.imshow("Masked Video",frame)
if cv.waitKey(1) & 0xFF == ord("d"):
break
else:
break
video.release()
result.release()
cv.destroyAllWindows()
Mask_info("samplesound.webm")
The problem is that the output video length is zero, while the input video is 10 seconds.
To elaborate on my comment above:
You should verify that video.read() returns any valid frame.
It could be that due to path or other issue the VideoCapture failed to open the input file.
You attempt to draw the rectangles (using cv.rectangle) before the if that checks whether you have a valid frame.
But if video.read() failed (e.g. when reaching the end of the input) frame will be None. Then cv.rectangle will throw an exception causing the program to terminate without flushing and closing the output file.
Instead you should do the drawings inside the isTrue == True branch of the if:
if isTrue == True:
cv.rectangle(frame,(65,0),(255,10),(0,0,0),-1)
cv.rectangle(frame,(394,0),(571,10),(0,0,0),-1)
result.write(frame)
# ...

How to save one image every 25 frames into a folder

I am trying to write images from IP camera into a new folder. However, as for now, it is writing for each frame. How to only save one image every 25 frames? This is my current code:
import cv2
import os
folder = 'test_python'
os.mkdir(folder)
url = "rtsp://axis-media/media.amp"
count = 0
cap = cv2.VideoCapture(url)
while True:
# read next frame
ret, frame = cap.read()
cv2.imshow('frame', frame)
cv2.imwrite(os.path.join(folder, "frame{:d}.jpg".format(count)), frame)
count += 1
The trivial solution would be:
if count % 25 == 0:
cv2.imwrite(...)

Writing and Reading video without saving in opencv

I want to read a video after I write it with cv2.VideoWriter without saving the video.
For example:
video = cv2.VideoWriter('using.mp4', cv2.VideoWriter_fourcc(*'MJPG'), 10, size)
Now, after writing this cv2.VideoWriter object, is it possible to read it likevideo.read(), but since read() is a function of cv2.VideoCapture and it will throw an error
Exception has occurred: AttributeError
'cv2.VideoWriter' object has no attribute 'read'
So, is there possible way of reading the cv2.VideoWriter?
An alternative to reading frames from the video writer, is to save the frames in a list instead of saving each frame in the the loop. when you finished, you can write them outside the loop and have the save affect as video.read()
video = cv2.VideoWriter('using.mp4', cv2.VideoWriter_fourcc(*'MJPG'), 10, size)
for frame in frames:
writer.write(frame)
for frame in frames:
# do other stuff here
detailed example (Notice i changed the fourcc - your example didnt work for me)
import cv2
def cam_test(port: int = 0) -> None:
frames = []
cap = cv2.VideoCapture(port)
if not cap.isOpened(): # Check if the web cam is opened correctly
print("failed to open cam")
else:
print('cam opened on port {}'.format(port))
for i in range(10 ** 10):
success, cv_frame = cap.read()
if not success:
print('failed to capture frame on iter {}'.format(i))
break
frames.append(cv_frame)
cv2.imshow('Input', cv_frame)
k = cv2.waitKey(1)
if k == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
# Now you have the frames at hand
if len(frames) > 0:
# if you want to write them
size = (frames[0].shape[1], frames[0].shape[0])
video = cv2.VideoWriter(
filename='using.mp4',
fourcc=cv2.VideoWriter_fourcc(c1='m', c2='p', c3='4', c4='v'),
fps=10,
frameSize=size
)
for frame in frames:
video.write(frame)
# and to answer your question, you wanted to do video.read() which would have gave you frame by frame
for frame in frames:
pass # each iteration is like video.read() if video.read() was possible
return
if __name__ == '__main__':
cam_test()

How to restrict a camera on capturing and not capturing images on python, opencv?

I have a camera that faces an LED sensor that I want to restrict on capturing images when the object is in sight otherwise not capturing. I will designate a point or region where the color pixels will change as an object arrives it will wait for 3sec and then capture. Thereafter it will not capture the same object if it still remains in the designated region. Here are my codes.
import cv2
import numpy as np
import os
os.chdir('C:/Users/Man/Desktop')
previous_flag = 0
current_flag = 0
a = 0
video = cv2.VideoCapture(0)
while True:
ret, frame = video.read()
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cv2.imshow('Real Time', rgb)
cv2.waitKey(1)
if(rgb[400, 200, 0]>200): # selecting a point that will change in terms of pixel values
current_flag = 0
previous_flag = current_flag
print('No object Detected')
else: # object arrived
current_flag = 1
change_in_flags = current_flag - previous_flag
if(change_in_flags==1):
time.sleep(3)
cv2.imwrite('.trial/cam+str(a).jpg', rgb)
a += 1
previous_flag = current_flag
video.release()
cv2.destroyAllWindows()
When I implement the above program, for the first case (if) it prints several lines of No object Detected.
How can I reduce those sequentially printed lines for No object Detected statement? So that the program can just print one line without repetition.
I also tried to add a while loop to keep the current status true after a+=1 like:
while True:
previous_flag = current_flag
continue
It worked but the system became so slow is there any way to avoid such a while loop such that the system becomes faster? Any advice on that
import cv2
import numpy as np
import os
os.chdir('C:/Users/Man/Desktop')
state1=0
a = 0
video = cv2.VideoCapture(0)
while True:
ret, frame = video.read()
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cv2.imshow('Real Time', rgb)
cv2.waitKey(1)
if(rgb[400, 200, 0]>200): # selecting a point that will change in terms of pixel values
if(state1 == 0):
print('No object Detected')
state1=1
else: # object arrived
time.sleep(1)
if(state1==1)
print('Object is detected')
cv2.imwrite('./trial/cam+str(a).jpg', rgb)
a += 1
state1=0
video.release()
cv2.destroyAllWindows()

OpenCV - Save video segments based on certion condition

Aim : Detect the motion and save only the motion periods in files with names of the starting time.
Now I met the issue about how to save the video to the files with video starting time.
What I tested :
I tested my program part by part. It seems that each part works well except the saving part.
Running status: No error. But in the saving folder, there is no video. If I use a static saving path instead, the video will be saved successfully, but the video will be override by the next video. My codes are below:
import cv2
import numpy as np
import time
cap = cv2.VideoCapture( 0 )
bgst = cv2.createBackgroundSubtractorMOG2()
fourcc=cv2.VideoWriter_fourcc(*'DIVX')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
n = "start_time"
while True:
ret, frame = cap.read()
dst = bgst.apply(frame)
dst = np.array(dst, np.int8)
if np.count_nonzero(dst)>3000: # use this value to adjust the "Sensitivity“
print('something is moving %s' %(time.ctime()))
path = r'E:\OpenCV\Motion_Detection\%s.avi' %n
out = cv2.VideoWriter( path, fourcc, 50, size )
out.write(frame)
key = cv2.waitKey(3)
if key == 32:
break
else:
out.release()
n = time.ctime()
print("No motion Detected %s" %n)
What I meant is:
import cv2
import numpy as np
import time
cap = cv2.VideoCapture( 0 )
bgst = cv2.createBackgroundSubtractorMOG2()
fourcc=cv2.VideoWriter_fourcc(*'DIVX')
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
path = r'E:\OpenCV\Motion_Detection\%s.avi' %(time.ctime())
out = cv2.VideoWriter( path, fourcc, 16, size )
while True:
ret, frame = cap.read()
dst = bgst.apply(frame)
dst = np.array(dst, np.int8)
for i in range(number of frames in the video):
if np.count_nonzero(dst)<3000: # use this value to adjust the "Sensitivity“
print("No Motion Detected")
out.release()
else:
print('something is moving %s' %(time.ctime()))
#label each frame you want to output here
out.write(frame(i))
key = cv2.waitKey(1)
if key == 32:
break
cap.release()
cv2.destroyAllWindows()
If you see the code there will be a for loop, within which the process of saving is done.
I do not know the exact syntax involving for loop with frames, but I hope you have the gist of it. You have to find the number of frames present in the video and set that as the range in the for loop.
Each frame gets saved uniquely (see the else condition.) As I said I do not know the syntax. Please refer and follow this procedure.
Cheers!

Categories

Resources