Skip to content

Instantly share code, notes, and snippets.

@mgritter
Last active October 24, 2016 04:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgritter/e11ce48beef1811feb6a2cab9b439f16 to your computer and use it in GitHub Desktop.
Save mgritter/e11ce48beef1811feb6a2cab9b439f16 to your computer and use it in GitHub Desktop.
Iteration 2 of using NNMF to blend pixel art
from scipy.misc import imread
import numpy as np
# These are flower images from the PROJCAM garden bundle.
path = "C:\Users\Mark\Documents\ProcJam\PROCJAM2016-Tess2D\PROCJAM2016-Tess2D\Garden\\"
names = [ "flower{:02d}.png".format( i ) for i in xrange( 0, 22 ) ]
original = [ imread( path + name ) for name in names ]
def flatten( image ):
return np.reshape( image, [-1] )
palette = set()
for image in original:
for row in image:
for color in row:
palette.add( tuple( color ) )
transparent = False
for (r,g,b,a) in list( palette ):
if a == 0: # transparent
transparent = True
palette.remove( (r,g,b,a) )
if transparent:
palette.add( (255, 255, 255, 0) )
palette = list( palette )
print "Palette", palette
def convertToPalette( image ):
px = []
for pixel in np.reshape( image, [-1, 4] ):
(r, g, b, a ) = pixel
if a == 0:
pixel = ( 255, 255, 255, 0 )
vec = [ int( tuple(pixel) == palette[i] ) for i in xrange( len( palette ) ) ]
px.append( vec )
newRep = np.array( px )
return np.reshape( newRep, [-1] )
from math import sqrt
def convertToRgb( image ):
y = len( palette )
pixels = np.reshape( image, [-1, y] )
pa = np.array( palette )
# Normalize to 1.0
row_sums = pixels.sum( axis = 1, keepdims = True )
normalized = pixels / row_sums
rgbVec = normalized.dot( pa )
dim = int( sqrt( len( rgbVec ) ) )
rgbMat = np.reshape( rgbVec, [dim, dim, 4] )
return np.array( rgbMat, dtype="uint8" )
# Matrix V has shape [samples, feature]
# Each sample is an image, each feature is the presence of a palette color
# in a pixel
V = np.matrix( [ convertToPalette( i ) for i in original ] )
(numSamples, numFeatures) = V.shape
print "Samples: ", numSamples
print "Features: ", numFeatures
from sklearn.decomposition import NMF
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def trial( numComponents = 22, max_iter = 10000 ):
model = NMF( n_components= numComponents, max_iter=max_iter )
W = model.fit_transform( V )
H = model.components_
# Matrix W has shape [ samples, components ]
# Matrix H has shape [ components, features ]
print "Error", model.reconstruction_err_
X2 = model.inverse_transform( W )
plt.figure( 1 )
numImages = len( names )
for n in xrange( numImages ):
# original
o = original[n]
plt.subplot( numImages, 2, n * 2 + 1 )
plt.imshow( o, interpolation = "none" )
plt.axis( "off" )
# reconstruction
p = convertToRgb( X2[n] )
plt.subplot( numImages, 2, n * 2 + 2 )
plt.imshow( p, interpolation = "none" )
plt.axis( "off" )
plt.show()
# return ( model, W, H )
def mixAll( numComponents = 22, max_iter = 10000 ):
model = NMF( n_components= numComponents, max_iter=max_iter )
W = model.fit_transform( V )
H = model.components_
# Matrix W has shape [ samples, components ]
# Matrix H has shape [ components, features ]
plt.figure( 1 )
numImages = len( names )
for a in xrange( numImages ):
for b in xrange( numImages ):
plt.subplot( numImages, numImages, numImages * a + b + 1 )
if a == b:
plt.imshow( original[a], interpolation = "none" )
elif a < b:
wa = W[a]
wb = W[b]
wi = ( wa + wb ) * 0.5
x = wi.dot( H )
plt.imshow( convertToRgb( x ), interpolation = "none" )
plt.axis( "off" )
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment