Spaces:
Sleeping
Sleeping
upload files
Browse files- .gitattributes +1 -0
- app.py +118 -0
- naming.py +79 -0
- requirements.txt +3 -0
- w2c11_j.npy +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
w2c11_j.npy filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import os
|
| 3 |
+
import shutil
|
| 4 |
+
import cv2
|
| 5 |
+
import numpy as np
|
| 6 |
+
|
| 7 |
+
from naming import im2c
|
| 8 |
+
from collections import Counter
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
COLOR_NAME = ['black', 'brown', 'blue', 'gray', 'green', 'orange', 'pink', 'purple', 'red', 'white', 'yellow']
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def get_top_names(img):
|
| 15 |
+
# resize images to smaller size
|
| 16 |
+
anchor = 512
|
| 17 |
+
width = img.shape[1]
|
| 18 |
+
height = img.shape[0]
|
| 19 |
+
if width > 1024 or height > 1024:
|
| 20 |
+
if width >= height:
|
| 21 |
+
dim = (np.floor(width/height*anchor).astype(int), anchor)
|
| 22 |
+
else:
|
| 23 |
+
dim = (anchor, np.floor(height/width*anchor).astype(int))
|
| 24 |
+
img = cv2.resize(img, dim, interpolation=cv2.INTER_LINEAR)
|
| 25 |
+
|
| 26 |
+
w2c = np.load('w2c11_j.npy').astype(np.float16)
|
| 27 |
+
_, _, name_idx_img, _ = im2c(img, w2c)
|
| 28 |
+
|
| 29 |
+
filtered_counts = Counter(name_idx_img[name_idx_img <= 10])
|
| 30 |
+
sorted_counts = sorted(filtered_counts.items(), key=lambda x: x[1], reverse=True)
|
| 31 |
+
top_3_values = [num for num, count in sorted_counts[:3]]
|
| 32 |
+
top_3_colors = [COLOR_NAME[i] for i in top_3_values]
|
| 33 |
+
# print("Top 3 colors:", top_3_colors)
|
| 34 |
+
return top_3_values, top_3_colors
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def classify_and_log(images):
|
| 38 |
+
output_folder = "classified_results"
|
| 39 |
+
os.makedirs(output_folder, exist_ok=True)
|
| 40 |
+
|
| 41 |
+
category_folders = {i: os.path.join(output_folder, COLOR_NAME[i]) for i in range(11)}
|
| 42 |
+
for folder in category_folders.values():
|
| 43 |
+
os.makedirs(folder, exist_ok=True)
|
| 44 |
+
|
| 45 |
+
log_file = os.path.join(output_folder, "log.txt")
|
| 46 |
+
|
| 47 |
+
results = {i: [] for i in range(11)}
|
| 48 |
+
|
| 49 |
+
with open(log_file, "w") as log:
|
| 50 |
+
for id_img, img in enumerate(images):
|
| 51 |
+
filename = os.path.basename(img.name)
|
| 52 |
+
img_array = cv2.imread(img).astype(np.float32)
|
| 53 |
+
img_array = cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB)
|
| 54 |
+
|
| 55 |
+
cat_id, category = get_top_names(img_array)
|
| 56 |
+
# print(category_folders[cat_id[0]], filename)
|
| 57 |
+
target_path = os.path.join(category_folders[cat_id[0]], filename)
|
| 58 |
+
|
| 59 |
+
cv2.imwrite(target_path, cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB))
|
| 60 |
+
|
| 61 |
+
print(f"Image:{filename} -> Top 3 colors:{category}\n")
|
| 62 |
+
|
| 63 |
+
log.write(f"{filename} -> {category}\n")
|
| 64 |
+
|
| 65 |
+
results[cat_id[0]].append(target_path)
|
| 66 |
+
|
| 67 |
+
# output_images = [results[i] for i in range(11)]
|
| 68 |
+
# print(output_images)
|
| 69 |
+
|
| 70 |
+
return log_file
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def swap_to_gallery(images):
|
| 74 |
+
return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False)
|
| 75 |
+
|
| 76 |
+
def upload_example_to_gallery(images, prompt, style, negative_prompt):
|
| 77 |
+
return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False)
|
| 78 |
+
|
| 79 |
+
def remove_back_to_files():
|
| 80 |
+
return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
with gr.Blocks() as demo:
|
| 85 |
+
gr.Markdown("## Image color categorization")
|
| 86 |
+
|
| 87 |
+
with gr.Row():
|
| 88 |
+
with gr.Column():
|
| 89 |
+
image_input = gr.File(
|
| 90 |
+
label="Drag (Select) more than one photos",
|
| 91 |
+
file_types=["image"],
|
| 92 |
+
file_count="multiple"
|
| 93 |
+
)
|
| 94 |
+
uploaded_files = gr.Gallery(label="Your images", visible=False, columns=5, rows=1, height=200)
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
with gr.Column(visible=False) as clear_button:
|
| 98 |
+
remove_and_reupload = gr.ClearButton(value="Remove and upload new ones", components=image_input, size="sm")
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
image_input.upload(fn=swap_to_gallery, inputs=image_input, outputs=[uploaded_files, clear_button, image_input])
|
| 102 |
+
remove_and_reupload.click(fn=remove_back_to_files, outputs=[uploaded_files, clear_button, image_input])
|
| 103 |
+
|
| 104 |
+
classify_btn = gr.Button("submit")
|
| 105 |
+
|
| 106 |
+
# with gr.Row():
|
| 107 |
+
# image_output = {str(i): gr.Gallery(label=f"{i}") for i in range(11)}
|
| 108 |
+
|
| 109 |
+
log_output = gr.File(label="download logs")
|
| 110 |
+
|
| 111 |
+
classify_btn.click(
|
| 112 |
+
classify_and_log,
|
| 113 |
+
inputs=[image_input],
|
| 114 |
+
outputs=[log_output]
|
| 115 |
+
)
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
demo.launch()
|
naming.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import cv2
|
| 3 |
+
from collections import Counter
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
COLOR_NAME = ['black', 'brown', 'blue', 'gray', 'green', 'orange', 'pink', 'purple', 'red', 'white', 'yellow']
|
| 7 |
+
|
| 8 |
+
def im2c(im, w2c):
|
| 9 |
+
"""
|
| 10 |
+
Convert an image to color name representation using a color-name matrix.
|
| 11 |
+
|
| 12 |
+
Returns:
|
| 13 |
+
numpy.ndarray: Processed image based on color parameter.
|
| 14 |
+
"""
|
| 15 |
+
# Define color name mappings
|
| 16 |
+
color_values = np.array([[ 0, 0, 0],
|
| 17 |
+
[165, 81, 43],
|
| 18 |
+
[ 0, 0, 255],
|
| 19 |
+
[127, 127, 127],
|
| 20 |
+
[ 0, 255, 0],
|
| 21 |
+
[255, 127, 0],
|
| 22 |
+
[255, 165, 216],
|
| 23 |
+
[191, 0, 191],
|
| 24 |
+
[255, 0, 0],
|
| 25 |
+
[255, 255, 255],
|
| 26 |
+
[255, 255, 0]], dtype=np.uint8)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
# Extract RGB channels
|
| 30 |
+
# RR, GG, BB = im[:, :, 0].flatten(), im[:, :, 1].flatten(), im[:, :, 2].flatten()
|
| 31 |
+
|
| 32 |
+
# Compute index for w2c lookup
|
| 33 |
+
index_im = ((im[:, :, 0].flatten() // 8) + 32 * (im[:, :, 1].flatten()// 8) + 32 * 32 * (im[:, :, 2].flatten() // 8)).astype(np.int32)
|
| 34 |
+
|
| 35 |
+
# w2cM = np.argmax(w2c, axis=1)
|
| 36 |
+
# name_idx_img = w2cM[index_im].reshape(im.shape[:2])
|
| 37 |
+
|
| 38 |
+
# max_prob = w2c[np.arange(w2c.shape[0]), w2cM]
|
| 39 |
+
# max_prob_map = max_prob[index_im].reshape(im.shape[:2])
|
| 40 |
+
|
| 41 |
+
prob_map = w2c[index_im, :].reshape((im.shape[0], im.shape[1], w2c.shape[1]))
|
| 42 |
+
max_prob_map = np.max(prob_map, axis=2)
|
| 43 |
+
name_idx_img = np.argmax(prob_map, axis=2)
|
| 44 |
+
|
| 45 |
+
color_img = np.zeros_like(im).astype(np.uint8)
|
| 46 |
+
|
| 47 |
+
for jj in range(im.shape[0]):
|
| 48 |
+
for ii in range(im.shape[1]):
|
| 49 |
+
color_img[jj, ii, :] = np.array(color_values[name_idx_img[jj, ii]])
|
| 50 |
+
|
| 51 |
+
return prob_map, max_prob_map, name_idx_img, color_img
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
if __name__ == "__main__":
|
| 55 |
+
# Load w2c matrix
|
| 56 |
+
w2c = np.load('w2c11_j.npy').astype(np.float16) # Assuming 'w2c.mat' was converted to 'w2c.npy'
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
image_path = './test.jpg'
|
| 60 |
+
img = cv2.imread(image_path).astype(np.float32)
|
| 61 |
+
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
| 62 |
+
|
| 63 |
+
prob_map, max_prob_img, name_idx_img, color_img = im2c(img, w2c)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
filtered_counts = Counter(name_idx_img[name_idx_img <= 10])
|
| 67 |
+
sorted_counts = sorted(filtered_counts.items(), key=lambda x: x[1], reverse=True)
|
| 68 |
+
top_3_values = [num for num, count in sorted_counts[:3]]
|
| 69 |
+
top_3_colors = [COLOR_NAME[i] for i in top_3_values]
|
| 70 |
+
|
| 71 |
+
print("Top 3 colors:", top_3_colors)
|
| 72 |
+
|
| 73 |
+
cv2.imwrite('colormap_j.jpg', cv2.cvtColor(color_img, cv2.COLOR_BGR2RGB))
|
| 74 |
+
|
| 75 |
+
# print(prob_map.sum(axis=2))
|
| 76 |
+
# print(name_idx_img)
|
| 77 |
+
# print(max_prob_img.shape)
|
| 78 |
+
# print(color_img)
|
| 79 |
+
|
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
numpy
|
| 2 |
+
cv2
|
| 3 |
+
opencv-python
|
w2c11_j.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bc5ede48fed749d552edf1fd5d058266c713f20af3d4a484310103be91766856
|
| 3 |
+
size 2883712
|