Added export all and partial update

This commit is contained in:
Arne van Iterson 2023-09-27 16:38:22 +02:00
parent dcd4411fbd
commit 8e7f1b57f1
2 changed files with 86 additions and 22 deletions

View File

@ -197,7 +197,7 @@
<layout manager="grid"> <layout manager="grid">
<property name="column">2</property> <property name="column">2</property>
<property name="columnspan">1</property> <property name="columnspan">1</property>
<property name="ipadx">0</property> <property name="ipadx">10</property>
<property name="row">7</property> <property name="row">7</property>
<property name="rowspan">1</property> <property name="rowspan">1</property>
</layout> </layout>
@ -284,6 +284,28 @@
</layout> </layout>
</object> </object>
</child> </child>
<child>
<object class="ttk.Button" id="export_all" named="True">
<property name="text" translatable="yes">Export ID for entire dataset</property>
<bind sequence="&lt;ButtonRelease&gt;" handler="apply_all" add="" />
<layout manager="grid">
<property name="column">1</property>
<property name="columnspan">2</property>
<property name="ipadx">30</property>
<property name="row">8</property>
</layout>
</object>
</child>
<child>
<object class="ttk.Label" id="label2">
<property name="font">TkIconFont</property>
<property name="text" translatable="yes">Powered by ARNweb.nl &amp; TomSelier.com</property>
<layout manager="grid">
<property name="column">0</property>
<property name="row">8</property>
</layout>
</object>
</child>
</object> </object>
</child> </child>
<child> <child>

View File

