]> wolfpit.net Git - hardware/fuck_tomatoes/.git/commitdiff
Refactored image processing into the current project structure
authorunknown <michaelreeves808@gmail.com>
Mon, 25 Feb 2019 06:49:37 +0000 (22:49 -0800)
committerunknown <michaelreeves808@gmail.com>
Mon, 25 Feb 2019 06:49:37 +0000 (22:49 -0800)
19 files changed:
.vscode/.ropeproject/config.py [new file with mode: 0644]
.vscode/.ropeproject/objectdb [new file with mode: 0644]
FuckTomato.py
MaskSettings.json [new file with mode: 0644]
Printer.py
Printer.pyc
Tests.py
User_Interface/Buttons.py
User_Interface/Sliders.py [new file with mode: 0644]
User_Interface/Sliders.pyc [new file with mode: 0644]
settings/frameSettings.pyc
settings/maskSettings.py [new file with mode: 0644]
settings/maskSettings.pyc [new file with mode: 0644]
utils/Detector.py [new file with mode: 0644]
utils/Detector.pyc [new file with mode: 0644]
utils/Gcode.py
utils/Gcode.pyc
utils/MaskProcessing.py [new file with mode: 0644]
utils/MaskProcessing.pyc [new file with mode: 0644]

diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py
new file mode 100644 (file)
index 0000000..dee2d1a
--- /dev/null
@@ -0,0 +1,114 @@
+# The default ``config.py``
+# flake8: noqa
+
+
+def set_prefs(prefs):
+    """This function is called before opening the project"""
+
+    # Specify which files and folders to ignore in the project.
+    # Changes to ignored resources are not added to the history and
+    # VCSs.  Also they are not returned in `Project.get_files()`.
+    # Note that ``?`` and ``*`` match all characters but slashes.
+    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
+    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
+    # '.svn': matches 'pkg/.svn' and all of its children
+    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
+    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
+    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
+                                  '.hg', '.svn', '_svn', '.git', '.tox']
+
+    # Specifies which files should be considered python files.  It is
+    # useful when you have scripts inside your project.  Only files
+    # ending with ``.py`` are considered to be python files by
+    # default.
+    # prefs['python_files'] = ['*.py']
+
+    # Custom source folders:  By default rope searches the project
+    # for finding source folders (folders that should be searched
+    # for finding modules).  You can add paths to that list.  Note
+    # that rope guesses project source folders correctly most of the
+    # time; use this if you have any problems.
+    # The folders should be relative to project root and use '/' for
+    # separating folders regardless of the platform rope is running on.
+    # 'src/my_source_folder' for instance.
+    # prefs.add('source_folders', 'src')
+
+    # You can extend python path for looking up modules
+    # prefs.add('python_path', '~/python/')
+
+    # Should rope save object information or not.
+    prefs['save_objectdb'] = True
+    prefs['compress_objectdb'] = False
+
+    # If `True`, rope analyzes each module when it is being saved.
+    prefs['automatic_soa'] = True
+    # The depth of calls to follow in static object analysis
+    prefs['soa_followed_calls'] = 0
+
+    # If `False` when running modules or unit tests "dynamic object
+    # analysis" is turned off.  This makes them much faster.
+    prefs['perform_doa'] = True
+
+    # Rope can check the validity of its object DB when running.
+    prefs['validate_objectdb'] = True
+
+    # How many undos to hold?
+    prefs['max_history_items'] = 32
+
+    # Shows whether to save history across sessions.
+    prefs['save_history'] = True
+    prefs['compress_history'] = False
+
+    # Set the number spaces used for indenting.  According to
+    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
+    # unit-tests use 4 spaces it is more reliable, too.
+    prefs['indent_size'] = 4
+
+    # Builtin and c-extension modules that are allowed to be imported
+    # and inspected by rope.
+    prefs['extension_modules'] = []
+
+    # Add all standard c-extensions to extension_modules list.
+    prefs['import_dynload_stdmods'] = True
+
+    # If `True` modules with syntax errors are considered to be empty.
+    # The default value is `False`; When `False` syntax errors raise
+    # `rope.base.exceptions.ModuleSyntaxError` exception.
+    prefs['ignore_syntax_errors'] = False
+
+    # If `True`, rope ignores unresolvable imports.  Otherwise, they
+    # appear in the importing namespace.
+    prefs['ignore_bad_imports'] = False
+
+    # If `True`, rope will insert new module imports as
+    # `from <package> import <module>` by default.
+    prefs['prefer_module_from_imports'] = False
+
+    # If `True`, rope will transform a comma list of imports into
+    # multiple separate import statements when organizing
+    # imports.
+    prefs['split_imports'] = False
+
+    # If `True`, rope will remove all top-level import statements and
+    # reinsert them at the top of the module when making changes.
+    prefs['pull_imports_to_top'] = True
+
+    # If `True`, rope will sort imports alphabetically by module name instead
+    # of alphabetically by import statement, with from imports after normal
+    # imports.
+    prefs['sort_imports_alphabetically'] = False
+
+    # Location of implementation of
+    # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
+    # case, you don't have to change this value, unless you're an rope expert.
+    # Change this value to inject you own implementations of interfaces
+    # listed in module rope.base.oi.type_hinting.providers.interfaces
+    # For example, you can add you own providers for Django Models, or disable
+    # the search type-hinting in a class hierarchy, etc.
+    prefs['type_hinting_factory'] = (
+        'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
+
+
+def project_opened(project):
+    """This function is called after opening the project"""
+    # Do whatever you like here!
diff --git a/.vscode/.ropeproject/objectdb b/.vscode/.ropeproject/objectdb
new file mode 100644 (file)
index 0000000..29c40cd
--- /dev/null
@@ -0,0 +1 @@
+\80\ 2}q\ 1.
\ No newline at end of file
index 2e5cbf9167def54848d6bb6150e79cf1e868134e..c28f6b451c8d05ad6ac78fa250c3c6b8d5c0f27f 100644 (file)
@@ -4,7 +4,6 @@ from User_Interface import Draw, MouseManager, Buttons
 start_time = time.time()
 
 cap = cv2.VideoCapture(0)
