Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added computer vision functionality #9

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
# MAIL_SERVER=smtp.example.com
# MAIL_USERNAME=example
# MAIL_PASSWORD=example-password
# VISION_KEY = your-vision-key
# VISION_ENDPOINT = https://example.cognitiveservices.azure.com/
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ $ pdm install
> [!TIP]
> If you don't have PDM installed, you can create a virtual environment with `venv` and install dependencies with `pip install -r requirements.txt`.

Setting up environment variables for azure congnitive services
- create a (.env) file with:
```
VISION_KEY = YOUR_SUBSCRIPTION_KEY
VISION_ENDPOINT = YOUR_AZURE_ENDPOINT
```
- get your key and endpoint by following the documentation - https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/quickstarts-sdk/image-analysis-client-library

To initialize the app, run the `flask init-app` command:

```
Expand Down
48 changes: 46 additions & 2 deletions moments/blueprints/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
from moments.notifications import push_collect_notification, push_comment_notification
from moments.utils import flash_errors, redirect_back, rename_image, resize_image, validate_image

from azure.cognitiveservices.vision.computervision import ComputerVisionClient
import os
from msrest.authentication import CognitiveServicesCredentials

from dotenv import load_dotenv
load_dotenv()

main_bp = Blueprint('main', __name__)


Expand Down Expand Up @@ -130,14 +137,27 @@ def upload():
if not validate_image(f.filename):
return 'Invalid image.', 400
filename = rename_image(f.filename)
f.save(current_app.config['MOMENTS_UPLOAD_PATH'] / filename)
photo_path = current_app.config['MOMENTS_UPLOAD_PATH'] / filename
f.save(photo_path)
filename_s = resize_image(f, filename, current_app.config['MOMENTS_PHOTO_SIZES']['small'])
filename_m = resize_image(f, filename, current_app.config['MOMENTS_PHOTO_SIZES']['medium'])
photo = Photo(
filename=filename, filename_s=filename_s, filename_m=filename_m, author=current_user._get_current_object()
filename=filename, filename_s=filename_s, filename_m=filename_m, author=current_user._get_current_object(), description = get_description(photo_path)
)
db.session.add(photo)
db.session.commit()
tags = get_tags(photo_path)
for tag in tags:
tag_found = db.session.scalar(select(Tag).filter_by(name=tag))
if tag_found is None:
tag_found= Tag(name=tag)
db.session.add(tag_found)
db.session.commit()
if tag_found not in photo.tags:
photo.tags.append(tag_found)
db.session.commit()

flash('Photo uploaded with auto description and tags generated by ML', 'success')
return render_template('main/upload.html')


Expand Down Expand Up @@ -426,3 +446,27 @@ def delete_tag(photo_id, tag_id):

flash('Tag deleted.', 'info')
return redirect(url_for('.show_photo', photo_id=photo_id))


def get_tags(image_url):

subscription_key = os.environ["VISION_KEY"]
endpoint = os.environ["VISION_ENDPOINT"]

computervision_client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(subscription_key))

with open(image_url, 'rb') as img_data:
tags_result_remote = computervision_client.tag_image_in_stream(img_data)
result = []
for tag in tags_result_remote.tags:
result.append(tag.name)
return result

def get_description(image_url):
subscription_key = os.environ["VISION_KEY"]
endpoint = os.environ["VISION_ENDPOINT"]

computervision_client = ComputerVisionClient(endpoint, CognitiveServicesCredentials(subscription_key))
with open(image_url, 'rb') as img_data:
description_result = computervision_client.describe_image_in_stream(img_data)
return description_result.captions[0].text
2 changes: 1 addition & 1 deletion moments/templates/admin/manage_photo.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ <h1>Photos
<tr>
<td>
<a href="{{ url_for('main.show_photo', photo_id=photo.id) }}">
<img src="{{ url_for('main.get_image', filename=photo.filename_s) }}" width="250">
<img src="{{ url_for('main.get_image', filename=photo.filename_s) }}" width="250" alt="{{ photo.description}}">
</a>
</td>
<td>{{ photo.description }}</td>
Expand Down
2 changes: 1 addition & 1 deletion moments/templates/macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{% macro photo_card(photo) %}
<div class="photo-card card">
<a class="card-thumbnail" href="{{ url_for('main.show_photo', photo_id=photo.id) }}">
<img class="card-img-top portrait" src="{{ url_for('main.get_image', filename=photo.filename_s) }}">
<img class="card-img-top portrait" src="{{ url_for('main.get_image', filename=photo.filename_s) }}" alt="{{ photo.description}}">
</a>
<div class="card-body">
{{ render_icon('suit-heart-fill') }} {{ photo.collectors_count }}
Expand Down
2 changes: 1 addition & 1 deletion moments/templates/main/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<div class="card-body">
<div class="text-center">
<a class="thumbnail" href="{{ url_for('.show_photo', photo_id=photo.id) }}" target="_blank">
<img class="img-fluid" src="{{ url_for('.get_image', filename=photo.filename_m) }}">
<img class="img-fluid" src="{{ url_for('.get_image', filename=photo.filename_m) }}" alt="{{ photo.description}}">
</a>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion moments/templates/main/photo.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div class="col-lg-8">
<div class="photo">
<a href="{{ url_for('.get_image', filename=photo.filename) }}" target="_blank">
<img class="img-fluid" src="{{ url_for('.get_image', filename=photo.filename_m) }}">
<img class="img-fluid" src="{{ url_for('.get_image', filename=photo.filename_m) }}" alt="{{ photo.description}}">
</a>
<span class="photo-bottom"></span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion moments/templates/main/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ <h5>{{ results|length }} results</h5>
{{ user_card(item) }}
{% else %}
<a class="badge text-bg-light rounded-pill" href="{{ url_for('.show_tag', tag_id=item.id) }}">
{{ item.name }} {{ item.photos|length }}
{{ item.name }} {{ item.photos_count }}
</a>
{% endif %}
{% endfor %}
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,5 @@ zipp==3.21.0; python_version < "3.10" \
--hash=sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4 \
--hash=sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931
--index-url https://pypi.python.org/simple

azure-cognitiveservices-vision-computervision