openCV imwrite writing 0 kb image frames - python-2.7

I am running the below code to convert video into frames. Problem is it is creating Image files with 0 KB size and when I open it is not showing anything.. I don't understand what is creating the problem. Do I need to install any Image codecs?
'''
Using OpenCV takes a mp4 video and produces a number of images. I am using OpenCV 3.3.0 version and Python 2.7
Which will produce a folder called data with the images, There will be 2000+ images for example.mp4.
'''
import cv2
import numpy as np
import os
# Playing video from file:
try:
cap = cv2.VideoCapture('aa.mkv')
except:
print "Could not open video file"
raise
print cap.grab()
try:
if not os.path.exists('data'):
os.makedirs('data')
except OSError:
print ('Error: Creating directory of data')
currentFrame = 0
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
if not frame is None:
# Saves image of the current frame in jpg file
name = './data/frame' + str(currentFrame) + '.jpg'
print ('Creating...' + name)
cv2.imwrite(name, frame)
#cv2.imshow(name, frame)
else:
break
# To stop duplicate images
currentFrame += 1
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

You are not using imwrite function to write frames. Also your imshow function name is misspelled. I have made changes in your code. Try this:
import cv2
import numpy as np
import os
# Playing video from file:
cap = cv2.VideoCapture('aa.mkv')
try:
if not os.path.exists('data'):
os.makedirs('data')
except OSError:
print ('Error: Creating directory of data')
currentFrame = 0
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
if not frame is None:
# Saves image of the current frame in jpg file
name = './data/frame' + str(currentFrame) + '.jpg'
print ('Creating...' + name)
cv2.imwrite(name, frame)
cv2.imshow(name, frame)
else:
break
# To stop duplicate images
currentFrame += 1
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

Related

Converting a sequence of ppm images to video with python

I'm trying to make a video out of ppm images using IPython (python 2.7).
I wrote this code :
import cv2
import glob
img1 = cv2.imread('C:/Users/Joseph/image0.ppm')
height, width, layers = img1.shape
video1 = cv2.VideoWriter('video1.avi', -1, 1, (width, height))
filenames = glob.glob('C:/Users/Joseph/*.ppm')
for filename in filenames:
print(filename)
img = cv2.imread(filename)
video1.write(img)
cv2.destroyAllWindows()
video1.release()
The video is created but is empty size=0B and it cannot be opened.
There is no error message.
I suspect the problem is the writing of the location, since print(filename) yields :
C:/Users/Joseph\image0.ppm
C:/Users/Joseph\image1.ppm
C:/Users/Joseph\image2.ppm
C:/Users/Joseph\image2.ppm
instead of what I had expected : C:/Users/Joseph/image0.ppm
Could you help me please?
EDIT: The type of file is type: GIMP 2.10.14 (.ppm). Could the issue be connected to this type of ppm ?
EDIT 2: It seems that the issue is not connected directly to .ppm.
Indeed, I tried (taking into account the answer of Rotem) :
import cv2
import glob
i = cv2.imread('C:/Users/Joseph/image0.ppm')
cv2.imwrite('C:/Users/Joseph/image.jpg',i)
img1 = cv2.imread('C:/Users/Joseph/image.jpg')
height, width, layers = img1.shape
# Set FOURCC code to '24BG' - '24BG' is used for creating uncompressed raw video
video1 = cv2.VideoWriter('video1.avi', cv2.VideoWriter_fourcc('D','I','B',' '), 1, (width, height))
filenames = glob.glob('C:/Users/Joseph/*.ppm')
try:
for filename in filenames:
print(filename)
img = cv2.imread(filename)
cv2.imwrite('C:/Users/Joseph/a.jpg',img)
img=cv2.imread('C:/Users/Joseph/a.jpg')
# Display input image for debugging
cv2.imshow('img', img)
cv2.waitKey(1000)
video1.write(img)
except:
print('An error occurred.')
cv2.destroyAllWindows()
video1.release()
And it doesn't work either. And I don't get any image displayed.
so it seems that it's an error in my cv2 for video. The jpg is well created.
EDIT : The solution.
In the spirit of the answer of rotem, I tried : cv2.VideoWriter_fourcc('M','J','P','G') and it worked !
There are multiple reasons for getting an empty video file, but the path looks correct.
In Windows system C:/Users/Joseph\image0.ppm and C:/Users/Joseph/image0.ppm are the same.
Manually delete video1.avi file, just to make sure the file is not locked.
I think the issue involved video codec, but I can't be sure about it.
in the command video1 = cv2.VideoWriter('video1.avi', -1, 1, (width, height)), the second parameter is a FOURCC code that selects the video codec for the video encoder.
When setting the value to -1, a dialog box is opened letting you select the codec.
In older versions of OpenCV it's not always working.
Try setting the FOURCC to 'DIB ', applies "Basic Windows bitmap format".
Use it for creating raw (uncompressed) AVI video file.
Here is the code:
import cv2
import glob
img1 = cv2.imread('C:/Users/Joseph/image0.ppm')
height, width, layers = img1.shape
# Set FOURCC code to '24BG' - '24BG' is used for creating uncompressed raw video
video1 = cv2.VideoWriter('video1.avi', cv2.VideoWriter_fourcc('D','I','B',' '), 1, (width, height))
filenames = glob.glob('*.ppm')
try:
for filename in filenames:
print(filename)
img = cv2.imread(filename)
# Display input image for debugging
cv2.imshow('img', img)
cv2.waitKey(1000)
video1.write(img)
except:
print('An error occurred.')
cv2.destroyAllWindows()
video1.release()
I added cv2.imshow('img', img) to help you debugging the problem, in case it's not a codec issue.
Make sure you are not getting any exceptions.
Please let me no if my answer solves your problem.

