Cannot Demultiplex Stream from Video created by Py OpenCV - python

I'm trying to use OpenCV to create a video out of individual frames. Although the code runs without error, I cannot play the resulting avi file. When I do, the error I get is Could not demultiplex stream.
The stripped down version of the code I'm using to do this is:
import caffe
import cv2
import fnmatch
import os
# Get Image List
image_list = fnmatch.filter('./sample/images','*.png')
image_list.sort()
# Create VideoWriter
# codec = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
# codec = -1
codec = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
video = cv2.VideoWriter( './movieT.avi',
codec,
20,
(289, 289))
for img_name in image_list:
# Load image
im_path = os.path.join('./sample/images',img_name)
img = caffe.io.load_image(im_path)
# Resize image to expected size
img = caffe.io.resize(img,(289, 289, 3))
# Write image
video.write(img)
video.release()
I Googled around a bit, and the main errors I see mentioned are ensuring the image sizes match the size expected by the cv2.VideoWiter and that I have the right codecs. I resize my images to ensure they are the right size and I tried a few different codecs. I also tried to install standard codecs using some apt-get install commands I also found by Googling around:
me#balin:~$ sudo apt update
me#balin:~$ sudo apt install libdvdnav4 libdvdread4 gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly libdvd-pkg
me#balin:~$ sudo apt install ubuntu-restricted-extras
I am currently using:
Ubuntu 18.04
Python 2.7.17
cv2.__version__ 4.0.1

I think your problem in incorrect use of fnmatch.filter() which doesn't get filenames from folder but it is used only to check if filename match pattern.
See example from fnmatch
import fnmatch
import os
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
print(file)
With your code I alwyas get empty list so later it can't add any image to video and I can't display this video.
But you can use glob.glob() for this
image_list = glob.glob('./sample/images/*.png')
This code works for me
import cv2
import glob
image_list = glob.glob('./sample/images/*.png')
image_list.sort()
#print(image_list)
codec = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
video = cv2.VideoWriter('./movieT.avi', codec, 20, (289, 289))
for img_name in image_list:
img = cv2.imread(img_name)
img = cv2.resize(img, (289, 289))
video.write(img)
video.release()

Related

The document could not be opened, opencv python3

I'm trying to make a video from images with python and OpenCV but when I run the script the video is generated but when I try to open it I give this error:
This is the script:
import cv2
import numpy as np
import glob
frameSize = (1920, 1080)
out = cv2.VideoWriter('output_video.avi',cv2.VideoWriter_fourcc(*'DIVX'), 60, frameSize)
for filename in glob.glob('/folder_path/*.jpg'):
img = cv2.imread(filename)
out.write(img)
out.release()
UPDATE:
If I use
out = cv2.VideoWriter('output_video.avi',cv2.VideoWriter_fourcc(*'MJPG'), 60, frameSize)
Instead
out = cv2.VideoWriter('output_video.avi',cv2.VideoWriter_fourcc(*'DIVX'), 60, frameSize)
The video start but I can see anything
Ok, I have found a solution.
This is the final code:
import cv2,os
from os.path import isfile, join
def convert_pictures_to_video(pathIn, pathOut, fps, time):
# this function converts images to video
frame_array=[]
files=[f for f in os.listdir(pathIn) if isfile(join(pathIn,f))]
#files.remove(".DS_Store")
for i in range (len(files)):
filename=pathIn+files[i]
# reading images
img=cv2.imread(filename)
# img=cv2.resize(img,(1400,1000))
height, width, layers = img.shape
size=(width,height)
for k in range (time):
frame_array.append(img)
out=cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'mp4v'), fps, size)
for i in range(len(frame_array)):
out.write(frame_array[i])
out.release()
pathIn= '/pathIn-folder/'
pathOut='/pathOut-folder/output.avi'
fps=1
time=20 # the duration of each picture in the video
convert_pictures_to_video(pathIn, pathOut, fps, time)
You can find more info and a tutorial here.
REMEMBER
If you have a mac there are two important things to do.
First you have to uncomment #files.remove(".DS_Store") because when you create a new folder on macOS there is an extra hidden file called .DS_Store
You can't open the output video with Quick Time Player
You have to use another software like VLC

