Zulko / moviepy

Video editing with Python
https://zulko.github.io/moviepy/
MIT License
12.42k stars 1.56k forks source link

ValueError: Invalid value for quantizer: 'wu' #368

Closed guduxingzou closed 7 years ago

guduxingzou commented 7 years ago

programe:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm # sklearn = scikit-learn
from sklearn.datasets import make_moons
from moviepy.editor import VideoClip
from moviepy.video.io.bindings import mplfig_to_npimage
import imageio
X, Y = make_moons(50, noise=0.1, random_state=2) # semi-random data

fig, ax = plt.subplots(1, figsize=(4, 4), facecolor=(1,1,1))
fig.subplots_adjust(left=0, right=1, bottom=0)
xx, yy = np.meshgrid(np.linspace(-2,3,500), np.linspace(-1,2,500))

def make_frame(t):
    ax.clear()
    ax.axis('off')
    ax.set_title("SVC classification", fontsize=16)

    classifier = svm.SVC(gamma=2, C=1)
    # the varying weights make the points appear one after the other
    weights = np.minimum(1, np.maximum(0, t**2+10-np.arange(50)))
    classifier.fit(X, Y, sample_weight=weights)
    Z = classifier.decision_function(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    ax.contourf(xx, yy, Z, cmap=plt.cm.bone, alpha=0.8,
                vmin=-2.5, vmax=2.5, levels=np.linspace(-2,2,20))
    ax.scatter(X[:,0], X[:,1], c=Y, s=50*weights, cmap=plt.cm.bone)

    return mplfig_to_npimage(fig)

animation = VideoClip(make_frame,duration=2)
animation.write_gif("svm.gif",fps=20)
fjansson commented 7 years ago

I see the same problem. The problem seems to be that convertToPIL() in imageio/plugins/pillowmulti.py is called with 'wu' as quantizer, but it supports only 'nq', 'neuquant', 0,1,2.

'wu' seems to come from the default parameter specified inwrite_gif_with_image_io(clip, filename, fps=None, opt='wu', loop=0, colors=None, verbose=True), at moviepy/video/io/gif_writers.py", line 291

Versions: Python 2.7.12 moviepy version '0.2.2.11' installed through anaconda imageio version '2.1.1' I don't have imagemagic installed.

Backtrace:

./statplot.py

[MoviePy] Building file animation.gif with imageio
  0%|                                                               | 0/101 [00:00<?, ?it/s]
Traceback (most recent call last):
  File "./statplot.py", line 112, in <module>
    animation.write_gif("animation.gif", fps=fps)
  File "<decorator-gen-56>", line 2, in write_gif
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "<decorator-gen-55>", line 2, in write_gif
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/moviepy/decorators.py", line 22, in convert_masks_to_RGB
    return f(clip, *a, **k)
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/moviepy/video/VideoClip.py", line 462, in write_gif
    verbose=verbose, colors=colors)
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/moviepy/video/io/gif_writers.py", line 291, in write_gif_with_image_io
    writer.append_data(frame)
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/imageio/core/format.py", line 468, in append_data
    return self._append_data(im, total_meta)
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/imageio/plugins/pillowmulti.py", line 101, in _append_data
    self._writer.add_image(im, duration, dispose)
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/imageio/plugins/pillowmulti.py", line 146, in add_image
    self.opt_palette_size)
  File "/export/scratch2/home/jansson/anaconda2/envs/clouds/lib/python2.7/site-packages/imageio/plugins/pillowmulti.py", line 340, in converToPIL
    raise ValueError('Invalid value for quantizer: %r' % quantizer)
ValueError: Invalid value for quantizer: 'wu'
rebecca-owen commented 7 years ago

I have the same problem - I think this is related to changes in the v2 update to imageio. For now using v1.6 of imageio is working for me while I try and figure it out.

quantology commented 7 years ago

You just need to remove the quantizer in gif_writers.py:

def write_gif_with_image_io(clip, filename, fps=None, opt='wu', loop=0,
                            colors=None, verbose=True):
    if not IMAGEIO_FOUND:
        raise ImportError("Writing a gif with imageio requires ImageIO installed,"
                         " with e.g. 'pip install imageio'")
    writer = imageio.save(filename, loop=loop,
                          fps=fps or clip.fps, palettesize=colors or 256)
    verbose_print(verbose, "\n[MoviePy] Building file %s with imageio\n"%filename)
    for frame in clip.iter_frames(fps=fps, progress_bar=True, dtype='uint8'):
        writer.append_data(frame)

Really, though, having that wrapper at all is pretty ridiculous.

robolivable commented 7 years ago

@metaperture What's ridiculous is the lack of a test suite.

stefanv commented 7 years ago

You can also change from write_gif to write_videofile.

@metaperture Would you consider making a PR to fix the issue?

EliteMasterEric commented 7 years ago

Okay, so I was going to create a pull request to fix this by setting the quantizer to 'nq', but I found this comment:

https://github.com/imageio/imageio/issues/223#issuecomment-278624024

It says that 0 is the best quantizer. Should I make 0 the default and allow people to select nq, 1, or 2 through the options, or just stick with nq?

ghost commented 7 years ago

pull request #460 should fix this issue. Hopefully we can get it merged very soon!

ghost commented 7 years ago

this has been fixed in the repo.

popovicidaniela commented 7 years ago

I get the error Invalid value for quantizer: 'wu' from pillowmulti.py, is it related ? seems like moviepy is up to date

def converToPIL(self, im, quantizer, palette_size=256):
        """Convert image to Paletted PIL image.

        PIL used to not do a very good job at quantization, but I guess
        this has improved a lot (at least in Pillow). I don't think we need
        neuqant (and we can add it later if we really want).
        """

        im_pil = ndarray_to_pil(im, 'gif')

        if quantizer in ('nq', 'neuquant'):
            # NeuQuant algorithm
            nq_samplefac = 10  # 10 seems good in general
            im_pil = im_pil.convert("RGBA")  # NQ assumes RGBA
            nqInstance = NeuQuant(im_pil, nq_samplefac)  # Learn colors
            im_pil = nqInstance.quantize(im_pil, colors=palette_size)
        elif quantizer in (0, 1, 2):
            # Adaptive PIL algorithm
            if quantizer == 2:
                im_pil = im_pil.convert("RGBA")
            else:
                im_pil = im_pil.convert("RGB")
            im_pil = im_pil.quantize(colors=palette_size, method=quantizer)
        else:
            raise ValueError('Invalid value for quantizer: %r' % quantizer)
return im_pil