-ret, frame = cap.read()
 cv2.namedWindow('image')
 printer = Printer.Printer('COM4', (200, 200))
 mouse = MouseManager.MouseManager(printer)
diff --git a/MaskSettings.json b/MaskSettings.json
new file mode 100644 (file)
index 0000000..f5cd938
--- /dev/null
@@ -0,0 +1,7 @@
+{
+    "open": 1,
+    "close": 11,
+    "erode": 10,
+    "dilate": 8,
+    "saturationMin": 170
+}
\ No newline at end of file
index 19a9dc661dc56f9f806160dc11b2856147c235aa..9ab31a725c780f978cd013abe348aca580678d61 100644 (file)
@@ -7,7 +7,7 @@ class Printer():
                self.COM = PrinterCOM
                self.max_X, self.max_Y = bedSize
                self.position = (0,0)
-               self.sendSerial = False
+               self.sendSpike = False
                self.settings = frameSettings.frameSettings()
                self.coeffs = MatrixConversion.find_coeffs(self.settings.image_frame.corners, self.settings.laser_frame.corners) 
                try: self.printerSerial = serial.Serial(PrinterCOM, 115200, timeout = 25)
@@ -42,7 +42,7 @@ class Printer():
        #it overflows the printer's serial buffer because it's a peice of dog shit
        def sendPackage(self, points):
                if points.count > 4: points = points[:4]
-               package = Gcode.buildGcodePackage(list(map(self.adjustXY, points)), (self.max_X, self.max_Y))
+               package = Gcode.buildGcodePackage(list(map(self.adjustXY, points)), (self.max_X, self.max_Y), self.sendSpike)
                self.writePackage(package)
 
        def packageIsExecuting(self):
index f665442cd862209bd44e66166c6e6bd852a4fabc..1f198c538c6f79ec6a3a00557a7c331508415aab 100644 (file)
Binary files a/Printer.pyc and b/Printer.pyc differ
index 599260f58f75d3227cde273256476c247c9be19f..5883907cacffd78cd0e3194c45f1ad8bbc69a1af 100644 (file)
--- a/Tests.py
+++ b/Tests.py
@@ -1,68 +1,27 @@
 import Printer, time, cv2
 import numpy as np
-from utils import Gcode
-
-params = cv2.SimpleBlobDetector_Params()
-# Change thresholds
-params.minThreshold = 1
-params.maxThreshold = 256
-params.filterByArea = True
-params.minArea = 350
-
-params.filterByConvexity = False
-params.filterByInertia = False
-
-detector = cv2.SimpleBlobDetector_create(params)
+from utils import Gcode, Detector, MaskProcessing
+from User_Interface import Sliders
 
 cap = cv2.VideoCapture(0)
 
-openVal = 1
-closeVal = 11
-erode = 10
-dilate = 8
-
+detector = Detector.InitializeBlobDetector()
 cv2.namedWindow('image')
 
-def nothing(x): pass
-
-cv2.createTrackbar('Open','image',openVal,20,nothing)
-cv2.createTrackbar('Close','image',closeVal,40,nothing)
-cv2.createTrackbar('Erode','image',erode,30,nothing)
-cv2.createTrackbar('Dilate','image',dilate,30,nothing)
-cv2.createTrackbar('Saturation','image',170,255,nothing)
+sliders = Sliders.Sliders('image')
 
 while 1:
