-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.py
More file actions
64 lines (52 loc) · 2.08 KB
/
api.py
File metadata and controls
64 lines (52 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from flask import Flask, request, jsonify
import numpy as np
import pickle
import os
import io
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2, preprocess_input
from tensorflow.keras.preprocessing import image
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import GlobalMaxPooling2D
from sklearn.neighbors import NearestNeighbors
app = Flask(__name__)
# Config
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
INDEX_PATH = os.path.join(BASE_DIR, 'index', 'features.pkl')
FILES_PATH = os.path.join(BASE_DIR, 'index', 'filenames.pkl')
IMG_SIZE = (224, 224)
# Load Model & Index
base_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
base_model.trainable = False
model = Sequential([base_model, GlobalMaxPooling2D()])
features = pickle.load(open(INDEX_PATH, 'rb'))
filenames = pickle.load(open(FILES_PATH, 'rb'))
neighbors = NearestNeighbors(n_neighbors=5, metric='euclidean', algorithm='brute')
neighbors.fit(features)
@app.route('/search', methods=['POST'])
def search():
"""
Accepts an image upload and returns similar image filenames.
"""
if 'image' not in request.files:
return jsonify({"error": "No image uploaded"}), 400
# Process Image
file = request.files['image']
img = image.load_img(io.BytesIO(file.read()), target_size=IMG_SIZE)
img_array = image.img_to_array(img)
expanded = np.expand_dims(img_array, axis=0)
preprocessed = preprocess_input(expanded)
# Extract Features
query_vector = model.predict(preprocessed, verbose=0).flatten()
query_vector = query_vector / np.linalg.norm(query_vector)
# Find Neighbors
distances, indices = neighbors.kneighbors([query_vector])
results = []
for i in range(len(indices[0])):
idx = indices[0][i]
results.append({
"filename": filenames[idx],
"score": float(1 - distances[0][i]) # Similarity Score
})
return jsonify(results)
if __name__ == '__main__':
app.run(port=5001, debug=True)