JoshuaPeddle commited on
Commit
5ec100d
·
1 Parent(s): 3964f0b
Files changed (8) hide show
  1. .gitignore +2 -0
  2. README.md +60 -11
  3. app.py +19 -0
  4. dockerfile +10 -0
  5. models/__init__.py +0 -0
  6. models/models.py +83 -0
  7. requirements.txt +64 -0
  8. upscaled_image.jpg +0 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __pycache__
2
+ .local
README.md CHANGED
@@ -1,11 +1,60 @@
1
- ---
2
- title: ImageTransfer Server
3
- emoji: 🐠
4
- colorFrom: indigo
5
- colorTo: indigo
6
- sdk: docker
7
- pinned: false
8
- license: openrail
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Image Transfer and Upscaling API
2
+ This service provides APIs to perform image upscaling and style transfer (Monet style) using Machine Learning models. The project is built using Flask, a lightweight WSGI web application framework.
3
+
4
+
5
+ ```bash
6
+ git clone <repository-url>
7
+ cd <project-directory>
8
+ Install the dependencies using pip.
9
+ ```
10
+ ```bash
11
+ pip install -r requirements.txt
12
+ ```
13
+ ## Running the Application
14
+ Run the application with the following command:
15
+
16
+ ```bash
17
+ python3 -m flask run --host=0.0.0.0
18
+ ```
19
+ The application should start and be accessible at localhost:5000.
20
+
21
+ ## API Endpoints
22
+ The application exposes two API endpoints:
23
+
24
+ ```/monet```: POST endpoint which accepts an image file and returns the image stylized in the style of Monet paintings.
25
+
26
+ ```/upscale```: POST endpoint which accepts an image file and returns the upscaled version of the image.
27
+ #File Structure
28
+ ```app.py```: This is the main application file which runs the Flask application and defines the API endpoints.
29
+ ```models/models.py```: This file contains the model loading and prediction functions.
30
+ ## models/models.py
31
+ ```tensor_to_image(tensor)```: Converts a TensorFlow tensor to an image and saves it to 'upscaled_image.jpg'.
32
+
33
+ ```request_to_image(request)```: Converts a Flask request object containing an image to a numpy array.
34
+
35
+ ```_monet(image, upscale=False)```: Accepts an image as input and returns the image stylized in the style of Monet paintings.
36
+
37
+ ```_upscale(image)```: Accepts an image as input and returns the upscaled version of the image.
38
+ ## Sending Requests to the API
39
+ For both endpoints, the image file should be included in the request as form data with the key 'image'. Here is an example using curl:
40
+
41
+ ```bash
42
+ Copy code
43
+ curl -X POST -F "image=@<image-file-path>" http://localhost:5000/monet
44
+ ```
45
+ ```bash
46
+ Copy code
47
+ curl -X POST -F "image=@<image-file-path>" http://localhost:5000/upscale
48
+ Replace <image-file-path> with the path to your image file.
49
+ ```
50
+ ## Notes
51
+ The model files for the Monet style transfer (models/monet_generator) are not included in this repository. You need to download them separately and place them in the correct location.
52
+ Contributing
53
+ Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
54
+
55
+ ## License
56
+ MIT
57
+
58
+ docker buildx build --platform linux/amd64,linux/arm64 -t joshuapeddle/imagetransfer-server:0.0.2 --push .
59
+
60
+ docker run -p 5000:5000 joshuapeddle/imagetransfer-server:0.0.2
app.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask , request, send_file
2
+ from flask_cors import CORS
3
+ from PIL import Image
4
+ from models.models import _upscale, _monet, request_to_image
5
+ from numpy import asarray
6
+
7
+ app = Flask(__name__)
8
+ CORS(app)
9
+ @app.route("/monet", methods=['POST'])
10
+ def monet():
11
+ return send_file(_monet(request_to_image(request) ,True), mimetype='image/jpg')
12
+
13
+ @app.route("/upscale", methods=['POST'])
14
+ def upscale():
15
+ return send_file(_upscale(request_to_image(request)), mimetype='image/jpg')
16
+
17
+ @app.route("/", methods=['GET'])
18
+ def hello():
19
+ return "Hello World"
dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9.16-buster
2
+
3
+ WORKDIR /usr/src/app
4
+
5
+ COPY requirements.txt ./
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0", "--debug"]
models/__init__.py ADDED
File without changes
models/models.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from PIL import Image
4
+ import tensorflow as tf
5
+ import tensorflow_hub as hub
6
+ from numpy import asarray
7
+ from tensorflow.python.ops.numpy_ops import np_config
8
+ np_config.enable_numpy_behavior()
9
+ os.environ["TFHUB_DOWNLOAD_PROGRESS"] = "True"
10
+ from huggingface_hub import from_pretrained_keras
11
+ def tensor_to_image(tensor):
12
+ tensor = tf.cast(tf.clip_by_value(tensor, 0, 255), tf.uint8)
13
+ tensor = Image.fromarray(tensor.numpy())
14
+ tensor.save('upscaled_image.jpg')
15
+ return 'upscaled_image.jpg'
16
+
17
+
18
+ def request_to_image(request):
19
+ image = request.files.get('image', False)
20
+ print(image)
21
+ if image:
22
+ return asarray(Image.open(image))
23
+ else:return asarray(Image.open(request.files['image']))
24
+
25
+
26
+ def _monet(image, upscale=False):
27
+ IMAGE_SIZE = (256, 256)
28
+ def decode_image(image):
29
+ #image = tf.image.decode_jpeg(image, channels=3)
30
+ image = (tf.cast(image, tf.float32) / 127.5) - 1
31
+ image = tf.reshape(image, [*IMAGE_SIZE, 3])
32
+ return image
33
+
34
+ #new_model = tf.keras.models.load_model('models/monet_generator', compile=False)
35
+ new_model = from_pretrained_keras("JoshuaPeddle/MonetGenerator")
36
+ #new_model.summary()
37
+ image = tf.image.resize(image, IMAGE_SIZE)
38
+ image = decode_image(image)
39
+
40
+ image = tf.expand_dims(image, 0)
41
+ start = time.time()
42
+ prediction = new_model(image, training=False)
43
+ prediction = tf.reshape(prediction, [256, 256, 3])
44
+ prediction = (prediction + 1) / 2
45
+ prediction = tf.image.convert_image_dtype(prediction, tf.uint8)
46
+ print("Time Taken: %f" % (time.time() - start))
47
+
48
+ if upscale:
49
+ return _upscale(prediction)
50
+
51
+ return tensor_to_image(prediction)
52
+
53
+
54
+
55
+
56
+ def _upscale(image):
57
+ SAVED_MODEL_PATH = "https://tfhub.dev/captain-pool/esrgan-tf2/1"
58
+ def preprocess_image(_image):
59
+ """ Loads image from path and preprocesses to make it model ready
60
+ Args:
61
+ image_path: Path to the image file
62
+ """
63
+ #hr_image = tf.image.decode_image(tf.io.read_file(image_path))
64
+ hr_image = _image
65
+ # If PNG, remove the alpha channel. The model only supports
66
+ # images with 3 color channels.
67
+ if hr_image.shape[-1] == 4:
68
+ hr_image = hr_image[...,:-1]
69
+ hr_size = (tf.convert_to_tensor(hr_image.shape[:-1]) // 4) * 4
70
+ hr_image = tf.image.crop_to_bounding_box(hr_image, 0, 0, hr_size[0], hr_size[1])
71
+ hr_image = tf.cast(hr_image, tf.float32)
72
+ return tf.expand_dims(hr_image, 0)
73
+
74
+
75
+ hr_image = preprocess_image(image)
76
+ model = hub.load(SAVED_MODEL_PATH)
77
+
78
+ start = time.time()
79
+ fake_image = model(hr_image)
80
+ fake_image = tf.squeeze(fake_image)
81
+ print("Time Taken: %f" % (time.time() - start))
82
+ fake_image = tf.image.resize(fake_image, (512,512))
83
+ return tensor_to_image(fake_image)
requirements.txt ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl-py==1.4.0
2
+ astunparse==1.6.3
3
+ blinker==1.6.2
4
+ cachetools==5.3.0
5
+ certifi==2023.5.7
6
+ charset-normalizer==3.1.0
7
+ click==8.1.3
8
+ contourpy==1.0.7
9
+ cycler==0.11.0
10
+ filelock==3.12.0
11
+ Flask==2.3.2
12
+ Flask-Cors==3.0.10
13
+ flatbuffers==23.5.8
14
+ fonttools==4.39.4
15
+ fsspec==2023.5.0
16
+ gast==0.4.0
17
+ google-auth==2.18.0
18
+ google-auth-oauthlib==1.0.0
19
+ google-pasta==0.2.0
20
+ grpcio==1.54.0
21
+ h5py==3.8.0
22
+ huggingface-hub==0.14.1
23
+ idna==3.4
24
+ importlib-metadata==6.6.0
25
+ importlib-resources==5.12.0
26
+ itsdangerous==2.1.2
27
+ jax==0.4.9
28
+ Jinja2==3.1.2
29
+ keras==2.12.0
30
+ kiwisolver==1.4.4
31
+ libclang==16.0.0
32
+ Markdown==3.4.3
33
+ MarkupSafe==2.1.2
34
+ matplotlib==3.7.1
35
+ ml-dtypes==0.1.0
36
+ numpy==1.23.5
37
+ oauthlib==3.2.2
38
+ opt-einsum==3.3.0
39
+ packaging==23.1
40
+ Pillow==9.5.0
41
+ protobuf==4.23.0
42
+ pyasn1==0.5.0
43
+ pyasn1-modules==0.3.0
44
+ pyparsing==3.0.9
45
+ python-dateutil==2.8.2
46
+ PyYAML==6.0
47
+ requests==2.30.0
48
+ requests-oauthlib==1.3.1
49
+ rsa==4.9
50
+ scipy==1.10.1
51
+ six==1.16.0
52
+ tensorboard==2.12.3
53
+ tensorboard-data-server==0.7.0
54
+ tensorflow==2.12.0
55
+ tensorflow-estimator==2.12.0
56
+ tensorflow-hub==0.13.0
57
+ tensorflow-io-gcs-filesystem==0.32.0
58
+ termcolor==2.3.0
59
+ tqdm==4.65.0
60
+ typing_extensions==4.5.0
61
+ urllib3==1.26.15
62
+ Werkzeug==2.3.4
63
+ wrapt==1.14.1
64
+ zipp==3.15.0
upscaled_image.jpg ADDED