diff --git a/src/helpers/algorithms.py b/src/helpers/algorithms.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/helpers/gui/main.ui b/src/helpers/gui/main.ui
index a410225..4594100 100644
--- a/src/helpers/gui/main.ui
+++ b/src/helpers/gui/main.ui
@@ -169,9 +169,9 @@
-
-
+
+ imgCtl
Next img >
-
3
10
@@ -197,10 +197,10 @@
Export PNG
- 3
+ 1
1
- 10
- 6
+ 30
+ 8
1
@@ -208,10 +208,10 @@
int:export_id
- 15
+ 10
- 2
- 6
+ 0
+ 8
@@ -219,9 +219,9 @@
Export Image by ID
- 2
+ 0
2
- 5
+ 7
@@ -280,9 +280,9 @@
-
+
+ applyAll
Export ID for entire dataset
-
2
2
@@ -303,17 +303,42 @@
-
+
+ applyAll
Run analysis for entire dataset (!)
-
2
2
15
+ 5
8
+
+
+ imgCtl
+ < Prev tree
+
+ 2
+ 10
+ 5
+ 5
+
+
+
+
+
+ imgCtl
+ Next tree >
+
+ 3
+ 10
+ 5
+ 5
+
+
+
diff --git a/src/suite.py b/src/suite.py
index d486684..842c590 100644
--- a/src/suite.py
+++ b/src/suite.py
@@ -27,6 +27,7 @@ config_json = json.load(config_file)
log = Logger(config_json["out"])
+
## UI class setup
class MainApp:
def __init__(self, master=None):
@@ -101,25 +102,47 @@ class MainApp:
"""
self.mainwindow.mainloop()
- def img_prev(self, event=None):
+ def imgCtl(self, widget_id):
"""
- Open previous image from path
+ Bunch a functions to switch between images in the given dataset
"""
- if self.img_current == 0:
- self.img_current = self.img_max - 1
- else:
- self.img_current = self.img_current - 1
+ cmd = widget_id.split("_")
+
+ # Determine detection based on widget id
+ if cmd[0] == "next":
+ dir = 1
+ elif cmd[0] == "prev":
+ dir = -1
+
+ # Get name of current img
+ start = copy.deepcopy(
+ self.img_name.split("_")[0]
+ ) # deepcopy cus snaky boi language likes to create pointers
+ next = start
+
+ while start == next:
+ # Check for limits
+ self.img_current += dir
+ if self.img_current == self.img_max:
+ self.img_current = 0
+ elif self.img_current == -1:
+ self.img_current = self.img_max - 1
+
+ if cmd[1] == "img":
+ break # Stop if only one image should be skipped
+ elif cmd[1] == "tree":
+ self.updatePath()
+ next = copy.deepcopy(self.img_name.split("_")[0])
+
+ # Update UI
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:
- self.img_current = self.img_current + 1
- self.update(self)
+ """
+ TODO:
+ - Primitive surface area
+ - Derivative max x and y pos
+ - Function min, max + y position
+ """
def apply(self, event=None, path=None):
"""
@@ -150,14 +173,19 @@ class MainApp:
else:
print("Nothing to export!")
- def apply_all(self, event=None, export = True):
+ def applyAll(self, widget_id):
"""
Export given preprocess id for every image in the dataset folder
"""
+ if widget_id == "export":
+ export = True
+ elif widget_id == "analyse":
+ export = False
+
img_id = self.export_id.get()
img_current = copy.deepcopy(self.img_current)
- if (export):
+ if export:
now = datetime.datetime.now()
path = pathlib.Path(
config_json["out"],
@@ -166,28 +194,24 @@ class MainApp:
os.mkdir(path)
while True:
- self.img_next()
-
- if (export):
+ if export:
self.apply(path=path)
+ self.imgCtl("next_img")
if self.img_current == img_current:
break
## Ensure display is always correct with image
self.update()
- def analyse_all(self, event=None):
- self.apply_all(export=False)
-
- def add_output(self, data, name: str):
+ def addOutput(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):
+ def drawOutput(self, size):
# Check if size of canvas has updated
drawW = self.canvas.winfo_width()
@@ -253,14 +277,17 @@ class MainApp:
for th1 in range(0, canny_max, canny_step):
for th2 in range(0, canny_max, canny_step):
- # Canny Edge Detection
- edges = cv2.Canny(image=img, threshold1=th1, threshold2=th2)
-
- w_res = cv2.countNonZero(edges)
y_ind = (int)(th1 / canny_step)
x_ind = (int)(th2 / canny_step)
- results[y_ind].append(w_res)
+ # Ignore all edges where th1 > th2
+ if th1 <= th2:
+ # Canny Edge Detection
+ edges = cv2.Canny(image=img, threshold1=th1, threshold2=th2)
+ w_res = cv2.countNonZero(edges)
+ results[y_ind].append(w_res)
+ else:
+ results[y_ind].append(0)
# print(f"Result at thres {th1}, {th2}; \tIndex {y_ind}, {x_ind} \t= {w_res}")
# print(results[y_ind])
@@ -313,23 +340,12 @@ class MainApp:
log.add(f"Mean {label}", mean[idx])
log.add(f"Std {label}", std[idx])
- def update(self, event=None, part_update=None):
+ def updatePath(self):
+ """
+ Only update image name and path
+ """
path = self.img_path.get()
- ## Check if hist and canny hm have to be rerendered
- if part_update == None: ## If partial update has not been forced, check if full update is required
- if self.img_current != self.img_old or self.img_size != self.img_size_old:
- part_update = False
- self.img_old = self.img_current
- self.img_size_old = self.img_size
- else:
- part_update = True
- else:
- if part_update == True:
- print("Partial update forced!")
- else:
- print("Full update forced!")
-
if path != None and path != "":
# Get all images at current path
images = []
@@ -341,6 +357,28 @@ class MainApp:
self.img_max = len(images)
self.img_name = os.path.split(images[self.img_current])[1]
+ return True
+ else:
+ return False
+
+ def update(self, event=None, part_update=None):
+ ## Check if hist and canny hm have to be rerendered
+ if (
+ part_update == None
+ ): ## If partial update has not been forced, check if full update is required
+ if self.img_current != self.img_old or self.img_size != self.img_size_old:
+ part_update = False
+ self.img_old = self.img_current
+ self.img_size_old = self.img_size
+ else:
+ part_update = True
+ else:
+ if part_update == True:
+ print("Partial update forced!")
+ else:
+ print("Full update forced!")
+
+ if self.updatePath():
log.add("Img", self.img_name)
# Get all user vars
@@ -355,26 +393,27 @@ class MainApp:
self.output = [[] for x in range(2)]
# Import and resize image
- img = cv2.imread(images[self.img_current])
+ # img = cv2.imread(images[self.img_current])
+ img = cv2.imread(os.path.join(self.img_path.get(), self.img_name))
img = cv2.resize(img, (size, size), interpolation=cv2.INTER_AREA)
- self.add_output(img, "Original")
+ self.addOutput(img, "Original")
# Set grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- self.add_output(img_gray, "Grayscale")
-
+ self.addOutput(img_gray, "Grayscale")
+
# Contrast / brightness boost
contrast_val = contrast / 100
bright_val = bright / 100
img_contrast = np.clip(
contrast_val * (img_gray + bright_val), 0, 255
).astype(np.uint8)
- # self.add_output(img_contrast, F"Contrast / Brightness\n c+{contrast_val} b+{bright_val}")
- self.add_output(img_contrast, f"BCG")
+ # self.addOutput(img_contrast, F"Contrast / Brightness\n c+{contrast_val} b+{bright_val}")
+ self.addOutput(img_contrast, f"BCG")
# Blurred edition
img_blur = cv2.GaussianBlur(img_gray, (3, 3), 0)
- self.add_output(img_blur, "Blurred_k3")
+ self.addOutput(img_blur, "Blurred_k3")
# Sobel edge
if sxy in ["x", "y", "both"]:
@@ -394,17 +433,17 @@ class MainApp:
else:
img_sobel = img_gray
- self.add_output(img_sobel, "Sobel_edge")
+ self.addOutput(img_sobel, "Sobel_edge")
log.add("Sobel nonzero", cv2.countNonZero(img_sobel))
# Canny edge
img_canny = cv2.Canny(image=img_blur, threshold1=ct1, threshold2=ct2)
- self.add_output(img_canny, "Canny_edge")
+ self.addOutput(img_canny, "Canny_edge")
# BGR
- self.add_output(img[:, :, 0], "BGR_B")
- self.add_output(img[:, :, 1], "BGR_G")
- self.add_output(img[:, :, 2], "BGR_R")
+ self.addOutput(img[:, :, 0], "BGR_B")
+ self.addOutput(img[:, :, 1], "BGR_G")
+ self.addOutput(img[:, :, 2], "BGR_R")
if img is not None:
self.drawHist(img, ("B", "G", "R"), 0, 0)
@@ -412,10 +451,10 @@ class MainApp:
# HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
- 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
+ self.addOutput(img_hsv, "HSV")
+ self.addOutput(img_hsv[:, :, 0], "HSV_H") # H
+ self.addOutput(img_hsv[:, :, 1], "HSV_S") # S
+ self.addOutput(img_hsv[:, :, 2], "HSV_V") # V
if not part_update:
if img_hsv is not None:
@@ -430,11 +469,11 @@ class MainApp:
if not part_update:
log.update()
else:
- log.clear() # Prevent partial updates from breaking log
+ log.clear() # Prevent partial updates from breaking log
# Show all data
plt.show(block=False) ## Graphs
- self.draw_output(size) ## Images
+ self.drawOutput(size) ## Images
if __name__ == "__main__":