├── test-stencils ├── invalid-digital-heart-stencil.png ├── valid-digital-heart-stencil.png ├── invalid-black-lives-matter-stencil.png ├── valid-black-lives-matter-stencil.png ├── valid-end-mass-surveillance-stencil.png ├── invalid-end-mass-surveillance-stencil.png └── invalid-black-lives-matter-stencil-inverse.png ├── .travis.yml ├── app.py ├── stencil_validator.py ├── .gitignore ├── README.md ├── test_stencil_validator.py └── xedgex.py /test-stencils/invalid-digital-heart-stencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/invalid-digital-heart-stencil.png -------------------------------------------------------------------------------- /test-stencils/valid-digital-heart-stencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/valid-digital-heart-stencil.png -------------------------------------------------------------------------------- /test-stencils/invalid-black-lives-matter-stencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/invalid-black-lives-matter-stencil.png -------------------------------------------------------------------------------- /test-stencils/valid-black-lives-matter-stencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/valid-black-lives-matter-stencil.png -------------------------------------------------------------------------------- /test-stencils/valid-end-mass-surveillance-stencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/valid-end-mass-surveillance-stencil.png -------------------------------------------------------------------------------- /test-stencils/invalid-end-mass-surveillance-stencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/invalid-end-mass-surveillance-stencil.png -------------------------------------------------------------------------------- /test-stencils/invalid-black-lives-matter-stencil-inverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drewrwilson/stencilvalidator/HEAD/test-stencils/invalid-black-lives-matter-stencil-inverse.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: 2 | - python 3 | 4 | env: 5 | - PYTHONPATH=$PYTHONPATH:/usr/lib/pyshared/python2.7 6 | 7 | addons: 8 | apt: 9 | packages: 10 | - libopencv-dev 11 | - python-opencv 12 | 13 | script: 14 | - python test_stencil_validator.py 15 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import sys 4 | import cv2 5 | 6 | sys.argv.pop(0) 7 | 8 | for arg in sys.argv: 9 | print 'Looking at "' + arg + '".' 10 | 11 | image = cv2.imread(arg) 12 | image = cv2.bitwise_not(image) 13 | detector = cv2.SimpleBlobDetector() 14 | blobs = detector.detect(image) 15 | number_of_blobs = len(blobs) 16 | valid = number_of_blobs == 0 17 | 18 | print str(valid) 19 | print 'Found ' + str(number_of_blobs) + ' blobs.' 20 | print '\n' 21 | -------------------------------------------------------------------------------- /stencil_validator.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | 3 | class StencilValidator: 4 | 5 | def __init__(self, path): 6 | self.path = path 7 | 8 | def image(self): 9 | cv2.imread(self.path) 10 | 11 | def inverted_image(self): 12 | cv2.bitwise_not(self.image) 13 | 14 | def detector(self): 15 | cv2.SimpleBlobDetector() 16 | 17 | def number_of_blobs(self): 18 | len(self.detector.detect(self.image)) 19 | 20 | def valid(self): 21 | return self.number_of_blobs == 0 # we don't yet know if this is the correct, may need to update this later 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | *.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stencil Validator [![Build Status](https://travis-ci.org/drewrwilson/stencilvalidator.svg)](https://travis-ci.org/drewrwilson/stencilvalidator) 2 | 3 | A tool for checking whether a design is a valid stencil or not. 4 | 5 | This is a work in progress. Alpha at best. 6 | 7 | ## Setup 8 | 9 | For osx. 10 | 11 | * Get homebrew! 12 | * Install python! `brew install python` 13 | * Give you homebrew the power of science! `brew tap homebrew/science` 14 | * Install opencv `brew install opencv` 15 | 16 | ## Testing 17 | 18 | There are a number of example stencils in the `test-stencils` directory. The 19 | filename indicates whether or not the stencil is valid 20 | (eg `valid-black-lives-matter` vs `invalid-black-lives-matter`). 21 | The invalid ones are just modified versions of the valid ones that include 22 | mistakes like shapes inside of shapes or letters that have sections without 23 | bridges. 24 | 25 | To run the tests: 26 | `python test_stencil_validator.py` 27 | -------------------------------------------------------------------------------- /test_stencil_validator.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from stencil_validator import StencilValidator 3 | 4 | class TestStencilValidator(unittest.TestCase): 5 | 6 | def test_black_lives_matter_is_invalid(self): 7 | validator = StencilValidator('test-stencils/invalid-black-lives-matter-stencil.png') 8 | self.assertFalse(validator.valid()) 9 | 10 | def test_digital_heart_is_invalid(self): 11 | validator = StencilValidator('test-stencils/invalid-digital-heart-stencil.png') 12 | self.assertFalse(validator.valid()) 13 | 14 | def test_end_mass_surveillance_is_invalid(self): 15 | validator = StencilValidator('test-stencils/invalid-end-mass-surveillance-stencil.png') 16 | self.assertFalse(validator.valid()) 17 | 18 | def test_another_black_lives_matter_is_valid(self): 19 | validator = StencilValidator('test-stencils/valid-black-lives-matter-stencil.png') 20 | self.assertTrue(validator.valid()) 21 | 22 | def test_another_digital_heart_is_valid(self): 23 | validator = StencilValidator('test-stencils/valid-digital-heart-stencil.png') 24 | self.assertTrue(validator.valid()) 25 | 26 | def test_end_mass_surveillance_is_valid(self): 27 | validator = StencilValidator('test-stencils/valid-end-mass-surveillance-stencil.png') 28 | self.assertTrue(validator.valid()) 29 | 30 | if __name__ == '__main__': 31 | unittest.main() 32 | -------------------------------------------------------------------------------- /xedgex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | This sample demonstrates Canny edge detection. 5 | Usage: 6 | edge.py [