diff --git a/MasterProject/docker-compose.yml b/MasterProject/docker-compose.yml index fa87091..9e72a4e 100644 --- a/MasterProject/docker-compose.yml +++ b/MasterProject/docker-compose.yml @@ -7,7 +7,7 @@ services: volumes: - .:/django # Volume means that this 'WORKDIR /django' will be mapped to '/django' in the container and encapslated the project files ports: - - 8000:8000 # Port mapping, '8000' will be mapped to '8000' in the container, basically bridge the connection between the host and the container + - 8000:8000 # Port mapping, host_port '8000' will be mapped to '8000' in the container, basically bridge the connection between the host and the container image: application:django container_name: app_container_django command: gunicorn MasterProject.wsgi:application --bind 0.0.0.0:8000 @@ -17,3 +17,41 @@ services: # docker-compose down # docker builder prune -> clears the cache # docker image prune -> Remove all dangling/unused images + +# Docker Desktop: +# masterproject: C:\Users\thisi\Desktop\SnapSpeak\MasterProject -> Docker Compose looks for the docker-compose.yml file in the directory: section represents the project directory on your host machine + +# Services: +# A service is a definition for a containerized application. It typically represents an individual component or unit of your application stack, such as a web server, a database, or any other service that your application requires +# Each service runs in its own isolated container. This isolation ensures that each component of your application operates independently and can be scaled, updated, or replaced without affecting other components + +# app +# Here 'app' is a service. you might have separate services for your Django application, database (such as PostgreSQL or MySQL), caching server (like Redis), message broker (like RabbitMQ), etc. +# Each service runs in its own isolated container. This isolation ensures that each component of your application operates independently and can be scaled, updated, or replaced without affecting other components. +# Docker Compose manages the lifecycle of these containers and handles the networking between them based on the configuration you provide. + +# build: . +# The Dockerfile contains the instructions for building the Docker image. +# The build directive in the Docker Compose configuration tells Docker Compose to use the Dockerfile to build the image for the specified service. +# Docker Compose orchestrates the build process according to the instructions provided in the Dockerfile and any additional configuration specified in the Docker Compose file. + +# .:/django +# The . volume is mapped to the entire project directory to the /django directory in the container. +# mount the current directory on the host machine (where the docker-compose.yml file is located) to the /django directory inside the container, live changes in host machine is reflected on the container + +# 8000:8000 +# when you access port 8000 on the host machine, the traffic will be forwarded to port 8000 inside the container, where your application (or service) is listening for incoming connections. This allows you to access your application running inside the container from the host machine + +# image: application:django +# When you specify image: application:django in your Docker Compose configuration, you're telling Docker Compose to use a Docker image named application with the tag django for the service defined in your docker-compose.yml file. +# When you specify the image in this way, Docker Compose will look for an existing Docker image named application with the tag django in your local Docker registry. If the image does not exist locally, Docker Compose will attempt to pull it from a remote registry (such as Docker Hub) unless you've already built it locally. +# In this case, application is the name of the image, and django is the tag. These are not default values; rather, they're specified by you in your Docker Compose file. +# If you run docker-compose build, Docker Compose will build the image based on the Dockerfile in the current directory and tag it with application:django +# when you run docker-compose build, Docker Compose will use the information specified in your docker-compose.yml file to build the image for the service(s) defined in the file. + +# container_name: app_container_django +# container_name directive in Docker Compose allows you to specify a custom name for the container that will be created based on the service defined in your docker-compose.yml file + +# command: gunicorn MasterProject.wsgi:application --bind 0.0.0.0:8000 +# Both gunicorn and python manage.py runserver are valid options for serving a Django application within a Docker container. However, gunicorn is often preferred for production deployments due to its ability to handle more concurrent connections and better performance compared to the Django development server +# MasterProject.wsgi:application: This specifies the WSGI application that Gunicorn should serve. MasterProject.wsgi refers to the WSGI module within your Django project, and application is the callable object within that module diff --git a/MasterProject/homeapp/utils.py b/MasterProject/homeapp/utils.py new file mode 100644 index 0000000..0228949 --- /dev/null +++ b/MasterProject/homeapp/utils.py @@ -0,0 +1,56 @@ +from keras.preprocessing.text import Tokenizer +from keras.preprocessing.sequence import pad_sequences +from keras.applications.xception import Xception +from keras.models import load_model +from pickle import load +import numpy as np +from PIL import Image + + +def load_tokenizer_and_model(): + tokenizer = load(open("model/tokenizer.p", "rb")) + model = load_model('model/model_9.h5') + xception_model = Xception(include_top=False, pooling="avg") + return tokenizer, model, xception_model + + +def extract_features(image, model): + image = image.resize((299, 299)) + image = np.array(image) + if image.shape[2] == 4: + image = image[..., :3] + image = np.expand_dims(image, axis=0) + image = image/127.5 + image = image - 1.0 + feature = model.predict(image) + return feature + + +def word_for_id(integer, tokenizer): + for word, index in tokenizer.word_index.items(): + if index == integer: + return word + return None + + +def generate_caption(model, tokenizer, photo, max_length): + in_text = '' + for i in range(max_length): + sequence = tokenizer.texts_to_sequences([in_text])[0] + sequence = pad_sequences([sequence], maxlen=max_length) + pred = model.predict([photo, sequence], verbose=0) + pred = np.argmax(pred) + word = word_for_id(pred, tokenizer) + if word is None or word == 'end': + break + in_text += ' ' + word + return in_text + + +def generate_caption_for_image(image): + tokenizer, model, xception_model = load_tokenizer_and_model() + max_length = 32 + # image = Image.open(image_path) + photo = extract_features(image, xception_model) + caption = generate_caption(model, tokenizer, photo, max_length) + return caption, image diff --git a/MasterProject/homeapp/views.py b/MasterProject/homeapp/views.py index 40bc745..8ebd9ac 100644 --- a/MasterProject/homeapp/views.py +++ b/MasterProject/homeapp/views.py @@ -8,13 +8,8 @@ import time import pytesseract - # Importing the Keras libraries and packages -from keras.models import load_model - -# Create your views here. - -captioning_model = load_model("my_model.h5") +from .utils import generate_caption_for_image def home(request): @@ -39,7 +34,7 @@ def upload_image_view(request): # Captioning Function calls START here: - captions = "this is a beautiful image" + captions, _ = generate_caption_for_image(image) # Captioning function calls END here diff --git a/MasterProject/my_model.h5 b/MasterProject/model/model_9.h5 similarity index 70% rename from MasterProject/my_model.h5 rename to MasterProject/model/model_9.h5 index c83f46e..52aee35 100644 Binary files a/MasterProject/my_model.h5 and b/MasterProject/model/model_9.h5 differ diff --git a/MasterProject/model/tokenizer.p b/MasterProject/model/tokenizer.p new file mode 100644 index 0000000..c13e927 Binary files /dev/null and b/MasterProject/model/tokenizer.p differ diff --git a/MasterProject/requirements.txt b/MasterProject/requirements.txt index b4bf4ae..1609788 100644 --- a/MasterProject/requirements.txt +++ b/MasterProject/requirements.txt @@ -4,7 +4,8 @@ Pillow==10.2.0 pytesseract==0.3.10 gunicorn==21.2.0 whitenoise==6.6.0 -tensorflow==2.15.0 +tensorflow==2.8.0 +protobuf==3.19.0 opencv-python==4.9.0.80 numpy==1.26.4 pipreqs==0.4.13 \ No newline at end of file diff --git a/MasterProject/static/assets/Captioning Prompts/166321294_4a5e68535f.jpg b/MasterProject/static/assets/Captioning Prompts/166321294_4a5e68535f.jpg new file mode 100644 index 0000000..ed22116 Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/166321294_4a5e68535f.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/17273391_55cfc7d3d4.jpg b/MasterProject/static/assets/Captioning Prompts/17273391_55cfc7d3d4.jpg new file mode 100644 index 0000000..1802549 Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/17273391_55cfc7d3d4.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/241347067_e58d05dbdc.jpg b/MasterProject/static/assets/Captioning Prompts/241347067_e58d05dbdc.jpg new file mode 100644 index 0000000..b45705a Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/241347067_e58d05dbdc.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/278496691_c1fd93e2d8.jpg b/MasterProject/static/assets/Captioning Prompts/278496691_c1fd93e2d8.jpg new file mode 100644 index 0000000..7485b23 Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/278496691_c1fd93e2d8.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/282116218_7fd7583d6e.jpg b/MasterProject/static/assets/Captioning Prompts/282116218_7fd7583d6e.jpg new file mode 100644 index 0000000..774c03b Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/282116218_7fd7583d6e.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/399212516_d68046b277.jpg b/MasterProject/static/assets/Captioning Prompts/399212516_d68046b277.jpg new file mode 100644 index 0000000..a29c6da Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/399212516_d68046b277.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/49553964_cee950f3ba.jpg b/MasterProject/static/assets/Captioning Prompts/49553964_cee950f3ba.jpg new file mode 100644 index 0000000..e28f6c0 Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/49553964_cee950f3ba.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/54501196_a9ac9d66f2.jpg b/MasterProject/static/assets/Captioning Prompts/54501196_a9ac9d66f2.jpg new file mode 100644 index 0000000..c3215ec Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/54501196_a9ac9d66f2.jpg differ diff --git a/MasterProject/static/assets/Captioning Prompts/96420612_feb18fc6c6.jpg b/MasterProject/static/assets/Captioning Prompts/96420612_feb18fc6c6.jpg new file mode 100644 index 0000000..c8d042d Binary files /dev/null and b/MasterProject/static/assets/Captioning Prompts/96420612_feb18fc6c6.jpg differ diff --git a/tree.txt b/tree.txt new file mode 100644 index 0000000..8ea48cd Binary files /dev/null and b/tree.txt differ