@ -12,6 +12,7 @@ import json
from helpers.statistics import imgStats from helpers.statistics import imgStats
import datetime import datetime
import os import os
import copy
## UI config load ## UI config load
PROJECT_PATH = pathlib.Path(__file__).parent PROJECT_PATH = pathlib.Path(__file__).parent
@ -40,6 +41,7 @@ class MainApp:
# Keep track of images in dataset # Keep track of images in dataset
self.img_current = 0 self.img_current = 0
self.img_old = -1
self.img_max = 0 self.img_max = 0
# Plots # Plots
@ -50,12 +52,14 @@ class MainApp:
self.canny_thr2 = None self.canny_thr2 = None
self.img_path = None self.img_path = None
self.contrast = None self.contrast = None
self.img_size = None self.img_size = None
self.img_size_old = 0 ## Check if the rendering size has changed, if it has the analysis has to be run
self.sobel_select = None self.sobel_select = None
self.export_id = None self.export_id = None
self.brightness = None self.brightness = None
builder.import_variables(self,['canny_thr1','canny_thr2','img_path','contrast','img_size','sobel_select','export_id','brightness']) builder.import_variables(self,['canny_thr1','canny_thr2','img_path','contrast','img_size','sobel_select','export_id','brightness'])
builder.connect_callbacks(self) builder.connect_callbacks(self)
# Load values from config after UI has been initialised # Load values from config after UI has been initialised
@ -95,19 +99,22 @@ class MainApp:
self.img_current = self.img_current + 1 self.img_current = self.img_current + 1
self.update(self) self.update(self)
def apply(self, event=None): def apply(self, event=None, path=None):
''' '''
Export current dataset Export current dataset
''' '''
# Get export settings # Get export settings
img_arr = self.tk_imgs img_arr = self.tk_imgs
img_id = self.export_id.get() img_id = self.export_id.get()
if path == None:
path = config_json["out"] path = config_json["out"]
else:
print(F"Using path: {path}")
if (img_id >= 0 and img_id < len(img_arr)): if (img_id >= 0 and img_id < len(img_arr)):
# Create file # Create file
now = datetime.datetime.now() now = datetime.datetime.now()
new_file_name = F"{now.strftime('%Y-%m-%dT%H.%M.%S')}-id{img_id}.png" new_file_name = F"{self.img_current}-{self.output[1][img_id]}-{now.strftime('%Y-%m-%dT%H.%M.%S')}.png"
# Put data # Put data
file_path = pathlib.Path(path, new_file_name) file_path = pathlib.Path(path, new_file_name)
@ -121,6 +128,25 @@ class MainApp:
else: else:
print("Nothing to export!") print("Nothing to export!")
def apply_all(self, event=None):
img_id = self.export_id.get()
img_current = copy.deepcopy(self.img_current)
now = datetime.datetime.now()
path = pathlib.Path(config_json["out"], F"{self.output[1][img_id]}-all-{now.strftime('%Y-%m-%dT%H.%M.%S')}/")
os.mkdir(path)
while True:
self.img_next()
self.update(part_update=True) # Enforce partial update since we don't need the histograms etc.
self.apply(path=path)
if (self.img_current == img_current):
break
## Ensure display is always correct with image
self.update()
def add_output(self, data, name: str): def add_output(self, data, name: str):
''' '''
Add CV2 image to canvas output Add CV2 image to canvas output
@ -162,7 +188,6 @@ class MainApp:
self.meta.insert(END, F"{idx}: {self.output[1][idx]}\n") self.meta.insert(END, F"{idx}: {self.output[1][idx]}\n")
# Clear output # Clear output
self.output = [[] for x in range(2)]
self.meta.config(state=DISABLED) self.meta.config(state=DISABLED)
# Draw canvas # Draw canvas
@ -220,9 +245,19 @@ class MainApp:
%(labels[0], mean[0], labels[1], mean[1], labels[2], mean[2], %(labels[0], mean[0], labels[1], mean[1], labels[2], mean[2],
labels[0], std[0], labels[1], std[1], labels[2], std[2])) labels[0], std[0], labels[1], std[1], labels[2], std[2]))
def update(self, event=None): def update(self, event=None, part_update=False):
path = self.img_path.get() path = self.img_path.get()
# print(path)
## Check if hist and canny hm have to be rerendered
if not part_update: ## 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:
print("Partial update forced!")
if path != None and path != "": if path != None and path != "":
# Get all images at current path # Get all images at current path
@ -240,6 +275,9 @@ class MainApp:
contrast = self.contrast.get() contrast = self.contrast.get()
bright = self.brightness.get() bright = self.brightness.get()
# Clear output
self.output = [[] for x in range(2)]
# 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)
@ -253,11 +291,12 @@ class MainApp:
contrast_val = contrast / 100 contrast_val = contrast / 100
bright_val = bright / 100 bright_val = bright / 100
img_contrast = np.clip(contrast_val * (img_gray + bright_val), 0, 255).astype(np.uint8) 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"Contrast / Brightness\n c+{contrast_val} b+{bright_val}")
self.add_output(img_contrast, F"BCG")
# Blurred edition # Blurred edition
img_blur = cv2.GaussianBlur(img_gray, (3, 3), 0) img_blur = cv2.GaussianBlur(img_gray, (3, 3), 0)
self.add_output(img_blur, "Blurred (3)") self.add_output(img_blur, "Blurred_k3")
# Sobel edge # Sobel edge
if sxy in ['x', 'y', 'both']: if sxy in ['x', 'y', 'both']:
@ -274,17 +313,18 @@ 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, F"Sobel Edge\n nz={cv2.countNonZero(img_sobel)}") self.add_output(img_sobel, "Sobel_edge")
# self.add_output(img_sobel, F"Sobel Edge\n nz={cv2.countNonZero(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") self.add_output(img_canny, "Canny_edge")
self.writeStats(img, ('B', 'G', 'R'), 0, 0) self.writeStats(img, ('B', 'G', 'R'), 0, 0)
# BGR # BGR
self.add_output(img[:, :, 0], "BGR B") self.add_output(img[:, :, 0], "BGR_B")
self.add_output(img[:, :, 1], "BGR G") self.add_output(img[:, :, 1], "BGR_G")
self.add_output(img[:, :, 2], "BGR R") self.add_output(img[:, :, 2], "BGR_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)
@ -292,15 +332,17 @@ class MainApp:
# HSV # HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
self.add_output(img_hsv, "HSV") self.add_output(img_hsv, "HSV")
self.add_output(img_hsv[:, :, 0], "HSV H") # H self.add_output(img_hsv[:, :, 0], "HSV_H") # H
self.add_output(img_hsv[:, :, 1], "HSV S") # S self.add_output(img_hsv[:, :, 1], "HSV_S") # S
self.add_output(img_hsv[:, :, 2], "HSV V") # V self.add_output(img_hsv[:, :, 2], "HSV_V") # V
if not part_update:
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)
self.writeStats(img_hsv, ('H', 'S', 'V'), 0, 1) self.writeStats(img_hsv, ('H', 'S', 'V'), 0, 1)
# Canny Heatmap # Canny Heatmap
if not part_update:
self.drawCannyHM(img, 1, 1) self.drawCannyHM(img, 1, 1)
# Show all data # Show all data