diff --git a/res/essay/2-5-1_bgr.png b/res/essay/2-5-1_bgr.png new file mode 100644 index 0000000..f75827a Binary files /dev/null and b/res/essay/2-5-1_bgr.png differ diff --git a/res/essay/2-5-1_bgr_expanded.png b/res/essay/2-5-1_bgr_expanded.png new file mode 100644 index 0000000..87a5f31 Binary files /dev/null and b/res/essay/2-5-1_bgr_expanded.png differ diff --git a/res/essay/2-5-1_bgr_histogram.png b/res/essay/2-5-1_bgr_histogram.png new file mode 100644 index 0000000..53b977a Binary files /dev/null and b/res/essay/2-5-1_bgr_histogram.png differ diff --git a/res/essay/2-5-1_hsv.png b/res/essay/2-5-1_hsv.png new file mode 100644 index 0000000..5825d67 Binary files /dev/null and b/res/essay/2-5-1_hsv.png differ diff --git a/res/essay/2-5-1_hsv_expanded.png b/res/essay/2-5-1_hsv_expanded.png new file mode 100644 index 0000000..c474f5a Binary files /dev/null and b/res/essay/2-5-1_hsv_expanded.png differ diff --git a/res/essay/2-5-1_hsv_histogram.png b/res/essay/2-5-1_hsv_histogram.png new file mode 100644 index 0000000..27196ea Binary files /dev/null and b/res/essay/2-5-1_hsv_histogram.png differ diff --git a/src/config/config.template.json b/src/config/config.template.json index 7594d9d..a17404f 100644 --- a/src/config/config.template.json +++ b/src/config/config.template.json @@ -1,4 +1,5 @@ { "path": "", + "out": "", "size": 750 } \ No newline at end of file diff --git a/src/experiments/algorithms/colourspace.py b/src/experiments/algorithms/colourspace.py index 0667ec9..571d434 100644 --- a/src/experiments/algorithms/colourspace.py +++ b/src/experiments/algorithms/colourspace.py @@ -16,53 +16,68 @@ def histNormalize(hist): for i in range(len(hist)): hist[i][0] = (hist[i][0] - min_val)/(max_val - min_val) +DATASET_PATH = "C:\\Users\\Tom\\Desktop\\Files\\Repositories\\EV5_Beeldherk_Bomen\\res\\trees\\" +SAVE_PATH = "C:\\Users\\Tom\\Desktop\\Files\\Repositories\\EV5_Beeldherk_Bomen\\res\\essay\\" +IMAGE = "berk_sq1_original.png" -# DATASET_PATH = "C:\\Users\\Tom\\Desktop\\Files\\Repositories\\snake-vault\\TREES\\dataset\\" -# full_img = cv2.imread(DATASET_PATH + "alder\\1.jpg", 1) +full_img = cv2.imread(DATASET_PATH + IMAGE, 1) +assert full_img is not None, "Path is wrong: " + DATASET_PATH + IMAGE -DATASET_PATH = "..\\..\\..\\res\\trees\\" -full_img = cv2.imread(DATASET_PATH + "berk_sq1_original.png", 1) -assert full_img is not None, "Path is wrong" bgr_img = cv2.resize(full_img, (0, 0), fx=0.25, fy=0.25) hsv_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2HSV) -# cv2.imshow('BGR',bgr_img) -# cv2.imshow('HSV',hsv_img) -# cv2.imshow('HSV - H',hsv_img[:, :, 0]) -# cv2.imshow('HSV - S',hsv_img[:, :, 1]) -# cv2.imshow('HSV - V',hsv_img[:, :, 2]) +cv2.imshow('BGR', bgr_img) +BGR = np.concatenate((bgr_img[:, :, 0], bgr_img[:, :, 1], bgr_img[:, :, 2]), + axis=1) +cv2.imshow("BGR - Expanded", BGR) + +cv2.imshow('HSV', hsv_img) +HSV = np.concatenate((hsv_img[:, :, 0], hsv_img[:, :, 1], hsv_img[:, :, 2]), + axis=1) +cv2.imshow("HSV - Expanded", HSV) + +cv2.imwrite(SAVE_PATH + "2-5-1_bgr.png", bgr_img) +cv2.imwrite(SAVE_PATH + "2-5-1_bgr_expanded.png", BGR) + +cv2.imwrite(SAVE_PATH + "2-5-1_hsv.png", hsv_img) +cv2.imwrite(SAVE_PATH + "2-5-1_hsv_expanded.png", HSV) -print("BGR") mean, std = imgStats(bgr_img) print(mean) print(std) print() +mean, std = imgStats(hsv_img) +print(mean) +print(std) +print() + +cv2.waitKey(0) +cv2.destroyAllWindows() + hist = cv2.calcHist([bgr_img], [0], None, [256], [0,256]) plt.plot(hist, label='B', c='b') hist = cv2.calcHist([bgr_img], [1], None, [256], [0,256]) plt.plot(hist, label='G', c='g') hist = cv2.calcHist([bgr_img], [2], None, [256], [0,256]) plt.plot(hist, label='R', c='r') +plt.title("BGR histogram") +plt.xlabel("Waarde van pixels [0-255]") +plt.ylabel("Hoeveelheid pixels") plt.grid() plt.legend() plt.show() -print("HSV") -mean, std = imgStats(hsv_img) -print(mean) -print(std) - hist = cv2.calcHist([hsv_img], [0], None, [256], [0,256]) plt.plot(hist, label='H') hist = cv2.calcHist([hsv_img], [1], None, [256], [0,256]) plt.plot(hist, label='S') hist = cv2.calcHist([hsv_img], [2], None, [256], [0,256]) plt.plot(hist, label='V') +plt.title("HSV histogram") +plt.xlabel("Waarde van pixels [0-255]") +plt.ylabel("Hoeveelheid pixels") plt.grid() plt.legend() -plt.show() - -cv2.waitKey(0) -cv2.destroyAllWindows() \ No newline at end of file +plt.show() \ No newline at end of file diff --git a/src/helpers/gui/main.ui b/src/helpers/gui/main.ui index 6f882ea..27b05d0 100644 --- a/src/helpers/gui/main.ui +++ b/src/helpers/gui/main.ui @@ -192,12 +192,12 @@ - Useless button + Export PNG 2 1 - 0 + 10 7 1 @@ -215,7 +215,7 @@ - Useless imput + Export Image by ID 1 2 @@ -228,8 +228,10 @@ 15 0 4 + false disabled - Image metadata should appear here + true + Image IDs should appear here 25 word @@ -282,6 +284,28 @@ + + + Export ID for entire dataset + + + 1 + 2 + 30 + 8 + + + + + + TkIconFont + Powered by ARNweb.nl & TomSelier.com + + 0 + 8 + + + diff --git a/src/suite.py b/src/suite.py index 16988e4..cc27040 100644 --- a/src/suite.py +++ b/src/suite.py @@ -10,6 +10,9 @@ import time import matplotlib.pyplot as plt import json from helpers.statistics import imgStats +import datetime +import os +import copy ## UI config load PROJECT_PATH = pathlib.Path(__file__).parent @@ -38,6 +41,7 @@ class MainApp: # Keep track of images in dataset self.img_current = 0 + self.img_old = -1 self.img_max = 0 # Plots @@ -48,12 +52,14 @@ class MainApp: self.canny_thr2 = None self.img_path = None self.contrast = 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.export_id = None self.brightness = None builder.import_variables(self,['canny_thr1','canny_thr2','img_path','contrast','img_size','sobel_select','export_id','brightness']) - builder.connect_callbacks(self) # Load values from config after UI has been initialised @@ -93,17 +99,53 @@ class MainApp: self.img_current = self.img_current + 1 self.update(self) - def apply(self, event=None): + def apply(self, event=None, path=None): ''' Export current dataset ''' + # Get export settings img_arr = self.tk_imgs img_id = self.export_id.get() + if path == None: + path = config_json["out"] + else: + print(F"Using path: {path}") - if (img_id >= 0 and img_id < len(img_arr)): - print("export") + if (img_id >= 0 and img_id < len(img_arr)): + # Create file + now = datetime.datetime.now() + new_file_name = F"{self.img_current}-{self.output[1][img_id]}-{now.strftime('%Y-%m-%dT%H.%M.%S')}.png" + + # Put data + file_path = pathlib.Path(path, new_file_name) + # print(file_path) + + imgpil = ImageTk.getimage(self.tk_imgs[img_id]) + imgpil.save(file_path, "PNG" ) + imgpil.close() + + print(f"Exported Image ID {img_id} to {os.path.join(path, new_file_name)}") else: 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): ''' @@ -146,7 +188,6 @@ class MainApp: 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 @@ -204,9 +245,20 @@ class MainApp: %(labels[0], mean[0], labels[1], mean[1], labels[2], mean[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() + ## 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 != "": # Get all images at current path images = [] @@ -223,6 +275,9 @@ class MainApp: contrast = self.contrast.get() bright = self.brightness.get() + # Clear output + self.output = [[] for x in range(2)] + # Import and resize image img = cv2.imread(images[self.img_current]) img = cv2.resize(img, (size, size), interpolation = cv2.INTER_AREA) @@ -236,11 +291,12 @@ class MainApp: 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"Contrast / Brightness\n c+{contrast_val} b+{bright_val}") + self.add_output(img_contrast, F"BCG") # Blurred edition 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 if sxy in ['x', 'y', 'both']: @@ -257,17 +313,18 @@ class MainApp: img_sobel = cv2.Sobel(src=img_blur, ddepth=cv2.CV_8U, dx=dx, dy=dy, ksize=5) else: 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 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) # BGR - self.add_output(img[:, :, 0], "BGR B") - self.add_output(img[:, :, 1], "BGR G") - self.add_output(img[:, :, 2], "BGR 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) @@ -275,16 +332,18 @@ 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.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) - self.writeStats(img_hsv, ('H', 'S', 'V'), 0, 1) + if not part_update: + if img_hsv is not None: + self.drawHist(img_hsv, ('H', 'S', 'V'), 0, 1) + self.writeStats(img_hsv, ('H', 'S', 'V'), 0, 1) # Canny Heatmap - self.drawCannyHM(img, 1, 1) + if not part_update: + self.drawCannyHM(img, 1, 1) # Show all data plt.show(block=False) ## Graphs