Now posterizes an image to a number of colors determined by the command line arguments on separator.py. Still needs to color match and then export to different layer files.
This commit is contained in:
parent
d7ec5bb111
commit
f862e28a8b
|
@ -0,0 +1,35 @@
|
|||
import argparse
|
||||
import cv2
|
||||
from pallete_schema import PalleteSchema
|
||||
|
||||
from os.path import isfile, realpath, basename, dirname, splitext, join
|
||||
|
||||
parser = argparse.ArgumentParser(description='Separate an image into most similar colors specified')
|
||||
|
||||
parser.add_argument('input', type=str, help='Input image to extract the pallete from')
|
||||
|
||||
class Pallete :
|
||||
input = ''
|
||||
output = ''
|
||||
image = None
|
||||
|
||||
def __init__ (self, args) :
|
||||
if isfile(args.input) :
|
||||
self.input = realpath(args.input)
|
||||
else :
|
||||
print(f'File {self.input} does not exist')
|
||||
exit(1)
|
||||
self.set_output()
|
||||
|
||||
def set_output (self) :
|
||||
dir = dirname(self.input)
|
||||
stem = splitext(basename(self.input))[0]
|
||||
self.output = join(dir, f'{stem}.json')
|
||||
print(f'Writing to {stem}.json')
|
||||
|
||||
def process (self) :
|
||||
image = cv2.imread(self.input)
|
||||
|
||||
if __name__ == "__main__" :
|
||||
args = parser.parse_args()
|
||||
Pallete(args)
|
|
@ -0,0 +1,32 @@
|
|||
from jsonschema import validate
|
||||
from json import dumps, loads
|
||||
|
||||
class PalleteSchema :
|
||||
colors = None
|
||||
schema = {
|
||||
"type" : "array",
|
||||
"items" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"name" : { "type" : "string" },
|
||||
"color" : {
|
||||
"type" : "array",
|
||||
"items" : { "type" : "number" }
|
||||
}
|
||||
},
|
||||
"required" : [ "name", "color" ]
|
||||
}
|
||||
}
|
||||
def __init__ (self, file = None):
|
||||
if file is not None:
|
||||
self.parse_file(file)
|
||||
|
||||
def parse_file (self, file) :
|
||||
with open(file) as f :
|
||||
self.parse(f.read())
|
||||
print(f'Parsed pallete file {file}')
|
||||
|
||||
def parse (self, jsonstr) :
|
||||
obj = loads(jsonstr)
|
||||
validate( instance = obj, schema = self.schema)
|
||||
self.colors = obj
|
|
@ -6,8 +6,38 @@ import cv2
|
|||
class Posterize:
|
||||
"""Posterize an image and then find nearest colors to use"""
|
||||
colors = []
|
||||
#def __init__ (self) :
|
||||
image = None
|
||||
pallete = None
|
||||
h = 0
|
||||
w = 0
|
||||
n_colors = 3
|
||||
|
||||
def __init__ (self, image, pallete, n_colors) :
|
||||
self.image = cv2.imread(image)
|
||||
(self.h, self.w) = self.image.shape[:2]
|
||||
self.pallete = pallete
|
||||
self.n_colors = n_colors
|
||||
self.process()
|
||||
|
||||
def process (self) :
|
||||
lab = cv2.cvtColor(self.image, cv2.COLOR_BGR2LAB)
|
||||
feature = lab.reshape((self.h * self.w, 3))
|
||||
|
||||
clusters = MiniBatchKMeans(n_clusters = self.n_colors, n_init = 'auto')
|
||||
|
||||
labels = clusters.fit_predict(feature)
|
||||
quant = clusters.cluster_centers_.astype('uint8')[labels]
|
||||
|
||||
rquant = quant.reshape((self.h, self.w, 3))
|
||||
rfeature = feature.reshape((self.h, self.w, 3))
|
||||
|
||||
bgrquant = cv2.cvtColor(rquant, cv2.COLOR_LAB2BGR)
|
||||
bgrfeature = cv2.cvtColor(rfeature, cv2.COLOR_LAB2BGR)
|
||||
|
||||
cv2.imshow("image", bgrquant)
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
def closest(self, colors, color):
|
||||
colors = np.array(colors)
|
||||
|
@ -16,6 +46,3 @@ class Posterize:
|
|||
index_of_smallest = np.where(distances == np.amin(distances))
|
||||
smallest_distance = colors[index_of_smallest]
|
||||
return smallest_distance
|
||||
|
||||
if __name__ == "__main__" :
|
||||
posterize = Posterize()
|
|
@ -1,3 +1,4 @@
|
|||
opencv-python
|
||||
numpy
|
||||
scikit-learn
|
||||
scikit-learn
|
||||
jsonschema
|
|
@ -1,18 +1,32 @@
|
|||
import argparse
|
||||
from posterize import Posterize
|
||||
from os.path import abspath
|
||||
|
||||
from os.path import isfile
|
||||
from pallete_schema import PalleteSchema
|
||||
from os.path import isfile, realpath, basename
|
||||
|
||||
parser = argparse.ArgumentParser(description='Separate an image into most similar colors specified')
|
||||
|
||||
parser.add_argument('input', type=str, help='Input image to separate')
|
||||
parser.add_argument('colors', type=int, help='Number of colors to separate into')
|
||||
parser.add_argument('pallete', type=str, help='Pallete file')
|
||||
parser.add_argument('output', type=str, help='Output dir to write to')
|
||||
|
||||
class Separator :
|
||||
posterize = Posterize()
|
||||
input = ''
|
||||
output = ''
|
||||
pallete = None
|
||||
|
||||
def __init__ (self, args) :
|
||||
print(args)
|
||||
if isfile(args.input) :
|
||||
self.input = realpath(args.input)
|
||||
else :
|
||||
print(f'File {args.input} does not exist')
|
||||
exit(1)
|
||||
if isfile(args.pallete) :
|
||||
self.pallete = PalleteSchema(args.pallete)
|
||||
else :
|
||||
print(f'File {args.pallete} does not exist')
|
||||
exit(2)
|
||||
Posterize(self.input, self.pallete, args.colors)
|
||||
|
||||
|
||||
if __name__ == "__main__" :
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"name" : "red",
|
||||
"color" : [255, 0, 0]
|
||||
},
|
||||
{
|
||||
"name" : "green",
|
||||
"color" : [0, 255, 0]
|
||||
},
|
||||
{
|
||||
"name" : "blue",
|
||||
"color" : [0, 0, 255]
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue