Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
390ccac
new: use flask cli for interface
rachmadaniHaryono Feb 2, 2019
1c73591
new: app models
rachmadaniHaryono Feb 2, 2019
58e5eaf
new: flask cli interface
rachmadaniHaryono Feb 2, 2019
f138310
new: simple main test
rachmadaniHaryono Feb 2, 2019
b38c7d9
new: merge cli test
rachmadaniHaryono Feb 5, 2019
9481407
new: docs: permission error fix
rachmadaniHaryono Feb 5, 2019
e9dc512
fix: version output result
rachmadaniHaryono Feb 6, 2019
564a4b4
new: docs: main func
rachmadaniHaryono Feb 6, 2019
8027c71
new: test: travis
rachmadaniHaryono Feb 6, 2019
7f2408d
fix: docs: readme syntax
rachmadaniHaryono Feb 6, 2019
707114a
new: dev: add opencv package
rachmadaniHaryono Feb 6, 2019
e868d2c
chg: docs: syntax highlight code
rachmadaniHaryono Feb 6, 2019
1700721
fix: docs: triangles_from_keypoints
rachmadaniHaryono Feb 6, 2019
39f1ac0
new: test: checksum model
rachmadaniHaryono Feb 6, 2019
ea87ccc
new: test: checksum list
rachmadaniHaryono Feb 6, 2019
1d9ed80
new: dev: add sqlalchemy_utils
rachmadaniHaryono Feb 6, 2019
263294d
new: dev: image api
rachmadaniHaryono Feb 6, 2019
7687688
new: dev: add pillow
rachmadaniHaryono Feb 6, 2019
787f357
new: dev: add appdirs
rachmadaniHaryono Feb 6, 2019
9cffc84
fix: dev: checksum get api exp res
rachmadaniHaryono Feb 6, 2019
da538ad
new: dev: data dir
rachmadaniHaryono Feb 6, 2019
0b9dacd
new: dev: home page
rachmadaniHaryono Feb 6, 2019
288aabf
new: dev: upload file api
rachmadaniHaryono Feb 6, 2019
cb301c8
new: dev: checksum duplicate !wip
rachmadaniHaryono Feb 6, 2019
fd2fd12
fix: test: doctest
rachmadaniHaryono Feb 6, 2019
06987de
new: dev: checksum duplicate !wip
rachmadaniHaryono Feb 6, 2019
8a44f0b
fix: dev: range list
rachmadaniHaryono Feb 6, 2019
7717f4e
chg: dev: remove unused test
rachmadaniHaryono Feb 6, 2019
25e9781
new: dev: checksum duplicate
rachmadaniHaryono Feb 7, 2019
9193f2f
new: dev: get_duplicate from model instead from filename
rachmadaniHaryono Feb 7, 2019
b08561e
fix: dev: get duplicate with checksum model
rachmadaniHaryono Feb 7, 2019
2f3ede2
chg: dev: models
rachmadaniHaryono Feb 7, 2019
f3ac86c
new: dev: interface
rachmadaniHaryono Feb 7, 2019
5415b02
chg: dev: move get_duplicate func to main module
rachmadaniHaryono Feb 7, 2019
60bae3d
chg: dev: use phash_triangles (faster)
rachmadaniHaryono Feb 7, 2019
1b46997
fix: dev: json api for duplicate endpoint
rachmadaniHaryono Feb 7, 2019
7a3ac61
fix: dev: get_duplicate
rachmadaniHaryono Feb 7, 2019
ba069dc
fix: test: upload api
rachmadaniHaryono Feb 7, 2019
db47c7d
chg: dev: remove unused table
rachmadaniHaryono Feb 7, 2019
78998ee
fix: dev: similar func
rachmadaniHaryono Feb 10, 2019
379b8be
Merge remote-tracking branch 'upstream/master' into feature/basic-server
rachmadaniHaryono Aug 5, 2019
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
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
language: python
python:
- "3.6"
# command to install dependencies
install:
- python setup.py develop
# command to run tests
script:
- pytest --doctest-module
75 changes: 37 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,23 @@ Instead of running these commands manually you can run the ./setup.sh script whi

Or if you want to run the commands manually...

