0

I am trying modify code from this question to use in Python 3.3 (I installed Pillow, scipy and NumPy):

import struct
from PIL import Image
import scipy
import scipy.misc
import scipy.cluster

NUM_CLUSTERS = 5
print ('reading image')
im = Image.open("image.jpg")
im = im.resize((150, 150))      # optional, to reduce time
ar = scipy.misc.fromimage(im)
shape = ar.shape
ar = ar.reshape(scipy.product(shape[:2]), shape[2])

print ('finding clusters')
codes, dist = scipy.cluster.vq.kmeans(ar, NUM_CLUSTERS)
print ('cluster centres:\n'), codes

vecs, dist = scipy.cluster.vq.vq(ar, codes)         # assign codes
counts, bins = scipy.histogram(vecs, len(codes))    # count occurrences

index_max = scipy.argmax(counts)                    # find most frequent
peak = codes[index_max]
colour = ''.join(chr(c) for c in peak).encode('hex')
print ('most frequent is %s (#%s)') % (peak, colour)

But I get this error:

Traceback (most recent call last):   File
"C:/Users/User/Desktop/pyt33_pic.py", line 24, in <module>
  colour = ''.join(chr(c) for c in peak).encode('hex') LookupError: unknown encoding: hex

What am I doing wrong?

Community
  • 1
  • 1
Daniel Petrov
  • 95
  • 3
  • 12

1 Answers1

0

In 2.x the codec "hex_codec" is aliased to "hex". This alias is restored in 3.4. A bigger change is that a buffer to bytes encoding requires using codecs.encode in Python 3. Additionally, for string formatting you'll need to decode the result. For example:

>>> peak
array([131, 128, 124], dtype=uint8)

>>> codecs.encode(peak, 'hex_codec').decode('ascii')
'83807c'

Alternatively you can use the format function to individually convert the numbers to hex:

>>> ''.join(format(c, '02x') for c in peak)
'83807c'
Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
  • Thank you! Your explanation really helped me. – Daniel Petrov May 24 '14 at 00:29
  • The first example uses `peak` as a buffer, since it's an array of bytes (i.e. `np.uint8`). Otherwise, assuming all elements are in `range(256)`, you'd have to use something like `codecs.encode(bytes(c for c in peak), 'hex_codec')`. Using `format` is simpler. – Eryk Sun May 24 '14 at 00:49