Compare commits
No commits in common. "3ae6b41c62558a797e1a51be29de10a474c62b92" and "27312ae6df03700cd52185d85db6899951fd8ef8" have entirely different histories.
3ae6b41c62
...
27312ae6df
59
.gitignore
vendored
@ -1,58 +1 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
out
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
|
|
||||||
# C extensions
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
bin/
|
|
||||||
build/
|
|
||||||
develop-eggs/
|
|
||||||
dist/
|
|
||||||
eggs/
|
|
||||||
lib/
|
|
||||||
lib64/
|
|
||||||
parts/
|
|
||||||
sdist/
|
|
||||||
var/
|
|
||||||
out/
|
|
||||||
*.egg-info/
|
|
||||||
.installed.cfg
|
|
||||||
*.egg
|
|
||||||
|
|
||||||
# Installer logs
|
|
||||||
pip-log.txt
|
|
||||||
pip-delete-this-directory.txt
|
|
||||||
|
|
||||||
# Unit test / coverage reports
|
|
||||||
.tox/
|
|
||||||
.coverage
|
|
||||||
.cache
|
|
||||||
nosetests.xml
|
|
||||||
coverage.xml
|
|
||||||
|
|
||||||
# Translations
|
|
||||||
*.mo
|
|
||||||
|
|
||||||
# Mr Developer
|
|
||||||
.mr.developer.cfg
|
|
||||||
.project
|
|
||||||
.pydevproject
|
|
||||||
|
|
||||||
# Rope
|
|
||||||
.ropeproject
|
|
||||||
|
|
||||||
# Django stuff:
|
|
||||||
*.log
|
|
||||||
*.pot
|
|
||||||
|
|
||||||
# Sphinx documentation
|
|
||||||
docs/_build/
|
|
||||||
|
|
||||||
# Temp
|
|
||||||
.venv/
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Config file
|
|
||||||
src/config/config.json
|
|
||||||
|
18
md/nuts.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
### Jullie gaan noten herkennen
|
||||||
|
|
||||||
|
Hoe de neuk? Nut.
|
||||||
|
1. Hoe gaan we de noten herkennen (beeld, smaak, geluid, text)?
|
||||||
|
- Beeldherkenning lol
|
||||||
|
2. Wat zijn de visuele kenmerken van de noten?
|
||||||
|
- Vorm, kleur, textuur, grootte
|
||||||
|
3. Hoeveel noten willen we herkennen
|
||||||
|
- Qua type, hoeveel verschillende noten
|
||||||
|
- Qua tijd, hoeveel noten tegelijkertijd
|
||||||
|
4. Wat is de achtergrond
|
||||||
|
5. Met wat voor camera worden de noten bekeken
|
||||||
|
6. Is de noot verwerkt
|
||||||
|
|
||||||
|
De deelvragen moeten sequentieel zijn
|
||||||
|
|
||||||
|
|
||||||
|
Wij moeten presenteren volgende week
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"path": "",
|
|
||||||
"size": 750
|
|
||||||
}
|
|
@ -5,7 +5,6 @@
|
|||||||
<property name="height">800</property>
|
<property name="height">800</property>
|
||||||
<property name="title" translatable="yes">Tree Recogniser 7000</property>
|
<property name="title" translatable="yes">Tree Recogniser 7000</property>
|
||||||
<property name="width">200</property>
|
<property name="width">200</property>
|
||||||
<bind sequence="<Destroy>" handler="on_quit" add="" />
|
|
||||||
<containerlayout manager="pack">
|
<containerlayout manager="pack">
|
||||||
<property name="propagate">false</property>
|
<property name="propagate">false</property>
|
||||||
</containerlayout>
|
</containerlayout>
|
||||||
@ -176,9 +175,9 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="ttk.Button" id="prev" named="True">
|
<object class="ttk.Button" id="button1">
|
||||||
<property name="text" translatable="yes">Prev img</property>
|
<property name="text" translatable="yes">Next img</property>
|
||||||
<bind sequence="<ButtonPress>" handler="img_prev" add="" />
|
<bind sequence="<ButtonPress>" handler="img_next" add="" />
|
||||||
<layout manager="grid">
|
<layout manager="grid">
|
||||||
<property name="column">1</property>
|
<property name="column">1</property>
|
||||||
<property name="ipadx">10</property>
|
<property name="ipadx">10</property>
|
||||||
@ -187,9 +186,9 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="ttk.Button" id="next" named="True">
|
<object class="ttk.Button" id="button2">
|
||||||
<property name="text" translatable="yes">Next img</property>
|
<property name="text" translatable="yes">Prev img</property>
|
||||||
<bind sequence="<ButtonPress>" handler="img_next" add="" />
|
<bind sequence="<ButtonPress>" handler="img_prev" add="" />
|
||||||
<layout manager="grid">
|
<layout manager="grid">
|
||||||
<property name="column">2</property>
|
<property name="column">2</property>
|
||||||
<property name="ipadx">10</property>
|
<property name="ipadx">10</property>
|
||||||
@ -214,7 +213,7 @@
|
|||||||
<bind sequence="<ButtonPress>" handler="apply" add="" />
|
<bind sequence="<ButtonPress>" handler="apply" add="" />
|
||||||
<layout manager="grid">
|
<layout manager="grid">
|
||||||
<property name="column">2</property>
|
<property name="column">2</property>
|
||||||
<property name="columnspan">1</property>
|
<property name="columnspan">2</property>
|
||||||
<property name="ipadx">0</property>
|
<property name="ipadx">0</property>
|
||||||
<property name="row">6</property>
|
<property name="row">6</property>
|
||||||
</layout>
|
</layout>
|
||||||
@ -239,22 +238,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="tk.Text" id="dataset" named="True">
|
|
||||||
<property name="height">10</property>
|
|
||||||
<property name="pady">0</property>
|
|
||||||
<property name="state">disabled</property>
|
|
||||||
<property name="text" translatable="yes">Image metadata should appear here</property>
|
|
||||||
<property name="width">25</property>
|
|
||||||
<property name="wrap">word</property>
|
|
||||||
<layout manager="grid">
|
|
||||||
<property name="column">3</property>
|
|
||||||
<property name="columnspan">1</property>
|
|
||||||
<property name="row">0</property>
|
|
||||||
<property name="rowspan">8</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
BIN
src/helpers/algorithms/__pycache__/pysift.cpython-311.pyc
Normal file
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.7 MiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.8 MiB |
165
src/suite.py
@ -8,18 +8,10 @@ import numpy as np
|
|||||||
import cv2
|
import cv2
|
||||||
import time
|
import time
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import json
|
|
||||||
|
|
||||||
## UI config load
|
|
||||||
PROJECT_PATH = pathlib.Path(__file__).parent
|
PROJECT_PATH = pathlib.Path(__file__).parent
|
||||||
PROJECT_UI = "./src/helpers/gui/main.ui"
|
PROJECT_UI = "./src/gui/main.ui"
|
||||||
|
|
||||||
## Config file load
|
|
||||||
CONFIG_PATH = "./src/config/config.json"
|
|
||||||
config_file = open(CONFIG_PATH)
|
|
||||||
config_json = json.load(config_file)
|
|
||||||
|
|
||||||
## UI class setup
|
|
||||||
class MainApp:
|
class MainApp:
|
||||||
def __init__(self, master=None):
|
def __init__(self, master=None):
|
||||||
self.builder = builder = pygubu.Builder()
|
self.builder = builder = pygubu.Builder()
|
||||||
@ -29,51 +21,38 @@ class MainApp:
|
|||||||
# Main widget
|
# Main widget
|
||||||
self.mainwindow = builder.get_object("main", master)
|
self.mainwindow = builder.get_object("main", master)
|
||||||
|
|
||||||
# Canvas for output images
|
|
||||||
self.canvas = builder.get_object("output_canvas")
|
self.canvas = builder.get_object("output_canvas")
|
||||||
self.tk_imgs = [] # Required or python will forget
|
self.tk_imgs = []
|
||||||
self.output = [[] for x in range(2)]
|
|
||||||
self.meta = builder.get_object("dataset")
|
|
||||||
|
|
||||||
# Keep track of images in dataset
|
self.canny_thr1 = None
|
||||||
|
self.canny_thr2 = None
|
||||||
|
|
||||||
|
self.img_path = None
|
||||||
self.img_current = 0
|
self.img_current = 0
|
||||||
self.img_max = 0
|
self.img_max = 0
|
||||||
|
|
||||||
# Plots
|
# Plots
|
||||||
self.axs = self.createPlot(2, 2)
|
self.axs = self.createPlot(2, 2)
|
||||||
|
|
||||||
# UI Variables
|
# UI
|
||||||
self.canny_thr1 = None
|
|
||||||
self.canny_thr2 = None
|
|
||||||
self.img_path = None
|
|
||||||
self.blur_rate = None
|
self.blur_rate = None
|
||||||
self.img_size = None
|
self.img_size = None
|
||||||
self.sobel_select = None
|
self.sobel_select = None
|
||||||
self.export_id = None
|
self.export_id = None
|
||||||
builder.import_variables(self, ['canny_thr1','canny_thr2','img_path','blur_rate','img_size', 'sobel_select', 'export_id'])
|
builder.import_variables(self,
|
||||||
|
['canny_thr1',
|
||||||
|
'canny_thr2',
|
||||||
|
'img_path',
|
||||||
|
'blur_rate',
|
||||||
|
'img_size',
|
||||||
|
'sobel_select',
|
||||||
|
'export_id'])
|
||||||
builder.connect_callbacks(self)
|
builder.connect_callbacks(self)
|
||||||
|
|
||||||
# Load values from config after UI has been initialised
|
|
||||||
self.img_path.set(config_json["path"])
|
|
||||||
self.img_size.set(config_json["size"])
|
|
||||||
|
|
||||||
def on_quit(self, event=None):
|
|
||||||
'''
|
|
||||||
Close PLT windows on main app quit
|
|
||||||
'''
|
|
||||||
plt.close()
|
|
||||||
self.mainwindow.quit();
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
'''
|
|
||||||
Run loop
|
|
||||||
'''
|
|
||||||
self.mainwindow.mainloop()
|
self.mainwindow.mainloop()
|
||||||
|
|
||||||
def img_prev(self, event=None):
|
def img_prev(self, event=None):
|
||||||
'''
|
|
||||||
Open previous image from path
|
|
||||||
'''
|
|
||||||
if self.img_current == 0:
|
if self.img_current == 0:
|
||||||
self.img_current = self.img_max - 1
|
self.img_current = self.img_max - 1
|
||||||
else:
|
else:
|
||||||
@ -81,9 +60,6 @@ class MainApp:
|
|||||||
self.update(self)
|
self.update(self)
|
||||||
|
|
||||||
def img_next(self, event=None):
|
def img_next(self, event=None):
|
||||||
'''
|
|
||||||
Open next image from path
|
|
||||||
'''
|
|
||||||
if self.img_current == (self.img_max - 1):
|
if self.img_current == (self.img_max - 1):
|
||||||
self.img_current = 0
|
self.img_current = 0
|
||||||
else:
|
else:
|
||||||
@ -91,9 +67,6 @@ class MainApp:
|
|||||||
self.update(self)
|
self.update(self)
|
||||||
|
|
||||||
def apply(self, event=None):
|
def apply(self, event=None):
|
||||||
'''
|
|
||||||
Export current dataset
|
|
||||||
'''
|
|
||||||
img_arr = self.tk_imgs
|
img_arr = self.tk_imgs
|
||||||
img_id = self.export_id.get()
|
img_id = self.export_id.get()
|
||||||
|
|
||||||
@ -102,54 +75,6 @@ class MainApp:
|
|||||||
else:
|
else:
|
||||||
print("Nothing to export!")
|
print("Nothing to export!")
|
||||||
|
|
||||||
def add_output(self, data, name: str):
|
|
||||||
'''
|
|
||||||
Add CV2 image to canvas output
|
|
||||||
'''
|
|
||||||
self.output[0].append(data)
|
|
||||||
self.output[1].append(name)
|
|
||||||
|
|
||||||
def draw_output(self, size):
|
|
||||||
# Check if size of canvas has updated
|
|
||||||
drawW = self.canvas.winfo_width()
|
|
||||||
|
|
||||||
# Reset drawing position
|
|
||||||
drawX = 0
|
|
||||||
drawY = 0
|
|
||||||
|
|
||||||
# Clear previously printed images
|
|
||||||
self.tk_imgs = []
|
|
||||||
|
|
||||||
self.meta.config(state=NORMAL)
|
|
||||||
self.meta.delete(1.0, END)
|
|
||||||
|
|
||||||
# Draw all output images
|
|
||||||
for idx, data in enumerate(self.output[0]):
|
|
||||||
# Create ui image
|
|
||||||
tk_img = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
|
|
||||||
tk_img = ImageTk.PhotoImage(image=Image.fromarray(tk_img))
|
|
||||||
self.tk_imgs.append(tk_img)
|
|
||||||
|
|
||||||
## Check if next item will be out of range
|
|
||||||
if (drawX + size >= drawW):
|
|
||||||
drawY += size
|
|
||||||
drawX = 0
|
|
||||||
self.canvas.configure(height=(drawY+size))
|
|
||||||
|
|
||||||
self.canvas.create_image(drawX,drawY,anchor=NW,image=self.tk_imgs[idx],tags="og")
|
|
||||||
drawX += size
|
|
||||||
|
|
||||||
# Add name to text box
|
|
||||||
self.meta.insert(END, F"{idx}: {self.output[1][idx]}\n")
|
|
||||||
|
|
||||||
# Clear output
|
|
||||||
self.output = [[] for x in range(2)]
|
|
||||||
self.meta.config(state=DISABLED)
|
|
||||||
|
|
||||||
# Draw canvas
|
|
||||||
# TODO IDK volgens mij moet je deze wel callen maar het programma doet het nog (geen vragen stellen)
|
|
||||||
# self.canvas.draw()
|
|
||||||
|
|
||||||
def createPlot(self, columns, rows):
|
def createPlot(self, columns, rows):
|
||||||
fig, axs = plt.subplots(columns, rows)
|
fig, axs = plt.subplots(columns, rows)
|
||||||
return axs
|
return axs
|
||||||
@ -195,6 +120,11 @@ class MainApp:
|
|||||||
|
|
||||||
def update(self, event=None):
|
def update(self, event=None):
|
||||||
path = self.img_path.get()
|
path = self.img_path.get()
|
||||||
|
print(path)
|
||||||
|
|
||||||
|
drawW = self.canvas.winfo_width()
|
||||||
|
drawX = 0
|
||||||
|
drawY = 0
|
||||||
|
|
||||||
if path != None and path != "":
|
if path != None and path != "":
|
||||||
# Get all images at current path
|
# Get all images at current path
|
||||||
@ -211,24 +141,31 @@ class MainApp:
|
|||||||
sxy = self.sobel_select.get()
|
sxy = self.sobel_select.get()
|
||||||
size = self.img_size.get()
|
size = self.img_size.get()
|
||||||
|
|
||||||
|
# Keep array of cv2 images to output
|
||||||
|
output = []
|
||||||
|
|
||||||
|
# Clear previously printed images
|
||||||
|
self.tk_imgs = []
|
||||||
|
|
||||||
# Import and resize image
|
# Import and resize image
|
||||||
img = cv2.imread(images[self.img_current])
|
img = cv2.imread(images[self.img_current])
|
||||||
img = cv2.resize(img, (size, size), interpolation = cv2.INTER_AREA)
|
img = cv2.resize(img, (size, size), interpolation = cv2.INTER_AREA)
|
||||||
self.add_output(img, "Original")
|
output.append(img) # First output image is original
|
||||||
|
|
||||||
# Set grayscale
|
# Set grayscale
|
||||||
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
self.add_output(img_gray, "Grayscale")
|
output.append(img_gray) # Second output is grayscale
|
||||||
|
|
||||||
# Blurred edition
|
# Blurred edition
|
||||||
if (br == 0):
|
if (br == 0):
|
||||||
|
# Disable
|
||||||
img_blur = img_gray
|
img_blur = img_gray
|
||||||
elif (br % 2 == 1):
|
elif (br % 2 == 1):
|
||||||
img_blur = cv2.GaussianBlur(img_gray, (br, br), 0)
|
img_blur = cv2.GaussianBlur(img_gray, (br, br), 0)
|
||||||
else:
|
else:
|
||||||
print(f"Blur rate changed to {br - 1}")
|
print(f"Blur rate changed to {br - 1}")
|
||||||
img_blur = cv2.GaussianBlur(img_gray, (br-1, br-1), 0)
|
img_blur = cv2.GaussianBlur(img_gray, (br-1, br-1), 0)
|
||||||
self.add_output(img_blur, "Blurred")
|
output.append(img_blur)
|
||||||
|
|
||||||
# Sobel edge
|
# Sobel edge
|
||||||
if sxy in ['x', 'y', 'both']:
|
if sxy in ['x', 'y', 'both']:
|
||||||
@ -245,36 +182,48 @@ class MainApp:
|
|||||||
img_sobel = cv2.Sobel(src=img_blur, ddepth=cv2.CV_8U, dx=dx, dy=dy, ksize=5)
|
img_sobel = cv2.Sobel(src=img_blur, ddepth=cv2.CV_8U, dx=dx, dy=dy, ksize=5)
|
||||||
else:
|
else:
|
||||||
img_sobel = img_gray
|
img_sobel = img_gray
|
||||||
self.add_output(img_sobel, "Sobel Edge")
|
output.append(img_sobel)
|
||||||
|
|
||||||
# Canny edge
|
# Canny edge
|
||||||
img_canny = cv2.Canny(image=img_blur,threshold1=ct1,threshold2=ct2)
|
img_canny = cv2.Canny(image=img_blur,threshold1=ct1,threshold2=ct2)
|
||||||
self.add_output(img_canny, "Canny Edge")
|
output.append(img_canny)
|
||||||
|
|
||||||
# BGR
|
# BGR
|
||||||
self.add_output(img[:, :, 0], "BGR B")
|
output.append(img[:, :, 0]) # B
|
||||||
self.add_output(img[:, :, 1], "BGR G")
|
output.append(img[:, :, 1]) # G
|
||||||
self.add_output(img[:, :, 2], "BGR R")
|
output.append(img[:, :, 2]) # R
|
||||||
|
|
||||||
if img is not None:
|
if img is not None:
|
||||||
self.drawHist(img, ('B', 'G', 'R'), 0, 0)
|
self.drawHist(img, ('B', 'G', 'R'), 0, 0)
|
||||||
|
|
||||||
# HSV
|
# HSV
|
||||||
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
||||||
self.add_output(img_hsv, "HSV")
|
output.append(img_hsv)
|
||||||
self.add_output(img_hsv[:, :, 0], "HSV H") # H
|
output.append(img_hsv[:, :, 0]) # H
|
||||||
self.add_output(img_hsv[:, :, 1], "HSV S") # S
|
output.append(img_hsv[:, :, 1]) # S
|
||||||
self.add_output(img_hsv[:, :, 2], "HSV V") # V
|
output.append(img_hsv[:, :, 2]) # V
|
||||||
|
|
||||||
if img_hsv is not None:
|
if img_hsv is not None:
|
||||||
self.drawHist(img_hsv, ('H', 'S', 'V'), 0, 1)
|
self.drawHist(img_hsv, ('H', 'S', 'V'), 0, 1)
|
||||||
|
|
||||||
# Canny Heatmap
|
|
||||||
self.drawCannyHM(img, 1, 1)
|
self.drawCannyHM(img, 1, 1)
|
||||||
|
|
||||||
# Show all data
|
plt.show(block=False)
|
||||||
plt.show(block=False) ## Graphs
|
|
||||||
self.draw_output(size) ## Images
|
# Draw all output images
|
||||||
|
for idx, data in enumerate(output):
|
||||||
|
# Create ui image
|
||||||
|
tk_img = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
|
||||||
|
tk_img = ImageTk.PhotoImage(image=Image.fromarray(tk_img))
|
||||||
|
self.tk_imgs.append(tk_img)
|
||||||
|
|
||||||
|
## Check if next item will be out of range
|
||||||
|
if (drawX + size >= drawW):
|
||||||
|
drawY += size
|
||||||
|
drawX = 0
|
||||||
|
self.canvas.configure(height=(drawY+size))
|
||||||
|
|
||||||
|
self.canvas.create_image(drawX,drawY,anchor=NW,image=self.tk_imgs[idx],tags="og")
|
||||||
|
drawX += size
|
||||||
|
self.canvas.draw()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = MainApp()
|
app = MainApp()
|
||||||
|