Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web app using Django and an Android app #26

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8039b5c
Refactored code
ymittal Dec 23, 2016
3cd1687
Added Django project
ymittal Dec 23, 2016
dfdee59
Added .gitignore
ymittal Dec 23, 2016
65414c7
Deleted sudoku/net file
ymittal Dec 23, 2016
090f960
Returning non Json result
ymittal Dec 23, 2016
a74ebb3
Init Android project
ymittal Dec 23, 2016
cacdd14
Established a connection b/w Django and Android app, simple http get …
ymittal Dec 23, 2016
a36d9cb
Experimenting http post with image
ymittal Dec 26, 2016
798a5c5
Capturing pic, saving to cache, making API call
ymittal Dec 26, 2016
55eb35e
Able to save to disk and POST full-sized image
ymittal Dec 26, 2016
16cb278
Jsonify response
ymittal Dec 27, 2016
b5c52f0
Handled more exceptions
ymittal Dec 27, 2016
8cca517
Added Json POJOs and fixed Retrofit response
ymittal Dec 27, 2016
0f9d8f3
Minor clean up
ymittal Dec 27, 2016
6b39d5f
Printing exceptions for debugging
ymittal Jan 25, 2017
1ba583a
Created README.md for Android
ymittal Jan 25, 2017
74f3915
Added step-by-step demo README
ymittal Jan 25, 2017
960cdfc
Update README.md
ymittal Jan 25, 2017
17c5687
Update README.md
ymittal Jan 25, 2017
2be624d
Update README.md
ymittal Jan 25, 2017
d3b7dcf
Update README.md
ymittal Jan 25, 2017
ec49a4e
Updated algorithm
ymittal Jan 25, 2017
cda058f
Refactored main python code to /codebase
ymittal Feb 9, 2017
7a46851
Merge branch 'master' of https://github.com/ymittal/snapsudoku
ymittal Feb 9, 2017
d7ac1e8
Removed __init__.py
ymittal Feb 9, 2017
f5b397e
Renamed Django app and a bunch of files
ymittal Feb 9, 2017
5222cf3
Updated README.md
ymittal Feb 9, 2017
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
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
*.pyc
/train/v1_test.tar.bz2
/train/v1_training.tar.bz2
.gitignore
.gitignore.swp
mnist.pkl.gz
save
scripts/validator.py
119 changes: 39 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,57 @@
SnapSudoku
===================
# SnapSudoku

