Spaces:
Runtime error
Runtime error
AnujPanthri
commited on
Commit
·
b2f488a
1
Parent(s):
0c2e200
added basic ui
Browse files- app/app.py +81 -0
- app/static/script.js +75 -0
- app/static/style.css +103 -0
- app/templates/index.html +38 -0
- requirements.txt +5 -0
- src/simple_regression_colorization/model/base_model_interface.py +2 -2
app/app.py
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import src
|
3 |
+
from src.utils.config_loader import constants,Config
|
4 |
+
from src.utils import config_loader
|
5 |
+
from src.utils.script_utils import validate_config
|
6 |
+
import importlib
|
7 |
+
from flask import Flask,request,Response
|
8 |
+
import PIL
|
9 |
+
import PIL.Image
|
10 |
+
import cv2
|
11 |
+
import numpy as np
|
12 |
+
import base64
|
13 |
+
import io
|
14 |
+
from flask import render_template
|
15 |
+
|
16 |
+
model_config_path = os.path.join(constants.ARTIFACT_MODEL_DIR,"config.yaml")
|
17 |
+
config = Config(model_config_path)
|
18 |
+
# validate config
|
19 |
+
validate_config(config)
|
20 |
+
|
21 |
+
config_loader.config = config
|
22 |
+
|
23 |
+
|
24 |
+
# now load model
|
25 |
+
model_dir = constants.ARTIFACT_MODEL_DIR
|
26 |
+
model_save_path = os.path.join(model_dir,"model.weights.h5")
|
27 |
+
|
28 |
+
if not os.path.exists(model_save_path):
|
29 |
+
raise Exception("No model found")
|
30 |
+
|
31 |
+
Model = importlib.import_module(f"src.{config.task}.model.models.{config.model}").Model
|
32 |
+
model = Model(model_save_path)
|
33 |
+
|
34 |
+
|
35 |
+
app = Flask(__name__)
|
36 |
+
|
37 |
+
|
38 |
+
@app.route("/",methods=["GET"])
|
39 |
+
def home():
|
40 |
+
# return "home page"
|
41 |
+
return render_template("index.html")
|
42 |
+
|
43 |
+
@app.route("/config",methods=["GET"])
|
44 |
+
def read_config():
|
45 |
+
content = open(model_config_path,"r").read()
|
46 |
+
return Response(content,mimetype='text')
|
47 |
+
|
48 |
+
@app.route("/colorize",methods=["POST"])
|
49 |
+
def colorize():
|
50 |
+
|
51 |
+
files = request.files
|
52 |
+
file = files.get('image')
|
53 |
+
print(file)
|
54 |
+
img = PIL.Image.open(file)
|
55 |
+
img = img.convert("L")
|
56 |
+
|
57 |
+
img = img.resize([config.image_size,config.image_size])
|
58 |
+
img = np.array(img)
|
59 |
+
print(img.min(),img.max())
|
60 |
+
print(img.shape)
|
61 |
+
|
62 |
+
# model.predict()
|
63 |
+
L = img[:,:,None]
|
64 |
+
L = (L/255*100).astype("uint8")
|
65 |
+
|
66 |
+
AB = model.predict(L[None])[0]
|
67 |
+
img = np.concatenate([L, AB], axis=-1)
|
68 |
+
colored_img = cv2.cvtColor(img, cv2.COLOR_LAB2RGB) * 255
|
69 |
+
|
70 |
+
print(colored_img.shape)
|
71 |
+
|
72 |
+
im = PIL.Image.fromarray(colored_img.astype("uint8"))
|
73 |
+
rawBytes = io.BytesIO()
|
74 |
+
im.save(rawBytes, "jpeg")
|
75 |
+
rawBytes.seek(0)
|
76 |
+
base64_img = (base64.b64encode(rawBytes.read())).decode("utf-8")
|
77 |
+
|
78 |
+
return {"image":base64_img}
|
79 |
+
|
80 |
+
|
81 |
+
app.run(debug=True,host="0.0.0.0",port=5000)
|
app/static/script.js
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var image = new MarvinImage();
|
2 |
+
var gray_scale_image = new MarvinImage();
|
3 |
+
|
4 |
+
image_file_input.addEventListener("change",(ev)=>{
|
5 |
+
console.log(ev);
|
6 |
+
console.log();
|
7 |
+
if(ev.target.files.length){
|
8 |
+
show_black_and_white_image(ev.target.files[0]);
|
9 |
+
}
|
10 |
+
})
|
11 |
+
|
12 |
+
|
13 |
+
function show_black_and_white_image(file){
|
14 |
+
var fr = new FileReader();
|
15 |
+
fr.onload = ()=>{
|
16 |
+
original_img.src = fr.result;
|
17 |
+
|
18 |
+
// var canvas = document.createElement("canvas");
|
19 |
+
// var ctx = canvas.getContext("2d");
|
20 |
+
|
21 |
+
// original_img.onload = function() {
|
22 |
+
// console.log(original_img.width,original_img.height);
|
23 |
+
// // console.log(original_img.width,original_img.height);
|
24 |
+
// canvas.height = original_img.height;
|
25 |
+
// canvas.width = original_img.width;
|
26 |
+
|
27 |
+
// ctx.drawImage(original_img, 0, 0,original_img.width,original_img.height);
|
28 |
+
// console.log(canvas.width,canvas.height);
|
29 |
+
|
30 |
+
// // image grayscale logic
|
31 |
+
// var imageData = ctx.getImageData(0,0,original_img.width,original_img.height);
|
32 |
+
|
33 |
+
// for(var i=0;i<imageData.data.length;i+=4){
|
34 |
+
// var avg = (
|
35 |
+
// imageData.data[i]
|
36 |
+
// + imageData.data[i+1]
|
37 |
+
// + imageData.data[i+2]
|
38 |
+
// )/3;
|
39 |
+
|
40 |
+
// imageData.data[i] = avg;
|
41 |
+
// imageData.data[i+1] = avg;
|
42 |
+
// imageData.data[i+2] = avg;
|
43 |
+
|
44 |
+
// }
|
45 |
+
// ctx.putImageData(imageData,0,0,0,0,imageData.width,imageData.height);
|
46 |
+
|
47 |
+
// original_img.src = canvas.toDataURL();
|
48 |
+
// original_img.onload = null;
|
49 |
+
// };
|
50 |
+
|
51 |
+
colorize();
|
52 |
+
}
|
53 |
+
fr.readAsDataURL(file);
|
54 |
+
}
|
55 |
+
|
56 |
+
function colorize(){
|
57 |
+
fetch(original_img.src)
|
58 |
+
.then((response)=>{
|
59 |
+
return response.blob()
|
60 |
+
})
|
61 |
+
.then((blob)=>{
|
62 |
+
// now send it
|
63 |
+
var formdata = new FormData();
|
64 |
+
formdata.append("image",blob,"image");
|
65 |
+
fetch("/colorize",{
|
66 |
+
method:"POST",
|
67 |
+
body:formdata,
|
68 |
+
})
|
69 |
+
.then(res=>res.json())
|
70 |
+
.then((data)=>{
|
71 |
+
console.log(data);
|
72 |
+
result_img.src = "data:image/png;charset=utf-8;base64,"+data["image"];
|
73 |
+
})
|
74 |
+
})
|
75 |
+
}
|
app/static/style.css
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* || RESET CSS */
|
2 |
+
* {
|
3 |
+
margin: 0;
|
4 |
+
padding: 0;
|
5 |
+
box-sizing: border-box;
|
6 |
+
}
|
7 |
+
|
8 |
+
body {
|
9 |
+
font-family: 'Courier New', Courier, monospace;
|
10 |
+
font-size: 1.3em;
|
11 |
+
|
12 |
+
min-height: 100vh;
|
13 |
+
|
14 |
+
display: flex;
|
15 |
+
flex-direction: column;
|
16 |
+
|
17 |
+
background-color: #333;
|
18 |
+
|
19 |
+
margin-inline: 1em;
|
20 |
+
}
|
21 |
+
|
22 |
+
h1 {
|
23 |
+
color: #bbb;
|
24 |
+
}
|
25 |
+
|
26 |
+
|
27 |
+
/* || GENERAL STYLES */
|
28 |
+
|
29 |
+
header>h1 {
|
30 |
+
text-align: center;
|
31 |
+
margin: 0.5em 0;
|
32 |
+
}
|
33 |
+
|
34 |
+
main {
|
35 |
+
flex-grow: 1;
|
36 |
+
}
|
37 |
+
|
38 |
+
.group {
|
39 |
+
width:100%;
|
40 |
+
display: flex;
|
41 |
+
justify-content: center;
|
42 |
+
align-items: center;
|
43 |
+
column-gap: 1em;
|
44 |
+
row-gap: 2em;
|
45 |
+
|
46 |
+
flex-wrap: wrap;
|
47 |
+
position: relative;
|
48 |
+
}
|
49 |
+
|
50 |
+
.group .container {
|
51 |
+
width: 90%;
|
52 |
+
max-width:400px;
|
53 |
+
height: 300px;
|
54 |
+
overflow: hidden;
|
55 |
+
}
|
56 |
+
|
57 |
+
.container img {
|
58 |
+
width:100%;
|
59 |
+
height:90%;
|
60 |
+
border-radius: 10px;
|
61 |
+
border: 2px solid #fff;
|
62 |
+
object-fit: contain;
|
63 |
+
|
64 |
+
background-color: #222;
|
65 |
+
/* object-fit: cover; */
|
66 |
+
}
|
67 |
+
|
68 |
+
.container__label {
|
69 |
+
display: block;
|
70 |
+
color: #fff;
|
71 |
+
font-weight: 500;
|
72 |
+
font-size: 0.9em;
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
#image_file_input {
|
77 |
+
display: None
|
78 |
+
}
|
79 |
+
|
80 |
+
#original_img {
|
81 |
+
cursor: pointer;
|
82 |
+
}
|
83 |
+
|
84 |
+
|
85 |
+
|
86 |
+
footer {
|
87 |
+
width: 100%;
|
88 |
+
display: flex;
|
89 |
+
justify-content: center;
|
90 |
+
align-items: center;
|
91 |
+
|
92 |
+
text-align: center;
|
93 |
+
font-size: 0.9em;
|
94 |
+
|
95 |
+
margin-top: 2em;
|
96 |
+
padding: 0.4em 0;
|
97 |
+
color: #ccc;
|
98 |
+
}
|
99 |
+
|
100 |
+
footer a {
|
101 |
+
text-decoration: underline;
|
102 |
+
color: #fff;
|
103 |
+
}
|
app/templates/index.html
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Image Colorization</title>
|
7 |
+
<link rel="stylesheet" href="static/style.css"/>
|
8 |
+
<script src="static/script.js" defer></script>
|
9 |
+
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
|
10 |
+
</head>
|
11 |
+
<body>
|
12 |
+
<header>
|
13 |
+
<h1>Color Black and White Images</h1>
|
14 |
+
</header>
|
15 |
+
<main>
|
16 |
+
<div class="group">
|
17 |
+
<div class="container">
|
18 |
+
<img id="original_img" onclick="image_file_input.click()"/>
|
19 |
+
<input id="image_file_input" type="file" accept="image/*" />
|
20 |
+
<span class="container__label">Original Image</span>
|
21 |
+
</div>
|
22 |
+
<div class="container">
|
23 |
+
<img id="result_img" />
|
24 |
+
<span class="container__label">Predicted Image</span>
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
</main>
|
28 |
+
<footer>
|
29 |
+
<p>
|
30 |
+
made with passion by
|
31 |
+
<a href="https://github.com/AnujPanthri/Image-Colorization/">Anuj Panthri</a>
|
32 |
+
|
|
33 |
+
trained using
|
34 |
+
<a href="/config">config.yaml</a>
|
35 |
+
</p>
|
36 |
+
</footer>
|
37 |
+
</body>
|
38 |
+
</html>
|
requirements.txt
CHANGED
@@ -1,9 +1,11 @@
|
|
1 |
absl-py==2.1.0
|
2 |
astunparse==1.6.3
|
3 |
attrs==23.2.0
|
|
|
4 |
Cerberus==1.3.5
|
5 |
certifi==2024.2.2
|
6 |
charset-normalizer==3.3.2
|
|
|
7 |
comet-ml==3.42.1
|
8 |
configobj==5.0.8
|
9 |
contourpy==1.2.1
|
@@ -11,6 +13,7 @@ cycler==0.12.1
|
|
11 |
dulwich==0.22.1
|
12 |
everett==3.1.0
|
13 |
filelock==3.14.0
|
|
|
14 |
flatbuffers==24.3.25
|
15 |
fonttools==4.51.0
|
16 |
fsspec==2024.5.0
|
@@ -21,6 +24,8 @@ h5py==3.11.0
|
|
21 |
huggingface-hub==0.23.1
|
22 |
idna==3.7
|
23 |
imageio==2.34.1
|
|
|
|
|
24 |
joblib==1.4.2
|
25 |
jsonschema==4.22.0
|
26 |
jsonschema-specifications==2023.12.1
|
|
|
1 |
absl-py==2.1.0
|
2 |
astunparse==1.6.3
|
3 |
attrs==23.2.0
|
4 |
+
blinker==1.8.2
|
5 |
Cerberus==1.3.5
|
6 |
certifi==2024.2.2
|
7 |
charset-normalizer==3.3.2
|
8 |
+
click==8.1.7
|
9 |
comet-ml==3.42.1
|
10 |
configobj==5.0.8
|
11 |
contourpy==1.2.1
|
|
|
13 |
dulwich==0.22.1
|
14 |
everett==3.1.0
|
15 |
filelock==3.14.0
|
16 |
+
Flask==3.0.3
|
17 |
flatbuffers==24.3.25
|
18 |
fonttools==4.51.0
|
19 |
fsspec==2024.5.0
|
|
|
24 |
huggingface-hub==0.23.1
|
25 |
idna==3.7
|
26 |
imageio==2.34.1
|
27 |
+
itsdangerous==2.2.0
|
28 |
+
Jinja2==3.1.4
|
29 |
joblib==1.4.2
|
30 |
jsonschema==4.22.0
|
31 |
jsonschema-specifications==2023.12.1
|
src/simple_regression_colorization/model/base_model_interface.py
CHANGED
@@ -58,9 +58,9 @@ class BaseModel(ABC):
|
|
58 |
|
59 |
def predict_colors(self,L_batch):
|
60 |
AB_batch = self.predict(L_batch)
|
61 |
-
colored_batch = np.concatenate([L_batch,
|
62 |
colored_batch = lab2rgb(colored_batch) * 255
|
63 |
-
return colored_batch
|
64 |
|
65 |
def show_results(self):
|
66 |
self.prepare_data()
|
|
|
58 |
|
59 |
def predict_colors(self,L_batch):
|
60 |
AB_batch = self.predict(L_batch)
|
61 |
+
colored_batch = np.concatenate([L_batch,AB_batch],axis=-1)
|
62 |
colored_batch = lab2rgb(colored_batch) * 255
|
63 |
+
return colored_batch.astype("uint8")
|
64 |
|
65 |
def show_results(self):
|
66 |
self.prepare_data()
|