-        
-    kernelOpen=np.ones((cv2.getTrackbarPos('Open','image'), cv2.getTrackbarPos('Open','image')))
-    kernelClose=np.ones((cv2.getTrackbarPos('Close','image'), cv2.getTrackbarPos('Close','image')))
-    kernelErode=np.ones((cv2.getTrackbarPos('Erode','image'), cv2.getTrackbarPos('Erode','image')))
-    kernelDilate=np.ones((cv2.getTrackbarPos('Dilate','image'), cv2.getTrackbarPos('Dilate','image')))
-    saturationMin = cv2.getTrackbarPos('Saturation','image')
-
-    lowerBound=np.array([0,saturationMin,20])
-    upperBound=np.array([20,255,255])
-
     ret, img = cap.read()
 
-    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
-    mask = cv2.inRange(hsv, lowerBound, upperBound)
-
-
-    mask=cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernelOpen, iterations = 1)
-    mask=cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernelClose, iterations= 2)
-    mask = cv2.erode(mask, kernelErode, iterations = 1)
-    mask = cv2.dilate(mask, kernelDilate, iterations = 1)
-
+    colorMask = MaskProcessing.GetColorMask(img, sliders)
+    res = MaskProcessing.ProcessImageMask(colorMask, img, sliders)
 
