Instantly share code, notes, and snippets.

# mgritter/icon_nnmf.py Last active Oct 24, 2016

What would you like to do?
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()