Pallete script can generate valid pallete json
This commit is contained in:
parent
423d4ee57d
commit
3f7ba3ad67
|
@ -1,5 +1,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
import cv2
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
from math import floor
|
||||||
from pallete_schema import PalleteSchema
|
from pallete_schema import PalleteSchema
|
||||||
|
|
||||||
from os.path import isfile, realpath, basename, dirname, splitext, join
|
from os.path import isfile, realpath, basename, dirname, splitext, join
|
||||||
|
@ -12,6 +14,9 @@ class Pallete :
|
||||||
input = ''
|
input = ''
|
||||||
output = ''
|
output = ''
|
||||||
image = None
|
image = None
|
||||||
|
selection = []
|
||||||
|
colors = []
|
||||||
|
i = 0
|
||||||
|
|
||||||
def __init__ (self, args) :
|
def __init__ (self, args) :
|
||||||
if isfile(args.input) :
|
if isfile(args.input) :
|
||||||
|
@ -19,16 +24,60 @@ class Pallete :
|
||||||
else :
|
else :
|
||||||
print(f'File {self.input} does not exist')
|
print(f'File {self.input} does not exist')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
self.set_output()
|
self.set_output()
|
||||||
|
self.load()
|
||||||
|
self.display_ui()
|
||||||
|
self.write()
|
||||||
|
|
||||||
def set_output (self) :
|
def set_output (self) :
|
||||||
dir = dirname(self.input)
|
dir = dirname(self.input)
|
||||||
stem = splitext(basename(self.input))[0]
|
stem = splitext(basename(self.input))[0]
|
||||||
|
name = basename(self.input)
|
||||||
|
print(f'Using image {name}')
|
||||||
self.output = join(dir, f'{stem}.json')
|
self.output = join(dir, f'{stem}.json')
|
||||||
print(f'Writing to {stem}.json')
|
print(f'Writing to {stem}.json')
|
||||||
|
|
||||||
def process (self) :
|
def load (self) :
|
||||||
image = cv2.imread(self.input)
|
self.image = cv2.imread(self.input)
|
||||||
|
|
||||||
|
def display_ui (self) :
|
||||||
|
cv2.imshow('pallete', self.image)
|
||||||
|
cv2.namedWindow('pallete')
|
||||||
|
cv2.setMouseCallback('pallete', self.on_click)
|
||||||
|
cv2.waitKey(0)
|
||||||
|
cv2.destroyAllWindows()
|
||||||
|
|
||||||
|
def on_click (self, event, x, y, flags, param) :
|
||||||
|
if event == cv2.EVENT_LBUTTONDOWN:
|
||||||
|
#print(f'{x},{y}')
|
||||||
|
if len(self.selection) == 0 :
|
||||||
|
self.selection.append([x, y])
|
||||||
|
elif len(self.selection) == 1 :
|
||||||
|
self.selection.append([x, y])
|
||||||
|
self.process_color(self.selection)
|
||||||
|
self.selection = []
|
||||||
|
|
||||||
|
def process_color (self, selection) :
|
||||||
|
top_left = selection[0]
|
||||||
|
bottom_right = selection[1]
|
||||||
|
color_select = self.image[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
|
||||||
|
avg_color_per_row = np.average(color_select, axis=0)
|
||||||
|
avg_color = np.average(avg_color_per_row, axis=0)
|
||||||
|
int_color = []
|
||||||
|
for i in avg_color :
|
||||||
|
int_color.append( int( round(i) ) )
|
||||||
|
self.colors.append({
|
||||||
|
'name' : str(self.i),
|
||||||
|
'color' : int_color,
|
||||||
|
'space' : 'BGR'
|
||||||
|
})
|
||||||
|
print(f'Added {self.i} = {int_color}')
|
||||||
|
self.i += 1
|
||||||
|
|
||||||
|
def write (self) :
|
||||||
|
PalleteSchema(self.output, self.colors)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__" :
|
if __name__ == "__main__" :
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
|
@ -12,14 +12,17 @@ class PalleteSchema :
|
||||||
"color" : {
|
"color" : {
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"items" : { "type" : "number" }
|
"items" : { "type" : "number" }
|
||||||
}
|
},
|
||||||
|
"space" : { "type" : "string" }
|
||||||
},
|
},
|
||||||
"required" : [ "name", "color" ]
|
"required" : [ "name", "color", "space" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def __init__ (self, file = None):
|
def __init__ (self, file = None, obj = None):
|
||||||
if file is not None:
|
if file is not None and obj is None:
|
||||||
self.parse_file(file)
|
self.parse_file(file)
|
||||||
|
else :
|
||||||
|
self.write(file, obj)
|
||||||
|
|
||||||
def parse_file (self, file) :
|
def parse_file (self, file) :
|
||||||
with open(file) as f :
|
with open(file) as f :
|
||||||
|
@ -29,4 +32,10 @@ class PalleteSchema :
|
||||||
def parse (self, jsonstr) :
|
def parse (self, jsonstr) :
|
||||||
obj = loads(jsonstr)
|
obj = loads(jsonstr)
|
||||||
validate( instance = obj, schema = self.schema)
|
validate( instance = obj, schema = self.schema)
|
||||||
self.colors = obj
|
self.colors = obj
|
||||||
|
|
||||||
|
def write(self, filepath, obj) :
|
||||||
|
validate( instance = obj, schema = self.schema)
|
||||||
|
jsonstr = dumps(obj, indent = 4)
|
||||||
|
with open(filepath, 'w') as outfile :
|
||||||
|
outfile.write(jsonstr)
|
|
@ -50,13 +50,20 @@ class Posterize:
|
||||||
self.original_colors = np.unique(reshaped, axis=0)
|
self.original_colors = np.unique(reshaped, axis=0)
|
||||||
#print(self.original_colors)
|
#print(self.original_colors)
|
||||||
for i in range(self.n_colors) :
|
for i in range(self.n_colors) :
|
||||||
mask = self.extract_color(self.image, self.original_colors[i])
|
mask = self.extract_color_mask(self.image, self.original_colors[i])
|
||||||
cv2.imwrite(f'{i}.png', mask)
|
cv2.imwrite(f'{i}.png', mask)
|
||||||
|
|
||||||
def extract_color (self, image, color):
|
def extract_color_mask (self, image, color):
|
||||||
mask = cv2.inRange(image, color, color)
|
mask = cv2.inRange(image, color, color)
|
||||||
return cv2.bitwise_not(mask)
|
return cv2.bitwise_not(mask)
|
||||||
|
|
||||||
|
def convert_color (self, color, color_space_a, color_space_b) :
|
||||||
|
pixel = np.zeros([1, 1, 3], dtype=np.uint8)
|
||||||
|
pixel = cv2.cvtColor(pixel, color_space_a)
|
||||||
|
pixel[:] = color
|
||||||
|
cvt = cv2.cvtColor(pixel, color_space_b)
|
||||||
|
return cvt[0, 0]
|
||||||
|
|
||||||
def closest(self, colors, color):
|
def closest(self, colors, color):
|
||||||
colors = np.array(colors)
|
colors = np.array(colors)
|
||||||
color = np.array(color)
|
color = np.array(color)
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name" : "red",
|
"name" : "red",
|
||||||
"color" : [255, 0, 0]
|
"color" : [255, 0, 0],
|
||||||
|
"space" : "RGB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "green",
|
"name" : "green",
|
||||||
"color" : [0, 255, 0]
|
"color" : [0, 255, 0],
|
||||||
|
"space" : "RGB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "blue",
|
"name" : "blue",
|
||||||
"color" : [0, 0, 255]
|
"color" : [0, 0, 255],
|
||||||
|
"space" : "RGB"
|
||||||
}
|
}
|
||||||
]
|
]
|
Loading…
Reference in New Issue