This commit is contained in:
Tom Selier 2023-09-23 21:56:45 +02:00
commit 387cdb1247
22 changed files with 197 additions and 86 deletions

59
.gitignore vendored
View File

@ -1 +1,58 @@
out
# Byte-compiled / optimized / DLL files
__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

View File

@ -1,18 +0,0 @@
### 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

View File

@ -0,0 +1,4 @@
{
"path": "",
"size": 750
}

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -5,6 +5,7 @@
<property name="height">800</property>
<property name="title" translatable="yes">Tree Recogniser 7000</property>
<property name="width">200</property>
<bind sequence="&lt;Destroy&gt;" handler="on_quit" add="" />
<containerlayout manager="pack">
<property name="propagate">false</property>
</containerlayout>
@ -175,9 +176,9 @@
</object>
</child>
<child>
<object class="ttk.Button" id="button1">
<property name="text" translatable="yes">Next img</property>
<bind sequence="&lt;ButtonPress&gt;" handler="img_next" add="" />
<object class="ttk.Button" id="prev" named="True">
<property name="text" translatable="yes">Prev img</property>
<bind sequence="&lt;ButtonPress&gt;" handler="img_prev" add="" />
<layout manager="grid">
<property name="column">1</property>
<property name="ipadx">10</property>
@ -186,9 +187,9 @@
</object>
</child>
<child>
<object class="ttk.Button" id="button2">
<property name="text" translatable="yes">Prev img</property>
<bind sequence="&lt;ButtonPress&gt;" handler="img_prev" add="" />
<object class="ttk.Button" id="next" named="True">
<property name="text" translatable="yes">Next img</property>
<bind sequence="&lt;ButtonPress&gt;" handler="img_next" add="" />
<layout manager="grid">
<property name="column">2</property>
<property name="ipadx">10</property>
@ -213,7 +214,7 @@
<bind sequence="&lt;ButtonPress&gt;" handler="apply" add="" />
<layout manager="grid">
<property name="column">2</property>
<property name="columnspan">2</property>
<property name="columnspan">1</property>
<property name="ipadx">0</property>
<property name="row">6</property>
</layout>
@ -238,6 +239,22 @@
</layout>
</object>
</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>
</child>
<child>

View File

@ -8,10 +8,18 @@ import numpy as np
import cv2
import time
import matplotlib.pyplot as plt
import json
## UI config load
PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = "./src/gui/main.ui"
PROJECT_UI = "./src/helpers/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:
def __init__(self, master=None):
self.builder = builder = pygubu.Builder()
@ -21,38 +29,51 @@ class MainApp:
# Main widget
self.mainwindow = builder.get_object("main", master)
# Canvas for output images
self.canvas = builder.get_object("output_canvas")
self.tk_imgs = []
self.tk_imgs = [] # Required or python will forget
self.output = [[] for x in range(2)]
self.meta = builder.get_object("dataset")
self.canny_thr1 = None
self.canny_thr2 = None
self.img_path = None
# Keep track of images in dataset
self.img_current = 0
self.img_max = 0
# Plots
self.axs = self.createPlot(2, 2)
# UI
# UI Variables
self.canny_thr1 = None
self.canny_thr2 = None
self.img_path = None
self.blur_rate = None
self.img_size = None
self.sobel_select = 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)
# 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):
'''
Run loop
'''
self.mainwindow.mainloop()
def img_prev(self, event=None):
'''
Open previous image from path
'''
if self.img_current == 0:
self.img_current = self.img_max - 1
else:
@ -60,6 +81,9 @@ class MainApp:
self.update(self)
def img_next(self, event=None):
'''
Open next image from path
'''
if self.img_current == (self.img_max - 1):
self.img_current = 0
else:
@ -67,6 +91,9 @@ class MainApp:
self.update(self)
def apply(self, event=None):
'''
Export current dataset
'''
img_arr = self.tk_imgs
img_id = self.export_id.get()
@ -75,6 +102,54 @@ class MainApp:
else:
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):
fig, axs = plt.subplots(columns, rows)
return axs
@ -120,11 +195,6 @@ class MainApp:
def update(self, event=None):
path = self.img_path.get()
print(path)
drawW = self.canvas.winfo_width()
drawX = 0
drawY = 0
if path != None and path != "":
# Get all images at current path
@ -141,31 +211,24 @@ class MainApp:
sxy = self.sobel_select.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
img = cv2.imread(images[self.img_current])
img = cv2.resize(img, (size, size), interpolation = cv2.INTER_AREA)
output.append(img) # First output image is original
self.add_output(img, "Original")
# Set grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
output.append(img_gray) # Second output is grayscale
self.add_output(img_gray, "Grayscale")
# Blurred edition
if (br == 0):
# Disable
img_blur = img_gray
elif (br % 2 == 1):
img_blur = cv2.GaussianBlur(img_gray, (br, br), 0)
else:
print(f"Blur rate changed to {br - 1}")
img_blur = cv2.GaussianBlur(img_gray, (br-1, br-1), 0)
output.append(img_blur)
self.add_output(img_blur, "Blurred")
# Sobel edge
if sxy in ['x', 'y', 'both']:
@ -182,48 +245,36 @@ class MainApp:
img_sobel = cv2.Sobel(src=img_blur, ddepth=cv2.CV_8U, dx=dx, dy=dy, ksize=5)
else:
img_sobel = img_gray
output.append(img_sobel)
self.add_output(img_sobel, "Sobel Edge")
# Canny edge
img_canny = cv2.Canny(image=img_blur,threshold1=ct1,threshold2=ct2)
output.append(img_canny)
self.add_output(img_canny, "Canny Edge")
# BGR
output.append(img[:, :, 0]) # B
output.append(img[:, :, 1]) # G
output.append(img[:, :, 2]) # R
self.add_output(img[:, :, 0], "BGR B")
self.add_output(img[:, :, 1], "BGR G")
self.add_output(img[:, :, 2], "BGR R")
if img is not None:
self.drawHist(img, ('B', 'G', 'R'), 0, 0)
# HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
output.append(img_hsv)
output.append(img_hsv[:, :, 0]) # H
output.append(img_hsv[:, :, 1]) # S
output.append(img_hsv[:, :, 2]) # V
self.add_output(img_hsv, "HSV")
self.add_output(img_hsv[:, :, 0], "HSV H") # H
self.add_output(img_hsv[:, :, 1], "HSV S") # S
self.add_output(img_hsv[:, :, 2], "HSV V") # V
if img_hsv is not None:
self.drawHist(img_hsv, ('H', 'S', 'V'), 0, 1)
# Canny Heatmap
self.drawCannyHM(img, 1, 1)
plt.show(block=False)
# 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()
# Show all data
plt.show(block=False) ## Graphs
self.draw_output(size) ## Images
if __name__ == "__main__":
app = MainApp()