How can i pass image itself (np.array) not path of it to zxing library for decode pdf417

Code:
import zxing
from PIL import Image
reader = zxing.BarCodeReader()
path = 'C:/Users/UI UX/Desktop/Uasa.png'
im = Image.open(path)
barcode = reader.decode(path)
print(barcode)
when i use code above work fine and return result:
BarCode(raw='P<E....
i need to use this code:
import zxing
import cv2
reader = zxing.BarCodeReader()
path = 'C:/Users/UI UX/Desktop/Uasa.png'
img = cv2.imread (path)
cv2.imshow('img', img)
cv2.waitKey(0)
barcode = reader.decode(img)
print(barcode)
but this code return an error:
TypeError: expected str, bytes or os.PathLike object, not numpy.ndarray
In another program i have image at base64 could help me somewhere here?
any body could help me with this?
ZXing does not support passing an image directly as it is using an external application to process the barcode image. If you're not locked into using the ZXing library for decoding PDF417 barcodes you can take a look at the PyPI package pdf417decoder.
If you're starting with a Numpy array like in your example then you have to convert it to a PIL image first.
import cv2
import pdf417decoder
from PIL import Image
npimg = cv2.imread (path)
cv2.imshow('img', npimg)
cv2.waitKey(0)
img = Image.fromarray(npimg)
decoder = PDF417Decoder(img)
if (decoder.decode() > 0):
print(decoder.barcode_data_index_to_string(0))
else:
print("Failed to decode barcode.")
You cannot. if you look at the source code you will see that what it does is call a java app with the provided path (Specifically com.google.zxing.client.j2se.CommandLineRunner).
If you need to pre-process your image then you will have to save it somewhere and pass the path to it to your library
I fix this by:
path = os.getcwd()
# print(path)
writeStatus = cv2.imwrite(os.path.join(path, 'test.jpg'), pdf_image)
if writeStatus is True:
print("image written")
else:
print("problem") # or raise exception, handle problem, etc.
sss = (os.path.join(path, 'test.jpg'))
# print(sss)
pp = sss.replace('\\', '/')
# print(pp)
reader = zxing.BarCodeReader()
barcode = reader.decode(pp)
The zxing package is not recommended. It is just a command line tool to invoke Java ZXing libraries.
You should use zxing-cpp, which is a Python module built with ZXing C++ code. Here is the sample code:
import cv2
import zxingcpp
img = cv2.imread('myimage.png')
results = zxingcpp.read_barcodes(img)
for result in results:
print("Found barcode:\n Text: '{}'\n Format: {}\n Position: {}"
.format(result.text, result.format, result.position))
if len(results) == 0:
print("Could not find any barcode.")

How can I convert some png files to a video using OpenCV?

The file appears and when I open it it just closes. I'm on Linux Mint Cinnamon.
import cv2
import numpy as np
import glob
size = (500,500)
img_array = []
for filename in glob.glob('home/user/Desktop/Images/*.png'):
img = cv2.imread(filename)
height, width, layers = img.shape
size = (width,height)
img_array.append(img)
out = cv2.VideoWriter('project.avi',cv2.VideoWriter_fourcc(*'DIVX'), 15, size)
for i in range(len(img_array)):
out.write(img_array[i])
out.release()
cvWaitKey(0)
Your code is fundamentally correct, but openCV video writing seems to be very sensitive to the machine environment, codecs etc.
As an alternative, you might consider the imageio library, for example:
import imageio
writer = imageio.get_writer('movie.mp4')
for img in img_array:
writer.append_data(img)
writer.close()
The examples are here.
Typo error: cvWaitKey(0) to cv2.waitKey(0)

How to convert multipage PDF to list of image objects in Python?

I'd like to turn a multipage PDF document into a series of image object in list structure, without saving the images in disk (I'd like to process them with PIL Image)in Python. So far I can only do this to write the images into files first:
from wand.image import Image
with Image(filename='source.pdf') as img:
with img.convert('png') as converted:
converted.save(filename='pyout/page.png')
But how could I turn the img objects above directly into list of PIL.Image objects?
new answer:
pip install pdf2image
from pdf2image import convert_from_path, convert_from_bytes
images = convert_from_path('/path/to/my.pdf')
You may need to install pillow as well. This might only work on linux.
https://github.com/Belval/pdf2image
Results may be different between the two methods.
old answer:
Python 3.4:
from PIL import Image
from wand.image import Image as wimage
import os
import io
if __name__ == "__main__":
filepath = "fill this in"
assert os.path.exists(filepath)
page_images = []
with wimage(filename=filepath, resolution=200) as img:
for page_wand_image_seq in img.sequence:
page_wand_image = wimage(page_wand_image_seq)
page_jpeg_bytes = page_wand_image.make_blob(format="jpeg")
page_jpeg_data = io.BytesIO(page_jpeg_bytes)
page_image = Image.open(page_jpeg_data)
page_images.append(page_image)
Lastly, you can make a system call to mogrify, but that can be more complicated as you need to manage temporary files.
Simple way is to save image files and delete them after reading them using PIL.
I recommend to use pdf2image package.
Before using pdf2image package, you might need to install poppler package via anaconda
conda install -c conda-forge poppler
If you are stuck, please update conda before installing :
conda update conda
conda update anaconda
After installing poppler, install pdf2image via pip :
pip install pdf2image
Then run this code :
from pdf2image import convert_from_path
dpi = 500 # dots per inch
pdf_file = 'work.pdf'
pages = convert_from_path(pdf_file ,dpi )
for i in range(len(pages)):
page = pages[i]
page.save('output_{}.jpg'.format(i), 'JPEG')
After this, please read them using PIL and delete them.
my answer with wand is the following:
from wand.image import Image as wi
...
Data = filedialog.askopenfilename(initialdir="/", title="Choose File", filetypes = (("Portable Document Format","*.pdf"),("All Files", "*.*")))
apps.append(Data)
print(Data)
PDFfile = wi(filename = Data, resolution = 300)
Images = PDFfile.convert('tiff')
ImageSequence = 1
for img in PDFfile.sequence:
image = wi(image = img)
image.save(filename = "Document_300"+"_"+str(ImageSequence)+".tiff")
ImageSequence += 1
Hopefully this will help you.
I've implemented it with a GUI where you can simply choose your file.
You can also change the PDFfile.convert() in jpg etc.
Download Poppler from here https://blog.alivate.com.au/poppler-windows/ , then use the following code:
from pdf2image import convert_from_path
file_name = 'A019'
images = convert_from_path(r'D:\{}.pdf'.format(file_name), poppler_path=r'C:\poppler-0.68.0\bin')
for i, im in enumerate(images):
im.save(r'D:\{}-{}.jpg'.format(file_name,i))
If you get an error because of poppler's path, add poppler's bin path to "Path" in windows environment variables. Path can be like this "C:\poppler-0.68.0\bin"

