From 4e78fcabe911b42211dd3aff0a64365c2f96ad21 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 27 Apr 2019 03:42:44 +0200 Subject: params --- README.md | 18 ++++++++++--- check/app/server/api.py | 67 ++++++++++++++++++++++++++++++++++--------------- client/app.js | 24 ++++++++++-------- 3 files changed, 75 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index e95635f..f4a9103 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,22 @@ DB_PASS=some_new_password #### POST /v1/match -Check if an image is in the database. If no images are found within the similarity threshold, add this image to the database. +Check if an image is in the database. If no images are found within the threshold, this image will be added to the database. -Options: +Form parameters: - `threshold` (default: 6) - Minimum similarity threshold. This is the Hamming distance used for phash comparisons. -- `add` (default: true) - Pass `false` if you do not want the image added to the database. - `limit` (default: 1) - Number of results to return. - `url` - Image URL to fetch and test (will be stored if `add` is true) -- `q` (file) - Uploaded file to test (will not be stored) \ No newline at end of file +- `q` (file) - Uploaded file to test (will not be stored) + +#### POST /v1/similar + +Find similar images to a query image. + +Form parameters: + +- `threshold` (default: 20) - Minimum similarity threshold. +- `limit` (default: 10) - Number of results to return. +- `url` - Image URL to fetch and test (will be stored if `add` is true) +- `q` (file) - Uploaded file to test (will not be stored) diff --git a/check/app/server/api.py b/check/app/server/api.py index 63de5b6..66a0dd1 100644 --- a/check/app/server/api.py +++ b/check/app/server/api.py @@ -15,7 +15,11 @@ from app.utils.file_utils import sha256_stream sanitize_re = re.compile('[\W]+') valid_exts = ['.gif', '.jpg', '.jpeg', '.png'] -LIMIT = 9 +MATCH_THRESHOLD = 20 +MATCH_LIMIT = 10 + +SIMILAR_THRESHOLD = 20 +SIMILAR_LIMIT = 10 api = Blueprint('api', __name__) @@ -26,17 +30,10 @@ def index(): """ return jsonify({ 'status': 'ok' }) -@api.route('/v1/match', methods=['POST']) -def match(): - """ - Search by uploading an image - """ - start = time.time() - +def get_params(default_threshold=MATCH_THRESHOLD, default_limit=MATCH_LIMIT): try: - threshold = int(request.form.get('threshold') or 6) - limit = int(request.form.get('limit') or 1) - add = str(request.form.get('add') or 'true') == 'true' + threshold = int(request.form.get('threshold') or default_threshold) + limit = int(request.form.get('limit') or default_limit) except: return jsonify({ 'success': False, @@ -59,6 +56,7 @@ def match(): 'error': 'not_an_image' }) + raw = None im = Image.open(file.stream).convert('RGB') else: url = request.form.get('url') @@ -81,13 +79,22 @@ def match(): raw = remote_response.read() im = Image.open(io.BytesIO(raw)).convert('RGB') +@api.route('/v1/match', methods=['POST']) +def match(): + """ + Search by uploading an image + """ + start = time.time() + + threshold, limit, raw, im = get_params() + phash = compute_phash_int(im) ext = ext[1:].lower() results = search_by_phash(phash=phash, threshold=threshold, limit=limit) if len(results) == 0: - if add and url: + if url: # hash = sha256_stream(file) hash = sha256_stream(io.BytesIO(raw)) add_phash(sha256=hash, phash=phash, ext=ext, url=url) @@ -97,17 +104,37 @@ def match(): logging.debug('query took {0:.2g} s.'.format(time.time() - start)) - if limit > 1: - return jsonify({ - 'success': True, - 'match': match, - 'results': results, - 'timing': time.time() - start, - }) + return jsonify({ + 'success': True, + 'match': match, + 'results': results, + 'timing': time.time() - start, + }) + +@api.route('/v1/similar', methods=['POST']) +def similar(): + """ + Search by uploading an image + """ + start = time.time() + + threshold, limit, raw, im = get_params(default_threshold=SIMILARITY_THRESHOLD, default_limit=SIMILARITY_LIMIT) + + phash = compute_phash_int(im) + ext = ext[1:].lower() + + results = search_by_phash(phash=phash, threshold=threshold, limit=limit) + + if len(results) == 0: + match = False + else: + match = True + + logging.debug('query took {0:.2g} s.'.format(time.time() - start)) return jsonify({ 'success': True, 'match': match, - 'closest_match': results[0] if len(results) else None, + 'results': results, 'timing': time.time() - start, }) diff --git a/client/app.js b/client/app.js index d18a5aa..b1c5eb4 100644 --- a/client/app.js +++ b/client/app.js @@ -54,7 +54,7 @@ export default class PhashApp extends Component { render() { return (
-

Perceptual Hash Demo

+

Search by Image

{this.renderQuery()} {this.renderResults()}
@@ -72,11 +72,12 @@ export default class PhashApp extends Component { return (
+
) } @@ -122,13 +123,16 @@ export default class PhashApp extends Component { ) } - const { phash, score, sha256, url} = closest_match return (
-
- Closest match: {sha256}
- Score: {score}
- Phash: {phash.toString(16)} + {matches.map(({ phash, score, sha256, url }) => ( +
+
+ Match: {sha256}
+ Score: {score}
+ Phash: {phash.toString(16)} +
+ ))}
) } -- cgit v1.2.3-70-g09d2