I am running OpenCV for facial recognition on a Raspberry Pi with a webcam, but it has stopped working without any change in my code

I am trying to run a facial recognition service on my Raspberry Pi, but it has suddenly stopped detecting faces
I am using python-opencv for this and the last time I tested it everything worked fine. The below code is for the the training the system on new faces
`
import cv2
import os
import numpy as np
from PIL import Image
import sqlite3
recognizer = cv2.createLBPHFaceRecognizer()
detector= cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
cam = cv2.VideoCapture(0)
con = sqlite3.connect('Users.db')
cur = con.cursor()
Id=raw_input('Enter your id: ')
name=raw_input('Enter your name: ')
sampleNum=0
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
#incrementing sample number
sampleNum=sampleNum+1
#saving the captured face in the dataset folder
cv2.imwrite("dataSet/User."+Id +'.'+ str(sampleNum) + ".jpg", gray[y:y+h,x:x+w])
cv2.imshow('frame',img)
#wait for 100 miliseconds
if cv2.waitKey(100) & 0xFF == ord('q'):
break
# break if the sample number is more than 20
elif sampleNum>30:
break
cam.release()
cv2.destroyAllWindows()
def getImagesAndLabels(path):
#get the path of all the files in the folder
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
#create empth face list
faceSamples=[]
#create empty ID list
Ids=[]
#now looping through all the image paths and loading the Ids and the images
for imagePath in imagePaths:
#loading the image and converting it to gray scale
pilImage=Image.open(imagePath).convert('L')
#Now we are converting the PIL image into numpy array
imageNp=np.array(pilImage,'uint8')
#getting the Id from the image
Id=int(os.path.split(imagePath)[-1].split(".")[1])
# extract the face from the training image sample
faces=detector.detectMultiScale(imageNp)
#If a face is there then append that in the list as well as Id of it
for (x,y,w,h) in faces:
faceSamples.append(imageNp[y:y+h,x:x+w])
Ids.append(Id)
return faceSamples,Ids
os.system("sudo rm trainer/trainer.yml")
faces,Ids = getImagesAndLabels('dataSet')
recognizer.train(faces, np.array(Ids))
recognizer.save('trainer/trainer.yml')
`
Normally it would open a window and show 30 photos in succession of the user's face, but now nothing shows up after it asks for a name. I have run other OpenCV applications and it can find faces in static images.
I had to replace the haar_cascade_frontalface.xml file

video is saving but showing 0 KB only. What is the probable error in these code of OpenCv