```
# From the root of the repo go to ./fullEndToEndDemo
cd ./fullEndToEndDemo

# Grab all the dependencies, this install is pretty huge
sudo apt-get update
sudo apt-get install git cmake g++ redis-server libboost-all-dev libopencv-dev python-opencv python-numpy python-scipy -y

#Make it
cmake .
make

# This step is optional. It removes a pointless annoying error opencv spits out
# About: https://stackoverflow.com/questions/12689304/ctypes-error-libdc1394-error-failed-to-initialize-libdc1394
sudo ln /dev/null /dev/raw1394

# Then run either ./runDemo1.sh or ./runDemo2.sh to run the demo


```console
$ # From the root of the repo go to ./fullEndToEndDemo
$ cd ./fullEndToEndDemo
$
$ # Grab all the dependencies, this install is pretty huge
$ sudo apt-get update
$ sudo apt-get install git cmake g++ redis-server libboost-all-dev libopencv-dev python-opencv python-numpy python-scipy -y
$
$ #Make it
$ cmake .
$ make
$
$ # This step is optional. It removes a pointless annoying error opencv spits out
$ # About: https://stackoverflow.com/questions/12689304/ctypes-error-libdc1394-error-failed-to-initialize-libdc1394
$ sudo ln /dev/null /dev/raw1394
$
$ # Then run either ./runDemo1.sh or ./runDemo2.sh to run the demo
```

# Python setup
Expand All @@ -58,19 +56,19 @@ This setup was tested on a newly deployed vm on Ubuntu 18.04 LTS, YMMV on differ

To use python package, do the following:

```
sudo apt-get update
sudo apt-get install python3-pip python3-opencv redis-server -y

# On some systems this path is missing
# read more here: https://github.com/pypa/pip/issues/3813
PATH="$PATH:~/.local/bin"

#cd to project directory
pip3 install .
```console
$ sudo apt-get update
$ sudo apt-get install python3-pip python3-opencv redis-server -y
$
$ # On some systems this path is missing
$ # read more here: https://github.com/pypa/pip/issues/3813
$ PATH="$PATH:~/.local/bin"
$
$ # cd to project directory
$ pip3 install .
```

You also need install redis.
if you got permission error, install it under virtual env or use `--user` flag.

# Demo 1

Expand All @@ -94,8 +92,8 @@ The demo takes <s>2 minutes</s> (1 minute 38 seconds*) to run on a quad core VM