How to export video as .mp4 using openCV?

I am trying to export video as .mp4 with openCV. I have tried several codecs but for now I had no success.
This is a function that constructs a video from frames:
def create_movie(self, out_directory, fps, total_frames):
img1 = cv2.imread("temp/scr0.png")
height, width, layers = img1.shape
codec = cv2.cv.CV_FOURCC('X','V','I','D')
video = cv2.VideoWriter(out_directory, codec, fps, (width, height))
for i in range(total_frames):
img_name = "temp/scr" + str(i) + ".png"
img = cv2.imread(img_name)
video.write(img)
video.release()
cv2.destroyAllWindows()
I usually get next error message, using different codecs:
Tag XVID/0x44495658 incompatible with output codec id '13'
Is is possible to do this and how?
There is a non-direct solution. You export as .avi and then convert to .mp4 using python's call which calls terminal command.
from subprocess import call
dir = out_directory.strip(".avi")
command = "avconv -i %s.avi -c:v libx264 -c:a copy %s.mp4" % (dir, dir)
call(command.split())
May be a little bit late to answer this, but if you want to write an .MP4 file with OpenCV try this:
import cv2
#your previous code here
fourcc = cv2.VideoWriter_fourcc(*'a\0\0\0')
out = cv2.VideoWriter('out.mp4', fourcc, fps, res)
#the character '\0' is the Null-Terminator or simply 0x00 in the ASCII-Table
#tag: *'a\0\0\0' corresponds to 0x00000061
#your following code here

Categories