Converting a sequence of ppm images to video with python - python-2.7

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.

Related

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

How detect if an image can paste a background?

I'm trying convert images in Pillow==5.4.1 to JPEG. So i use this follow code:
from PIL import Image as PilImage
img = PilImage.open('energy.png')
img.convert('RGB').save('newimage.jpeg', 'jpeg')
Some images works fine, but when i try if this image:
My result is follow:
OK, i have a problem, when a image have transparency, the background turn black. So i research and follow this code:
PIL Convert PNG or GIF with Transparency to JPG without
from PIL import Image
im = Image.open("energy.png")
bg = Image.new("RGB", im.size, (255,255,255))
bg.paste(im,im)
bg.save("newimage.jpeg")
This works fine for this picture:
The background turn white, no problem i can survive with it. But when i use this code for other images:
In [28]: im = Image.open('444.png')
In [29]: bg = Image.new("RGB", im.size, (255,255,255))
In [30]: bg.paste(im,im)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-30-f36dbc2a3949> in <module>()
----> 1 bg.paste(im,im)
/home/developer/.virtualenvs/prisvo/local/lib/python2.7/site-packages/PIL/Image.pyc in paste(self, im, box, mask)
1455 if mask:
1456 mask.load()
-> 1457 self.im.paste(im, box, mask.im)
1458 else:
1459 self.im.paste(im, box)
ValueError: bad transparency mask
This error occur with this two images:
One of this two images is png (with no transparency), and the other is already jpeg, but i need to accept jpg and png. Because i need to do this:
img.convert('RGB').save(smallJpegThumbStr, 'jpeg', quality=75)
I need to compact.
So i use (and i think) a bad implementation:
try:
bg = PilImage.new("RGB", img.size, (255,255,255))
bg.paste(img,mask=img)
bg.convert('RGB').save(mediumJpegThumbStr, 'jpeg', quality=75)
except:
img.convert('RGB').save(mediumJpegThumbStr, 'jpeg', quality=75)
In others words, when occur a error i go to another implementation. I think this is not right. My first idea is use the first implementation (inside expect) to jpeg images, and second implementation to png (inside try). But the error also occur to png (for some images). I dont know if is there a condition for this command bg.paste(im,im), or if exist an way to detect this error: ValueError: bad transparency mask without using try.
This command help. But:
bg.paste(im,mask=im.convert('L'))

(imageio or celery) Error closing: 'Image' object has no attribute 'fp'

I am using imageio to write png images to file.
import numpy as np
import matplotlib.cm as cm
import imageio # for saving the image
import matplotlib as mpl
hm_colors = ['blue', 'white','red']
cmap = mpl.colors.LinearSegmentedColormap.from_list('bwr', hm_colors)
data = np.array([[1,2,3],[5,6,7]])
norm = mpl.colors.Normalize(vmin=-3, vmax=3)
colormap = cm.ScalarMappable(norm=norm, cmap=cmap)
im = colormap.to_rgba(data)
# scale the data to a width of w pixels
im = np.repeat(im, w, axis=1)
im = np.repeat(im, h, axis=0)
# save the picture
imageio.imwrite("my_img.png", im)
This process is performed automatically and I noticed some Error messages saying:
Error closing: 'Image' object has no attribute 'fp'.
Before this message I get warning:
/usr/local/lib/python2.7/dist-packages/imageio/core/util.py:78: UserWarning: Lossy conversion from float64 to uint8, range [0, 1] dtype_str, out_type.__name__))
However, the images seem to be generated and saved just fine.
I can't find data to recreate this message.
Any idea why I get this error and why it doesn't noticeably affect the results? I don't use PIL.
One possible reason could come from using this in Celery.
Thanks!
L.
I encountered the same issue using imageio.imwrite in Python 3.5. It's a fairly harmless except for the fact that that it's stopping garbage collection and leading to excessive memory usage when writing thousands of images. The solution was to use the PIL module, which is a dependency of imageio. The last line of your code should read:
from PIL import Image
image = Image.fromarray(im)
image.save('my_img.png')

openCV imwrite writing 0 kb image frames

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()

Python - fetching image from urllib and then reading EXIF data from PIL Image not working

I use the following code to fetch an image from a url in python :
import urllib
from PIL import Image
urllib.urlretrieve("http://www.gunnerkrigg.com//comics/00000001.jpg", "00000001.jpg")
filename = '00000001.jpg'
img = Image.open(filename)
exif = img._getexif()
However, this way the exif data is always "None". But when I download the image by hand and then read the EXIF data in python, the image data is not None.
I have also tried the following approach (from Downloading a picture via urllib and python):
import urllib
f = open('00000001.jpg','wb')
f.write(urllib.urlopen('http://www.gunnerkrigg.com//comics/00000001.jpg').read())
f.close()
filename = '00000001.jpg'
img = Image.open(filename)
exif = img._getexif()
But this gives me 'None' for 'exif' again. Could someone please point out what I may do to solve this problem?
Thank you!
The .jpg you are using contains no exif information. If you try the same python with an exif example from http://www.exif.org/samples/ , I think you will find it works.