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:
|
class Posterize:
|
||||||
"""Posterize an image and then find nearest colors to use"""
|
"""Posterize an image and then find nearest colors to use"""
|
||||||
colors = []
|
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):
|
def closest(self, colors, color):
|
||||||
colors = np.array(colors)
|
colors = np.array(colors)
|
||||||
|
@ -16,6 +46,3 @@ class Posterize:
|
||||||
index_of_smallest = np.where(distances == np.amin(distances))
|
index_of_smallest = np.where(distances == np.amin(distances))
|
||||||
smallest_distance = colors[index_of_smallest]
|
smallest_distance = colors[index_of_smallest]
|
||||||
return smallest_distance
|
return smallest_distance
|
||||||
|
|
||||||
if __name__ == "__main__" :
|
|
||||||
posterize = Posterize()
|
|
|
@ -1,3 +1,4 @@
|
||||||
opencv-python
|
opencv-python
|
||||||
numpy
|
numpy
|
||||||
scikit-learn
|
scikit-learn
|
||||||
|
jsonschema
|
|
@ -1,18 +1,32 @@
|
||||||
import argparse
|
import argparse
|
||||||
from posterize import Posterize
|
from posterize import Posterize
|
||||||
from os.path import abspath
|
from pallete_schema import PalleteSchema
|
||||||
|
from os.path import isfile, realpath, basename
|
||||||
from os.path import isfile
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Separate an image into most similar colors specified')
|
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('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')
|
parser.add_argument('output', type=str, help='Output dir to write to')
|
||||||
|
|
||||||
class Separator :
|
class Separator :
|
||||||
posterize = Posterize()
|
input = ''
|
||||||
|
output = ''
|
||||||
|
pallete = None
|
||||||
|
|
||||||
def __init__ (self, args) :
|
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__" :
|
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