-    maskImg = cv2.bitwise_and(img,img, mask= mask)
-    maskImg = 255 - maskImg
-    points = detector.detect(maskImg)
-    img = cv2.drawKeypoints(img, points, np.array([]), (255,0,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
+    points = detector.detect(res)
+    img = cv2.drawKeypoints(img, points, np.array([]), (255, 0, 0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
 
-    cv2.imshow('image', maskImg)
-    cv2.imshow('wut', img)
+    cv2.imshow('image', res)
+    cv2.imshow('cum', img)
+    cv2.imshow('color', colorMask)
 
     command = cv2.waitKey(10) & 0xFF
     if command == ord('q'):
index a5947b43037638f94ea6aec2658496ab431363e4..7e8d8e2f028c9d3209fe7244b52c22c6e7655bf9 100644 (file)
@@ -9,7 +9,7 @@ def checkButtons(printer):
        elif command == ord('d'):
                enableDots = not enableDots
        elif command == ord('f'):
-               printer.sendSerial = not printer.sendSerial
+               printer.sendSerial = not printer.sendSpike
        elif command == ord('h'):
                printer.home()
        elif command == ord('c'):
diff --git a/User_Interface/Sliders.py b/User_Interface/Sliders.py
new file mode 100644 (file)
index 0000000..244dc1c
--- /dev/null
@@ -0,0 +1,31 @@
+import cv2
+from settings import maskSettings
+
+openVal = 1
+closeVal = 11
+erode = 10
+dilate = 8
+saturationMin = 170
+
+class Sliders:
+
+    def nothing(self, x): pass
+    def __init__(self, windowName):
+        self.maskSettings = maskSettings.MaskSettings()
+        cv2.createTrackbar('Open', windowName, self.maskSettings.open, 20, self.nothing)
+        cv2.createTrackbar('Close', windowName, self.maskSettings.close, 40, self.nothing)
+        cv2.createTrackbar('Erode', windowName, self.maskSettings.erode, 30, self.nothing)
+        cv2.createTrackbar('Dilate', windowName, self.maskSettings.dilate, 30, self.nothing)
+        cv2.createTrackbar('Saturation', windowName, self.maskSettings.saturationMin, 255, self.nothing)
+
+    def updateMaskSettings(self):
+        self.maskSettings.open = cv2.getTrackbarPos('Open', 'image')
+        self.maskSettings.close = cv2.getTrackbarPos('Close', 'image')
+        self.maskSettings.erode = cv2.getTrackbarPos('Erode', 'image')
+        self.maskSettings.dilate = cv2.getTrackbarPos('Dilate', 'image')
+        self.maskSettings.saturationMin = cv2.getTrackbarPos('Saturation', 'image')
+
+    def getMaskSettings(self):
+        self.updateMaskSettings()
+        return self.maskSettings
+
diff --git a/User_Interface/Sliders.pyc b/User_Interface/Sliders.pyc
new file mode 100644 (file)
index 0000000..6a004ef
Binary files /dev/null and b/User_Interface/Sliders.pyc differ
index fccd8dde82104c0e0c75ada8866af1b6fc5e0455..434ec472c610bd1e95c7d5248a9c5e0f3f116d34 100644 (file)
Binary files a/settings/frameSettings.pyc and b/settings/frameSettings.pyc differ
diff --git a/settings/maskSettings.py b/settings/maskSettings.py
new file mode 100644 (file)
index 0000000..6df0921
--- /dev/null
@@ -0,0 +1,27 @@
+import json
+MaskSettingsName = 'MaskSettings.json'
+
+class MaskSettings:
+    def __init__(self):
+        with open(MaskSettingsName, 'r') as file:
+            data = json.load(file)
+            
+        self.open = data['open']
+        self.close = data['close']
+        self.erode = data['erode']
+        self.dilate = data['dilate']
+        self.saturationMin = data['saturationMin']
+
+    def getSettingsTuple(self):
+        return (self.open, self.close, self.erode, self.dilate, self.saturationMin)
+
+    def saveSettings(self):
+        jsonDict = {
+            'open': self.open,
+            'close': self.close,
+            'erode': self.erode,
+            'dilate': self.dilate,
+            'saturationMin': self.saturationMin
+        }
+        with open(MaskSettingsName, 'w') as file:
+            json.dump(jsonDict, file)
\ No newline at end of file
diff --git a/settings/maskSettings.pyc b/settings/maskSettings.pyc
new file mode 100644 (file)
index 0000000..0aea8b0
Binary files /dev/null and b/settings/maskSettings.pyc differ
diff --git a/utils/Detector.py b/utils/Detector.py
new file mode 100644 (file)
index 0000000..cdd6d5d
--- /dev/null
@@ -0,0 +1,15 @@
+import cv2
+
+def InitializeBlobDetector():
+    params = cv2.SimpleBlobDetector_Params()
+    params.minThreshold = 1
+    params.maxThreshold = 256
+    
+    params.filterByArea = True
+    params.minArea = 350
+
+    params.filterByConvexity = False
+    params.filterByInertia = False
+
+    return cv2.SimpleBlobDetector_create(params)
\ No newline at end of file
diff --git a/utils/Detector.pyc b/utils/Detector.pyc
new file mode 100644 (file)
index 0000000..fb1aa04
Binary files /dev/null and b/utils/Detector.pyc differ
index 64d658e1df5e3e13d13a8f038faf1c4dc918dce9..82c9812d7acd4d202dc9d1d9fa10e1f68508b2ab 100644 (file)
@@ -1,11 +1,14 @@
 from utils import Geometry
 
-def buildGcodePackage(points, xyMax):
-               package = 'G0 F5000\n'
+def buildGcodePackage(points, xyMax, withSpike):
+               package = 'G0 F5000\n' #Set printer head speed
                for point in points:
                        if Geometry.pointWithinBounds(point, xyMax):
                                x,y = point
-                               package += 'G0 X{:.1f} Y{:.1f}\n'.format(x, y)
-                               package += 'M106 S300\nG4 P500\nM107\n'
+                               package += 'G0 X{:.1f} Y{:.1f}\n'.format(x, y) #Positioning format
+                               #Pnumatic trigger on/off
+                               if withSpike: package += 'M106 S300\n'
+                               package += 'G4 P500\n'
+                               if withSpike: package += 'M107\n'
                package += 'G0 X0 Y0\n'
                return package
\ No newline at end of file
index cfbe18869443a941b6aa6a5fca28a56c2fc509c2..66be296243f3b13658dd5eac98e19e4ba572005f 100644 (file)
Binary files a/utils/Gcode.pyc and b/utils/Gcode.pyc differ
diff --git a/utils/MaskProcessing.py b/utils/MaskProcessing.py
new file mode 100644 (file)
index 0000000..fecae50
--- /dev/null
@@ -0,0 +1,23 @@
+import cv2
+import numpy as np
+
+def GetColorMask(img, sliders):
+    saturationMin = sliders.getMaskSettings().saturationMin
+
+    lowerBound = np.array([0,saturationMin,20])
+    upperBound = np.array([20,255,255])
+
+    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
+    return cv2.inRange(hsv, lowerBound, upperBound)
+
+def ProcessImageMask(mask, ogImg, sliders):
+    _open, _close, _erode, _dilate, _saturationMin = sliders.getMaskSettings().getSettingsTuple()
+
+    maskImg = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((_open, _open)), iterations = 1)
+    maskImg = cv2.morphologyEx(maskImg, cv2.MORPH_CLOSE, np.ones((_close, _close)), iterations= 2)
+    maskImg = cv2.erode(maskImg, np.ones((_erode, _erode)), iterations = 1)
+    maskImg = cv2.dilate(maskImg, np.ones((_dilate, _dilate)), iterations = 1)
+    
+    maskImg = cv2.bitwise_and(ogImg, ogImg, mask = maskImg)
+    maskImg = 255 - maskImg
+    return maskImg
\ No newline at end of file
diff --git a/utils/MaskProcessing.pyc b/utils/MaskProcessing.pyc
new file mode 100644 (file)
index 0000000..b8359c4
Binary files /dev/null and b/utils/MaskProcessing.pyc differ