From 76f36c6c5dafe754b066903b1ee8ecdd1b92dcab Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 16 Dec 2018 20:01:23 +0100 Subject: faceSearch client --- client/faceSearch/faceSearch.result.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 client/faceSearch/faceSearch.result.js (limited to 'client/faceSearch/faceSearch.result.js') diff --git a/client/faceSearch/faceSearch.result.js b/client/faceSearch/faceSearch.result.js new file mode 100644 index 00000000..844a5a70 --- /dev/null +++ b/client/faceSearch/faceSearch.result.js @@ -0,0 +1,30 @@ +import React, { Component } from 'react' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' + +import * as actions from './faceSearch.actions' + +class FaceSearchResult extends Component { + componentDidMount() { + } + + render() { + return ( +
+ Result here +
+ ) + } +} + +const mapStateToProps = state => ({ + query: state.faceSearch.query, + result: state.faceSearch.result, + options: state.faceSearch.options, +}) + +const mapDispatchToProps = dispatch => ({ + actions: bindActionCreators({ ...actions }, dispatch), +}) + +export default connect(mapStateToProps, mapDispatchToProps)(FaceSearchResult) -- cgit v1.2.3-70-g09d2 From d7df4ee5b9e24a9cdf2bf4d1bc2e73e97352afdc Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 17 Dec 2018 01:02:40 +0100 Subject: searches execute --- client/actions.js | 6 +----- client/faceSearch/faceSearch.result.js | 35 ++++++++++++++++++++++++++++++---- megapixels/app/models/sql_factory.py | 5 +++-- megapixels/app/server/api.py | 9 +++++---- site/assets/css/applets.css | 17 +++++++++++++++++ 5 files changed, 57 insertions(+), 15 deletions(-) (limited to 'client/faceSearch/faceSearch.result.js') diff --git a/client/actions.js b/client/actions.js index 37b4eb2e..bb011838 100644 --- a/client/actions.js +++ b/client/actions.js @@ -1,9 +1,5 @@ import * as faceSearch from './faceSearch/faceSearch.actions' -// import * as review from './review/review.actions' -// import * as metadata from './metadata/metadata.actions' export { - // search, - // review, - // metadata, + faceSearch } diff --git a/client/faceSearch/faceSearch.result.js b/client/faceSearch/faceSearch.result.js index 844a5a70..2b223a46 100644 --- a/client/faceSearch/faceSearch.result.js +++ b/client/faceSearch/faceSearch.result.js @@ -1,17 +1,44 @@ import React, { Component } from 'react' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' +import { courtesyS } from '../util' import * as actions from './faceSearch.actions' class FaceSearchResult extends Component { - componentDidMount() { - } - render() { + const { dataset } = this.props.payload + const { distances, results } = this.props.result + if (!results) { + return ( +
+ ) + } + if (!this.props.result.results.length) { + return ( +
No results
+ ) + } + const els = results.map((result, i) => { + const distance = distances[i] + const { uuid } = result.uuid + const { fullname, gender, description, images } = result.identity + return ( +
+ + {fullname} {'('}{gender}{')'}
+ {description}
+ {courtesyS(images, 'image')}
+ {distance} +
+ ) + }) + return (
- Result here +
+ {els} +
) } diff --git a/megapixels/app/models/sql_factory.py b/megapixels/app/models/sql_factory.py index 0f7e73a0..9a44941b 100644 --- a/megapixels/app/models/sql_factory.py +++ b/megapixels/app/models/sql_factory.py @@ -83,8 +83,8 @@ class SqlDataset: def get_identity(self, id): table = self.get_table('identity_meta') - identity = table.query.filter(table.image_id >= id).order_by(table.image_id.asc()).first().toJSON() - print(identity) + # id += 1 + identity = table.query.filter(table.image_id <= id).order_by(table.image_id.desc()).first().toJSON() return { 'uuid': self.select('uuids', id), 'identity': identity, @@ -100,6 +100,7 @@ class SqlDataset: # for obj in session.query(table).filter_by(id=id): print(table) obj = session.query(table).filter(table.id == id).first() + session.close() return obj.toJSON() def get_table(self, type): diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index 36563910..2f78ecd3 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -70,7 +70,7 @@ def upload(name): query = np.array([ vec ]).astype('float32') # query FAISS! - distances, indexes = faiss_dataset.search(query, 5) + distances, indexes = faiss_dataset.search(query, 10) if len(indexes) == 0: print("weird, no results!") @@ -85,6 +85,7 @@ def upload(name): return [] lookup = {} + ids = [i+1 for i in indexes] for _d, _i in zip(distances, indexes): lookup[_i+1] = _d @@ -97,13 +98,13 @@ def upload(name): query = { 'timing': time.time() - start, } - results = [ dataset.get_identity(index) for index in indexes ] + results = [ dataset.get_identity(id) for id in ids ] print(results) return jsonify({ 'results': results, - # 'distances': distances.tolist(), - # 'indexes': indexes.tolist(), + 'distances': distances.tolist(), + 'indexes': indexes.tolist(), }) @api.route('/dataset//name', methods=['GET']) diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index 54508f44..a01703d5 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -17,6 +17,23 @@ justify-content: flex-start; } +.results { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} +.results > div { + width: 200px; + margin-left: 20px; + margin-bottom: 40px; + font-size: 8pt; +} +.results > div img { + margin-bottom: 4px; +} +.results > div:nth-child(3n+1) { + margin-left: 0; +} .query h2 { margin-top: 0; padding-top: 0; } -- cgit v1.2.3-70-g09d2 From a2d4ad0499e4ee4f3f528b2ed7bc162d61026d09 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 17 Dec 2018 01:13:32 +0100 Subject: build --- client/faceSearch/faceSearch.result.js | 14 +++++++++++++- megapixels/app/server/api.py | 14 ++++++++++---- site/assets/css/applets.css | 3 +++ 3 files changed, 26 insertions(+), 5 deletions(-) (limited to 'client/faceSearch/faceSearch.result.js') diff --git a/client/faceSearch/faceSearch.result.js b/client/faceSearch/faceSearch.result.js index 2b223a46..1882def0 100644 --- a/client/faceSearch/faceSearch.result.js +++ b/client/faceSearch/faceSearch.result.js @@ -5,10 +5,22 @@ import { courtesyS } from '../util' import * as actions from './faceSearch.actions' +const errors = { + 'bbox': "Sorry, we couldn't find a face in that image. Please choose an image where the face is large and clear.", + 'nomatch': "We didn't find a match.", + 'default': "There was an error!", +} + class FaceSearchResult extends Component { render() { const { dataset } = this.props.payload - const { distances, results } = this.props.result + const { distances, results, error } = this.props.result + if (error) { + let errorMessage = errors[error.message] || errors.default + return ( +
{errorMessage}
+ ) + } if (!results) { return (
diff --git a/megapixels/app/server/api.py b/megapixels/app/server/api.py index 2f78ecd3..bc60118c 100644 --- a/megapixels/app/server/api.py +++ b/megapixels/app/server/api.py @@ -58,6 +58,10 @@ def upload(name): # get detection as BBox object bboxes = detector.detect(im_np, largest=True) + if not len(bboxes): + return jsonify({ + 'error': 'bbox' + }) bbox = bboxes[0] dim = im_np.shape[:2][::-1] bbox = bbox.to_dim(dim) # convert back to real dimensions @@ -73,16 +77,18 @@ def upload(name): distances, indexes = faiss_dataset.search(query, 10) if len(indexes) == 0: - print("weird, no results!") - return [] + return jsonify({ + 'error': 'nomatch' + }) # get the results for this single query... distances = distances[0] indexes = indexes[0] if len(indexes) == 0: - print("no results!") - return [] + return jsonify({ + 'error': 'nomatch' + }) lookup = {} ids = [i+1 for i in indexes] diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index a01703d5..ecba518c 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -30,6 +30,9 @@ } .results > div img { margin-bottom: 4px; + width: 200px; + height: 200px; + background: rgba(255,255,255,0.05); } .results > div:nth-child(3n+1) { margin-left: 0; -- cgit v1.2.3-70-g09d2