diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..085ebce
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,108 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# dotenv
+.env
+
+# virtualenv
+.venv
+venv/
+ENV/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+
+
+.pytest_cache
+
+.benchmarks/
+tests/benchmarks/data/*
+tests/fixtures/mask* 
diff --git a/README.md b/README.md
index 45e714c..8068332 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,22 @@ PythonSIFT has been reimplemented (and greatly improved!) in Python 3. You can f
 
 Last tested successfully using `Python 3.7.6` and `OpenCV-Python 4.2.0`.
 
+## Installation
+
+```
+$ git clone https://github.com/rmislam/PythonSIFT.git
+$ cd PythonSIFT
+$ pip install -U pip
+$ pip install -e .[examples]
+```
+
+## Examples
+
+```bash
+cd examples
+python template_matching_demo.py
+```
+
 ## Usage
 
 ```python
diff --git a/box.png b/examples/img/box.png
similarity index 100%
rename from box.png
rename to examples/img/box.png
diff --git a/box_in_scene.png b/examples/img/box_in_scene.png
similarity index 100%
rename from box_in_scene.png
rename to examples/img/box_in_scene.png
diff --git a/template_matching_demo.py b/examples/template_matching_demo.py
similarity index 94%
rename from template_matching_demo.py
rename to examples/template_matching_demo.py
index 2bff94b..54c04be 100644
--- a/template_matching_demo.py
+++ b/examples/template_matching_demo.py
@@ -7,8 +7,8 @@
 
 MIN_MATCH_COUNT = 10
 
-img1 = cv2.imread('box.png', 0)           # queryImage
-img2 = cv2.imread('box_in_scene.png', 0)  # trainImage
+img1 = cv2.imread('img/box.png', 0)           # queryImage
+img2 = cv2.imread('img/box_in_scene.png', 0)  # trainImage
 
 # Compute SIFT keypoints and descriptors
 kp1, des1 = pysift.computeKeypointsAndDescriptors(img1)
diff --git a/pysift/__init__.py b/pysift/__init__.py
new file mode 100644
index 0000000..a3df621
--- /dev/null
+++ b/pysift/__init__.py
@@ -0,0 +1,7 @@
+"""pysift."""
+
+import pkg_resources
+
+from pysift.pysift import computeKeypointsAndDescriptors
+
+version = pkg_resources.get_distribution(__package__).version
diff --git a/pysift.py b/pysift/pysift.py
similarity index 100%
rename from pysift.py
rename to pysift/pysift.py
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..b5113a9
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,46 @@
+"""Setup for pysift."""
+
+from setuptools import find_packages, setup
+
+with open("README.md") as f:
+    readme = f.read()
+
+# Runtime requirements.
+inst_reqs = [
+    "numpy",
+    "opencv-python",
+]
+
+extra_reqs = {
+    "test": ["pytest", "pytest-benchmark", "pytest-cov"],
+    "dev": ["pytest", "pytest-benchmark", "pytest-cov"],
+    "examples": ["matplotlib"],
+    "docs": ["mkdocs"],
+}
+
+setup(
+    name="pysift",
+    version="0.0.1",
+    python_requires=">=3.5",
+    description="Python implementation of the SIFT algorithm.",
+    long_description=readme,
+    long_description_content_type="text/markdown",
+    classifiers=[
+        "Intended Audience :: Information Technology",
+        "Intended Audience :: Science/Research",
+        "License :: OSI Approved :: MIT License",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.6",
+        "Topic :: Scientific/Engineering",
+    ],
+    keywords="Image processing",
+    author="Russ Islam",
+    author_email="russmislam@gmail.com",
+    url="https://github.com/rmislam/PythonSIFT",
+    license="MIT",
+    packages=find_packages(exclude=["ez_setup", "examples", "tests"]),
+    include_package_data=True,
+    zip_safe=True,
+    install_requires=inst_reqs,
+    extras_require=extra_reqs,
+)