*Thanks to [meowcoder](https://github.com/meowcoder) for the speed up!

```
user@instance-1:~/transformationInvariantImageSearch/fullEndToEndDemo$ time ./runDemo1.sh
```console
$ time ./fullEndToEndDemo/runDemo1.sh
Loading image: inputImages/cat1.png ... done
Added 46725 image fragments to DB
Loading image: inputImages/cat2.png ... done
Expand Down Expand Up @@ -135,8 +133,8 @@ sys 0m6.592s
python example

```console
$ time transformation-invariant-image-search insert fullEndToEndDemo/inputImages/cat* && \
time transformation-invariant-image-search lookup fullEndToEndDemo/inputImages/cat_original.png
$ time transformation-invariant-image-search insert fullEndToEndDemo/inputImages/cat* && \
$ time transformation-invariant-image-search lookup fullEndToEndDemo/inputImages/cat_original.png

loading fullEndToEndDemo/inputImages/cat1.png
100%|██| 3/3 [00:07<00:00, 2.66s/it]
Expand Down Expand Up @@ -219,8 +217,8 @@ Here the two images mona.jpg and van_gogh.jpg are inserted into the database and

*Thanks to [meowcoder](https://github.com/meowcoder) for the speed up!

```
user@instance-1:~/transformationInvariantImageSearch/fullEndToEndDemo$ time ./runDemo2.sh
```console
$ time ./fullEndToEndDemo/runDemo2.sh
Loading image: ./inputImages/mona.jpg ... done
Added 26991 image fragments to DB
Loading image: ./inputImages/van_gogh.jpg ... done
Expand All @@ -239,8 +237,9 @@ sys 0m18.224s
python example

```console
$ time transformation-invariant-image-search insert ./fullEndToEndDemo/inputImages/mona.jpg ./fullEndToEndDemo/inputImages/van_gogh.jpg && \
time transformation-invariant-image-search lookup ./fullEndToEndDemo/inputImages/monaComposite.jpg
$ time transformation-invariant-image-search insert \
$ ./fullEndToEndDemo/inputImages/mona.jpg ./fullEndToEndDemo/inputImages/van_gogh.jpg && \
$ time transformation-invariant-image-search lookup ./fullEndToEndDemo/inputImages/monaComposite.jpg

loading ./fullEndToEndDemo/inputImages/mona.jpg
100%|███| 3/3 [00:03<00:00, 1.24s/it]
Expand Down
19 changes: 14 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#!/usr/bin/env python
from setuptools import setup, find_packages

"""
TODO
- copy or link `python` folder to `transformation_invariant_image_search`
"""

def readme():
with open('README.md') as f:
Expand All @@ -29,16 +25,29 @@ def readme():
zip_safe=False,
python_requires='>=3.6',
install_requires=[
'appdirs>=1.4.3',
'Flask-Admin==1.5.3',
'Flask-SQLAlchemy>=2.3.2',
'Flask>=1.0.2',
'hiredis',
'numpy',
'opencv-python>=4.0.0.21',
'Pillow>=5.4.1',
'redis',
'scikit-learn',
'scipy',
'SQLAlchemy-Utils>=0.33.11',
'tqdm>=4.29.1',
],
extras_require={
'dev': [
'docutils==0.14',
'pytest==4.2.0',
],
},
entry_points={
'console_scripts': [
'transformation-invariant-image-search = transformation_invariant_image_search.main:main']
'transformation-invariant-image-search = transformation_invariant_image_search.main:cli']
},
classifiers=[
'Development Status :: 3 - Alpha',
Expand Down
98 changes: 98 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import json
import os
import shutil
import tempfile

from click.testing import CliRunner
from flask import current_app
import click
import pytest

from transformation_invariant_image_search import main


@pytest.fixture
def client():
db_fd, config_db = tempfile.mkstemp()
image_fd = tempfile.mkdtemp()
db_uri = 'sqlite:///{}'.format(config_db)
app = main.create_app(db_uri=db_uri, image_dir=image_fd)
app.config['DATABASE'] = config_db
app.config['TESTING'] = True
client = app.test_client()

yield client

os.close(db_fd)
os.unlink(app.config['DATABASE'])
shutil.rmtree(image_fd)


def test_empty_db(client):
"""Start with a blank database."""
rv = client.get('/')
assert b'Home - Transformation Invariant Image Search' in rv.data


def test_checksum_get(client):
"""test checksum with a blank database."""
url = '/api/checksum'
rv = client.get(url)
assert rv.get_json() == []


def test_checksum_post(client):
"""Start with a blank database."""
csm_value = '54abb6e1eb59cccf61ae356aff7e491894c5ca606dfda4240d86743424c65faf'
url = '/api/checksum'
exp_dict = dict(value=csm_value, id=1, ext='png', trash=False)
rv = client.post(url, data=dict(value=csm_value, ext='png'))
assert rv.get_json() == exp_dict
rv = client.get(url)
assert rv.get_json() == [exp_dict]


def test_image_post(client):
url = '/api/image'
filename = 'fullEndToEndDemo/inputImages/cat_original.png'
csm_value = '54abb6e1eb59cccf61ae356aff7e491894c5ca606dfda4240d86743424c65faf'
ext = 'png'
exp_dict = dict(id=1, value=csm_value, ext=ext, trash=False)
rv = client.post(url)
assert rv.get_json()['error']
file_data = {'file': open(filename, 'rb')}
rv = client.post(url, data=file_data)
post_exp_dict = exp_dict.copy()
post_exp_dict['url'] = ['http://localhost/i/{}.{}'.format(csm_value, ext)]
assert rv.get_json() == post_exp_dict
image_dir = client.application.config.get('IMAGE_DIR')
exp_dst_file = os.path.join(image_dir, csm_value[:2], '{}.{}'.format(csm_value, ext))
assert os.path.isfile(exp_dst_file)
rv = client.get(url)
assert rv.get_json() == [exp_dict]


def test_upload_api(client):
filename = 'fullEndToEndDemo/inputImages/cat1.png'
upload_url = '/api/image'
rv = client.post(upload_url, data={'file': open(filename, 'rb')})
assert rv.get_json() == {
'ext': 'png', 'id': 1, 'trash': False,
'url': ['http://localhost/i/4aba099f752d609aad2ed4c28f972ae96d02ad2579d0dd3f16b1ac29a88caf6d.png'],
'value': '4aba099f752d609aad2ed4c28f972ae96d02ad2579d0dd3f16b1ac29a88caf6d'
}


@pytest.mark.parametrize(
'args,word',
[
('--help', 'Usage:'),
('--version', 'Transformation Invariant Image Search')
]
)
def test_cli(args, word):
runner = CliRunner()
result = runner.invoke(main.cli, [args])
assert result.exit_code == 0
if word is not None:
assert word in result.output
13 changes: 13 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
def test_checksum():
from transformation_invariant_image_search import models, main
app = main.create_app(db_uri='sqlite://')
csm_value = '54abb6e1eb59cccf61ae356aff7e491894c5ca606dfda4240d86743424c65faf'
with app.app_context():
models.DB.create_all()
m = models.Checksum(value=csm_value, ext='png')
models.DB.session.add(m)
models.DB.session.commit()
assert m.id == 1

res = models.DB.session.query(models.Checksum).filter_by(id=1).first()
assert res.value == csm_value
10 changes: 10 additions & 0 deletions transformation_invariant_image_search/keypoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ def recolour(img, gauss_width=41):


def compute_keypoints(img):
"""Compute keypoints.

>>> filename = 'fullEndToEndDemo/inputImages/cat_original.png'
>>> img = cv2.imread(filename)
>>> res = compute_keypoints(img)
>>> len(res) == 50
True
>>> sorted(res)[0]
(1.0, 26.0)
"""
gauss_width = 21
img = recolour(img, gauss_width)
b, _, _ = cv2.split(img)
Expand Down
Loading