I am trying to save video using videocapture object in openCv using python. But after pressing 'q' the video is saved as 'output.avi' but its size is showing as 0 KB. Need your help, not able to find out the error.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
#1.2. Gui Features in OpenCV 25
#OpenCV-Python Tutorials Documentation, Release 1
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
Here you need to play with fourCC code
FourCC code is passed as cv2.VideoWriter_fourcc('M','J','P','G') or cv2.VideoWriter_fourcc(*'MJPG) for MJPG.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
# Define the codec and create VideoWriter object
#fourcc = cv2.cv.CV_FOURCC(*'DIVX')
#out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,0)
# write the flipped frame
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
For more read, OpenCV saving doc and FourCC doc
It maybe that the codecs for XVID is not properly installed.
(If you are using Jupyter Notebook, there would be jupyter logs begin with OpenCV: FFMPEG: ...)
If you are on linux, you could try to use the cv2.VideoWriter_fourcc(*'mp4v') as below:
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output.mp4', -1, 20.0, (640,480))
Notice, the extension mp4 matters! Should choose the right extension matching the codec.

Can not Read or Play a Video in OpenCV+Python using VideoCapture

import cv2
import numpy as np
cap = cv2.VideoCapture('traffic.avi')
retval, frame = cap.read()
print retval
================ RESTART: J:\Python For DIP\traffic_video.py ================
False
>>>
The Value of retval is always False, which means the video is not read by the command. It must be True to read frames. I don't know what to do. However when I use my default webcam it turns to be True. I tried many videos and the same problem appears. Note: I have installed the ffmpeg correctly.
Note: This is not the full code, in this step I am only validating cap.read() either True or False
This method is guaranteed 100%
first of all check your version of OpenCV, say for instance 2.4.11. you can check it by typing the following commands in your Python Shell:
>>> from cv2 import __version__
>>> __version__
'2.4.11'
>>>
Then go to C:\opencv\build\x86\vc12\bin and copy opencv_ffmpeg2411.dll.
Finally go to root directory of Python ex: C:\Python27 and paste opencv_ffmpeg2411.dll in it
check the name of the file opencv_ffmpeg2411.dll, whether the version
of opencv is written or not, if not do the following
opencv_ffmpeg(version of your opencv without dots).dll
After that create a new Python file and copy this code and paste it loading your own video
import numpy as np
import cv2
# Capture video from file
cap = cv2.VideoCapture('your video')
while True:
ret, frame = cap.read()
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
you will have an output video for example like this:
Result
Finding the root directory of Python can be a little tricky. I am using an Enthought distribution and, at first, pasted the opencv_ffmpeg file into the wrong Python directory.
WRONG:
C:\Users\USERNAME\AppData\Local\Programs\Python\Python35-32
RIGHT:
C:\Users\USERNAME\AppData\Local\Enthought\Canopy\User
Long story short, make sure you find the right Python directory.

Multi Processing in python

I am trying to record Set top box signal using videorecording feature of opencv in python.
I am using capture device to capture the set top box signal whose FPS is 30.
Video Recording from External capture device is successful using opencv.
Here is the code for video recording
#VideoRecord.py
CaptureDeviceID = 1
cap = VideoCapture(CaptureDeviceID)
if cap.isOpened():
cap.set(CV_CAP_PROP_FRAME_WIDTH, 640)
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480)
else:
exit()
fourcc = cv2.cv.CV_FOURCC()
out = cv2.VideoWriter('output.avi',fourcc, 30.0, (640,480))
while(cap.isOpened()):
frameNo = 0
ret, frame = cap.read()
if ret==True:
frameNo++
# write the frame
out.write(frame)
if (frameNo > 150):
break
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
Now through Script I am changing channel using IRBlaster command.
This channel change should come in recorded video.
code for sending channel+ command
# sendCommand.py
redrat_path = r'C:\Program Files\RedRat\RedRat Control\RR_CLI_V3.01\RR_CLI.exe
redrat_process=subprocess.Popen(\"%s %s\" % (redrat_path,\"RedRat-0 -output RedRatDB.xml -device STB1 -signal Channel+ "))
In words I want to record video and send command in parallel process.So that the created video file has this
channel change event recorded.
How should I achieve this effectively so that I will not miss any frame while I am sending channel change command?.
Do i have to use threading?
Please suggest some ideas.I want to use Python