*Take a picture of a Sudoku and have SnapSudoku solve it for you!*
Take a picture of an unsolved Sudoku and have SnapSudoku solve it for you! This repository also consists of an Android application which harnesses an API endpoint created using [Django REST Framework](http://www.django-rest-framework.org/).

## How to use

----------
TODO:
---------
- [ ] Improve algorithm to get better Sudoku Grid extraction, make it `more robust against blurs` .
- [ ] Improve `empty cell detection`. Only a basic logic is used right now.
```
$ git clone https://github.com/ymittal/SnapSudoku.git
$ cd SnapSudoku
$ pip install -r requirements.txt
$ python snapsudoku/sudoku.py <path>
```

Prerequisites:
-------------
You can read the directions to test the Android application [**here**](https://github.com/ymittal/SnapSudoku/blob/master/android/README.md).

- Python 2.7 but __not__ Python 3
- Download from [here](https://www.python.org/downloads/)
### Algorithm

- OpenCV
- `sudo apt-get install python-opencv` (preferred)
- Install OpenCV from [here](http://opencv.org/downloads.html)
- Basic image preprocessing - **Thresholding**
- Crop out approx. Sudoku puzzle (largest contour)
- Get the grid square verticles (*need for improvement*)
- Get the largest contour of the image
- Get the largest bounding rectangle within the contour
- Compute the grid corners
- Do a **warp perspective** on the Sudoku
- Extract cells by slicing the grid evenly
- Isolate cells as follows
- Extract the largest connected component, giving more priority to the center pixels
- Remove all major noise in a cell
- Predict digits using a Neural Network

- Numpy (1.11.0)
- `pip install numpy` (preferred)
- You can build it from source [here](https://github.com/numpy/numpy)
The Neural Network created was trained with around 250 digits. The [constants](https://github.com/ymittal/SnapSudoku/blob/master/snapsudoku/networks/net) used in the training phase and the [training dataset](https://github.com/ymittal/SnapSudoku/tree/master/snapsudoku/train) can be found in the repository itself.

How to use:
----------
git clone https://github.com/prajwalkr/SnapSudoku.git
cd SnapSudoku
python sudoku.py <path-to-input-image>
### Working

Here's a Sudoku image from a smartphone:

Working:
-------
> Here's a Sudoku image from a smartphone:
<img src="https://lh3.googleusercontent.com/-rGpsVTsqkYU/VwysnNV6U4I/AAAAAAAAG00/1XVCxhPkVzMTugwy53PUTVu76JtywthyQCLcB/s1000/test1.jpg" alt="Input Image" width="320px">

![Input Sudoku Image](https://lh3.googleusercontent.com/-rGpsVTsqkYU/VwysnNV6U4I/AAAAAAAAG00/1XVCxhPkVzMTugwy53PUTVu76JtywthyQCLcB/s1000/test1.jpg "Input image")![](blob:https%3A//drive.google.com/7556d1d6-752d-4e86-b913-8373d50ebe41)
</br>
The current code produces the following output:

> The current code gives out the following output to the Terminal:
<img src="https://lh3.googleusercontent.com/-PLL7mtKdT68/VxzRU-D1mxI/AAAAAAAAH4s/v2lvYd_mQes3J3ta0PwQ_W2gwxhrVS_VQCLcB/s500/Final+Result.png" alt="Final Result" width="320px">

![Final result](https://lh3.googleusercontent.com/-PLL7mtKdT68/VxzRU-D1mxI/AAAAAAAAH4s/v2lvYd_mQes3J3ta0PwQ_W2gwxhrVS_VQCLcB/s500/Final+Result.png "Final Result")
**Note:** For a detailed step-by-step demo, check out [**this**](https://github.com/ymittal/SnapSudoku/blob/master/snapsudoku/demo/README.md).

Algorithm
-------------
## TODO

> 1. Basic image preprocessing - **Thresholding**.
> 2. Crop out approx. Sudoku puzzle (Largest contour)
> 3. Get the grid square vertices: *(a better way of doing this is required!)* </br>
3.1. Get the **largest contour** of the image.</br>
3.2. Get the largest **bounding rectangle** within the contour.</br>
3.3. Compute the grid corners.
> 4. Do a **Warp perspective** on the sudoku image
> 5. We will extract cells from this, by slicing the sudoku grid evenly.
> 6. Digit isolation in cell is done through a series of steps: </br>
6.1. Extract the **largest connected component** in the image, giving more *priority to the center pixels*. </br>
6.2. Removing all major noise in the cell.
> 7. Predict Digits using a Neural Network.

> The only 3rd party libraries required are *OpenCV, Numpy*. The Neural Network created was trained with around 250 digits. The constants used in the training phase, the training data-set is in this repository itself.

Here are some illustrations of the different stages:
-------

> After Preprocessing:

![After Preprocessing](https://lh3.googleusercontent.com/-hTPN4mSDNiY/Vwy8UgTcxNI/AAAAAAAAG1c/e67gE9TSAKQrcd-ADHmAgOtuMDQPhyCrgCLcB/s500/After+Preprocessing.png "After Preprocessing")

> Final processed Sudoku Grid

![enter image description here](https://lh3.googleusercontent.com/-AcbLo77wYH0/VxtPrbXcAYI/AAAAAAAAH0E/OmEzl2Hn9JkjQTxfdAVTn7ZeN3q3rsutgCLcB/s500/Sudoku+Grid.png "Sudoku Grid Image")

> Here are a few digits after processing the cells:

![Digit 3](https://lh3.googleusercontent.com/-2zxwex6LYnk/VxtQEQH6fDI/AAAAAAAAH0Q/nFmrwIlm7HYV7O2qZEoICQDKF8fcoFKmQCLcB/s100/three.png "Three")![Digit 8](https://lh3.googleusercontent.com/-oPRnuu7XXxc/VwzHKJjnpyI/AAAAAAAAG2o/11FlxwHkkygGEHgoY4NQLZroq-fH6b5MACLcB/s100/eight.png "eight.png")

> Here's a typical empty cell:

![empty cell](https://lh3.googleusercontent.com/-p2bhyuRWptI/VwzHVYrtABI/AAAAAAAAG2w/C_vKYzb75sQ8gcPdf0aaHCjB6dM02du8wCLcB/s100/emptycell.png "emptycell.png")

> Predicted Grid:

![Prediction](https://lh3.googleusercontent.com/-bmiUuMHZtYw/VxtQ8SezWLI/AAAAAAAAH0s/VV8HvATwHEAfhtKJqT6nK-fh0A28E52gwCLcB/s500/Digits.png "Digits")

> Solved Grid:

![Solved Grid](https://lh3.googleusercontent.com/-zWnlGKCz9xs/VxzSmieN5EI/AAAAAAAAH48/DR6t33TSfhgDVe7ew3n0YRKAUJB45rKWACLcB/s500/Solved+Grid.png "Solved Grid")
----------
Contributors
------------------
[cclauss](https://github.com/cclauss) <br/>
[lakshmanaram](https://github.com/lakshmanaram)

I'll be very happy to get new ideas to improve the accuracy and make the application better. Feel free to give a pull request! :smile:
- [ ] Improve algorithm to get better Sudoku grid extraction and make it more robust against blurs.
- [ ] Improve empty cell detection. Only a basic logic is being used right now.

### Contributors

* [prajwalkr](https://github.com/prajwalkr) **Prajwal Renukanand**
* [cclauss](https://github.com/cclauss)
* [lakshmanaram](https://github.com/lakshmanaram)
* [ymittal](https://github.com/ymittal) **Yash Mittal**

We are happy to get new ideas to make the application more accurate. Feel free to submit a pull request or open an issue. :smile:
14 changes: 14 additions & 0 deletions algorithm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
### Algorithm

- Basic image preprocessing - **Thresholding**
- Crop out approx. Sudoku puzzle (largest contour)
- Get the grid square verticles (*need for improvement*)
- Get the largest contour of the image
- Get the largest bounding rectangle within the contour
- Compute the grid corners
- Do a **warp perspective** on the Sudoku
- Extract cells by slicing the grid evenly
- Isolate cells as follows
- Extract the largest connected component, giving more priority to the center pixels
- Remove all major noise in a cell
- Predict digits using a Neural Network
13 changes: 0 additions & 13 deletions algorithm.txt

This file was deleted.

9 changes: 9 additions & 0 deletions android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
22 changes: 22 additions & 0 deletions android/.idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions android/.idea/copyright/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions android/.idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions android/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions android/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions android/.idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions android/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SnapSudoku Android

An Android application to solve an unsolved sudoku by taking its picture

## Getting Started

* Before testing on an emulator, run the Django server as follows. You can access `localhost` at `http://10.0.2.2:8000/` on an Android emulator.

```
$ python manage.py runserver
```
**Note:** You need to turn on camera settings for your emulator.

* If you deployed the Django app, add the URL to the list of `ALLOWED_HOSTS` in [`settings.py`](https://github.com/ymittal/SnapSudoku/blob/master/django_project/settings.py). Additionally, modify the `baseUrl` of `Retrofit.Builder()` in the Java code.

## Authors

Please feel free to reach out to [Yash Mittal]([email protected]) if you have any questions regarding the Android codebase.
1 change: 1 addition & 0 deletions android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
32 changes: 32 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 25
buildToolsVersion "25.0.1"
defaultConfig {
applicationId "com.example.yash.snapsudoku"
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.0.1'
testCompile 'junit:junit:4.12'

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
}
17 changes: 17 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\Yash\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
Loading