Merge branch 'main' of https://arnweb.nl/gitea/arne/EV5_Beeldherk_Bomen
This commit is contained in:
commit
a8c7581fac
BIN
res/essay/2-5-1_bgr.png
Normal file
BIN
res/essay/2-5-1_bgr.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 426 KiB |
BIN
res/essay/2-5-1_bgr_expanded.png
Normal file
BIN
res/essay/2-5-1_bgr_expanded.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 427 KiB |
BIN
res/essay/2-5-1_bgr_histogram.png
Normal file
BIN
res/essay/2-5-1_bgr_histogram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
res/essay/2-5-1_hsv.png
Normal file
BIN
res/essay/2-5-1_hsv.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 398 KiB |
BIN
res/essay/2-5-1_hsv_expanded.png
Normal file
BIN
res/essay/2-5-1_hsv_expanded.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 398 KiB |
BIN
res/essay/2-5-1_hsv_histogram.png
Normal file
BIN
res/essay/2-5-1_hsv_histogram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
@ -1,4 +1,5 @@
|
||||
{
|
||||
"path": "",
|
||||
"out": "",
|
||||
"size": 750
|
||||
}
|
@ -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()
|
@ -192,12 +192,12 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="ttk.Button" id="button3">
|
||||
<property name="text" translatable="yes">Useless button</property>
|
||||
<property name="text" translatable="yes">Export PNG</property>
|
||||
<bind sequence="<ButtonPress>" handler="apply" add="" />
|
||||
<layout manager="grid">
|
||||
<property name="column">2</property>
|
||||
<property name="columnspan">1</property>
|
||||
<property name="ipadx">0</property>
|
||||
<property name="ipadx">10</property>
|
||||
<property name="row">7</property>
|
||||
<property name="rowspan">1</property>
|
||||
</layout>
|
||||
@ -215,7 +215,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="ttk.Label" id="label1">
|
||||
<property name="text" translatable="yes">Useless imput</property>
|
||||
<property name="text" translatable="yes">Export Image by ID</property>
|
||||
<layout manager="grid">
|
||||
<property name="column">1</property>
|
||||
<property name="columnspan">2</property>
|
||||
@ -228,8 +228,10 @@
|
||||
<property name="height">15</property>
|
||||
<property name="pady">0</property>
|
||||
<property name="selectborderwidth">4</property>
|
||||
<property name="setgrid">false</property>
|
||||
<property name="state">disabled</property>
|
||||
<property name="text" translatable="yes">Image metadata should appear here</property>
|
||||
<property name="takefocus">true</property>
|
||||
<property name="text" translatable="yes">Image IDs should appear here</property>
|
||||
<property name="width">25</property>
|
||||
<property name="wrap">word</property>
|
||||
<layout manager="grid">
|
||||
@ -282,6 +284,28 @@
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ttk.Button" id="export_all" named="True">
|
||||
<property name="text" translatable="yes">Export ID for entire dataset</property>
|
||||
<bind sequence="<ButtonRelease>" 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 & TomSelier.com</property>
|
||||
<layout manager="grid">
|
||||
<property name="column">0</property>
|
||||
<property name="row">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
89
src/suite.py
89
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,18 +99,54 @@ 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")
|
||||
# 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):
|
||||
'''
|
||||
Add CV2 image to canvas output
|
||||
@ -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,15 +332,17 @@ 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 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
|
||||
if not part_update:
|
||||
self.drawCannyHM(img, 1, 1)
|
||||
|
||||
# Show all data
|
||||
|
Loading…
Reference in New Issue
Block a user