SA-Kenan/01_Auswertung/Auswertung_Farbkanaele_V01-00.py

222 lines
13 KiB
Python
Raw Permalink Normal View History

2022-05-09 20:30:26 +02:00
# Date: 18.12.2021
# Author: Kenan Gömek
# Das Skript stellt die unterschiedlichen Farbkanäle der aufgenommenen Bilder dar und erstellt schnitte, um die Pixelwerte anzuzeigen.
# Update:21.12.2021
# Update Comment: Dominierender Farbkanal wird automatisch erkannt und die Zeilen- und Spaltenmarkierungen werden alle nach dem hellsten
# Punkt im dominierenden Farbkanal gerichtet
# Import needed Packages
import cv2 as cv
import numpy as np
import time
from datetime import datetime
import os
from matplotlib import pyplot as plt
# define User Input
# No vowels in path name!'
PATH_IMAGE_FOLDER = r'U:\bwsyncshare\Auswertung'
COMMENT = "" # User Comment for plot
# select cut mode for determining pixel values
cut_mode = 'auto' # options: 'auto', 'manual'
ROW = 152 # Row-Number for Cut [Pixels] for cut_mode 'manual' index begins from 0
COLUMN = 1742 # Column-Number for Cut [Pixels] for cut_mode 'manual' index begins from 0
# define functions
def calc_arithmetic_mean_of_brightness_per_pixel(r, g, b):
"""Calculate overall brightness per pixel of the image. Mittelere Helligkeit pro pixel berechnen."""
r = r.astype('uint16') # set dtype of one colour to uint16, because the sum of 255+255+255 >255 =765
# the rest will also be uint16 then
image_heigth = r.shape[0]
image_width = r.shape[1]
number_of_colour_channels = 3
arithmetic_mean_of_brightness_image = np.sum((r+g+b)/number_of_colour_channels)
arithmetic_mean_of_brightness_per_pixel = arithmetic_mean_of_brightness_image/(image_width*image_heigth)
max_possible_brightness = 255 # maximum possible brightness for an uint8
arithmetic_mean_of_brightness_per_pixel_relative = arithmetic_mean_of_brightness_per_pixel/max_possible_brightness # range: 0-1
return arithmetic_mean_of_brightness_per_pixel_relative
# start
image_filenames = [f for f in os.listdir(PATH_IMAGE_FOLDER) if f.endswith('.png')]
image_filenames.sort()
for image_number, image_name in enumerate(image_filenames):
print(f"Current image {image_number+1}/{len(image_filenames)}: {image_name}")
# Split and Merge colour channels
img_bgr = cv.imread(os.path.join(PATH_IMAGE_FOLDER,image_name), cv.IMREAD_COLOR)
b, g, r = cv.split(img_bgr)
img_rgb = img_bgr[:, :, ::-1]
# Create Cuts and display Pixel Values
image_width = r.shape[1]
if image_width < 1000:
plot_marker_offset = 4 # Thickness of marker-line in plot in pixels
elif image_width >= 1000:
plot_marker_offset = 10 # Thickness of marker-line in plot in pixels
# Identify dominating colour channel and set cut row and column
max_pixelvalue_red = r.max(); max_pixelvalue_green = g.max(); max_pixelvalue_blue = b.max()
max_pixelvalue = np.max([max_pixelvalue_red, max_pixelvalue_green, max_pixelvalue_blue])
idx_max_pixelvalue_red = np.unravel_index(r.argmax(), r.shape) # row=idx_..[0] column=idx_..[1]
idx_max_pixelvalue_green = np.unravel_index(g.argmax(), g.shape) # row=idx_..[0] column=idx_..[1]
idx_max_pixelvalue_blue = np.unravel_index(b.argmax(), b.shape) # row=idx_..[0] column=idx_..[1]
if max_pixelvalue == max_pixelvalue_red:
idx_max_pixelvalue = idx_max_pixelvalue_red; msg_dominating_colourchannel = 'red'
elif max_pixelvalue == max_pixelvalue_green:
idx_max_pixelvalue = idx_max_pixelvalue_green; msg_dominating_colourchannel = 'green'
elif max_pixelvalue == max_pixelvalue_blue:
idx_max_pixelvalue = idx_max_pixelvalue_blue; msg_dominating_colourchannel = 'blue'
if cut_mode == 'auto':
cut_row = idx_max_pixelvalue[0]; cut_column = idx_max_pixelvalue[1]
elif cut_mode == 'manual':
cut_row = ROW; cut_column = COLUMN
else:
print('Wrong cut_mode. End script.'); quit()
# Red channel
# Info linspace(start, stop, num):
# stop: The end value of the sequence --> stop is included
# num: Number of samples to generate.
# Because Array stars at index 0: e.g. image with 3280x2464 Pixels: for 3280 Pixels you need 3280 values between 0 and 3279
# check: x_red_h must have 3280 values?? --> Yes from 0 to 3279 in 1 steps
x_red_h = np.linspace(0, r.shape[1]-1, r.shape[1]); y_red_h = r[cut_row,:] # data horizontal cut ->width (e.g.: 3280)
x_red_v = np.linspace(0, r.shape[0]-1, r.shape[0]); y_red_v = r[:,cut_column] # data vertical cut ->height (e.g.: 2464)
msg1_red = f"Maximum Pixel value in red channel: {max_pixelvalue_red}"; print(msg1_red)
msg2_red = f"Index of max Value in red channel (row, colum): {idx_max_pixelvalue_red}"; print(msg2_red)
msg3_red = f"Maximum Pixel value in marked-row {cut_row}: {np.max(y_red_h)}"; print(msg3_red)
msg4_red = f"Maximum Pixel value in marked-column {cut_column}: {np.max(y_red_v)}"; print(msg4_red)
r_copy = r.copy(); r_copy[cut_row:cut_row+plot_marker_offset,:]=255; r_copy[:, cut_column:cut_column+plot_marker_offset]=255 # manipulate image for displaying in marked plot
# Green channel
x_green_h = np.linspace(0, g.shape[1]-1, g.shape[1]); y_green_h = g[cut_row,:] # data horizontal cut
x_green_v = np.linspace(0, g.shape[0]-1, g.shape[0]); y_green_v = g[:,cut_column] # data vertical cut
msg1_green = f"Maximum Pixel value in green channel: {max_pixelvalue_green}"; print(msg1_green)
msg2_green = f"Index of max Value in green channel (row, colum): {idx_max_pixelvalue_green}"; print(msg2_green)
msg3_green = f"Maximum Pixel value in marked-row {cut_row}: {np.max(y_green_h)}"; print(msg3_green)
msg4_green = f"Maximum Pixel value in marked-column {cut_column}: {np.max(y_green_v)}"; print(msg4_green)
g_copy = g.copy(); g_copy[cut_row:cut_row+plot_marker_offset,:]=255; g_copy[:, cut_column:cut_column+plot_marker_offset]=255 # manipulate image for displaying in marked plot
# Blue channel
x_blue_h = np.linspace(0, b.shape[1]-1, b.shape[1]); y_blue_h = b[cut_row,:] # data horizontal cut
x_blue_v = np.linspace(0, b.shape[0]-1, b.shape[0]); y_blue_v = b[:,cut_column] # data vertical cut
msg1_blue = f"Maximum Pixel value in blue channel: {max_pixelvalue_blue}"; print(msg1_blue)
msg2_blue = f"Index of max Value in blue channel (row, colum): {idx_max_pixelvalue_blue}"; print(msg2_blue)
msg3_blue = f"Maximum Pixel value in marked-row {cut_row}: {np.max(y_blue_h)}"; print(msg3_blue)
msg4_blue = f"Maximum Pixel value in marked-column {cut_column}: {np.max(y_blue_v)}"; print(msg4_blue)
b_copy = b.copy(); b_copy[cut_row:cut_row+plot_marker_offset,:]=255; b_copy[:, cut_column:cut_column+plot_marker_offset]=255 # manipulate image for displaying in marked plot
# Create Plots
fig1, ((ax_orig_1,ax01,ax02,ax03),(ax_red_1, ax_red_2, ax_red_3, ax_red_4),
(ax_green_1, ax_green_2, ax_green_3, ax_green_4),(ax_blue_1, ax_blue_2, ax_blue_3, ax_blue_4)) \
= plt.subplots(4, 4, figsize=(30,25))
fig1.suptitle(f'Image: {image_name}', y=0.9)
yticks=np.append(np.arange(0,230,25), 255) #set yticks for cuts
xlim_max_h=r.shape[1] # xlim for horizontal cut. No special reason for choosing red channel.
xlim_max_v=r.shape[0] # xlim for vertical cut. No special reason for choosing red channel.
ax_orig_1.imshow(img_rgb); ax_orig_1.set_title("Original Image");
ax_orig_1.set_xlabel('Width=H=Columns'); ax_orig_1.set_ylabel('Heigth=V=Rows')
# red channel
ax_red_1.imshow(r, cmap = 'gray'); ax_red_1.set_title("Red Channel");
ax_red_1.set_xlabel('Width=H=Columns'); ax_red_1.set_ylabel('Heigth=V=Rows')
ax_red_2.imshow(r_copy, cmap = 'gray'); ax_red_2.set_title("Red Channel - marked");
ax_red_2.set_xlabel('Width=H=Columns'); ax_red_2.set_ylabel('Heigth=V=Rows')
ax_red_3.plot(x_red_h,y_red_h, linewidth=2.0); ax_red_3.set_title("Horizontal Cut");
ax_red_3.grid(True); ax_red_3.set_ylim(ymin=0, ymax=260); ax_red_3.set_yticks(yticks); ax_red_3.set_xlim(0,xlim_max_h)
ax_red_3.set_xlabel('Width=H=Columns'); ax_red_3.set_ylabel('Pixel Value')
ax_red_4.plot(x_red_v,y_red_v, linewidth=2.0); ax_red_4.set_title("Vertical Cut");
ax_red_4.grid(True); ax_red_4.set_ylim(ymin=0, ymax=260); ax_red_4.set_yticks(yticks); ax_red_4.set_xlim(0, xlim_max_v)
ax_red_4.set_xlabel('Heigth=V=Rows'); ax_red_4.set_ylabel('Pixel Value')
# green channel
ax_green_1.imshow(g, cmap = 'gray'); ax_green_1.set_title("Green Channel");
ax_green_1.set_xlabel('Width=H=Columns'); ax_green_1.set_ylabel('Heigth=V=Rows')
ax_green_2.imshow(g_copy, cmap = 'gray'); ax_green_2.set_title("Green Channel - marked");
ax_green_2.set_xlabel('Width=H=Columns'); ax_green_2.set_ylabel('Heigth=V=Rows')
ax_green_3.plot(x_green_h,y_green_h, linewidth=2.0); ax_green_3.set_title("Horizontal Cut");
ax_green_3.grid(True); ax_green_3.set_ylim(ymin=0, ymax=260); ax_green_3.set_yticks(yticks); ax_green_3.set_xlim(0,xlim_max_h)
ax_green_3.set_xlabel('Width=H=Columns'); ax_green_3.set_ylabel('Pixel Value')
ax_green_4.plot(x_green_v,y_green_v, linewidth=2.0); ax_green_4.set_title("Vertical Cut");
ax_green_4.grid(True); ax_green_4.set_ylim(ymin=0, ymax=260); ax_green_4.set_yticks(yticks); ax_green_4.set_xlim(0, xlim_max_v)
ax_green_4.set_xlabel('Heigth=V=Rows'); ax_green_4.set_ylabel('Pixel Value')
# blue channel
ax_blue_1.imshow(b, cmap = 'gray'); ax_blue_1.set_title("Blue Channel");
ax_blue_1.set_xlabel('Width=H=Columns'); ax_blue_1.set_ylabel('Heigth=V=Rows')
ax_blue_2.imshow(b_copy, cmap = 'gray'); ax_blue_2.set_title("Blue Channel - marked");
ax_blue_2.set_xlabel('Width=H=Columns'); ax_blue_2.set_ylabel('Heigth=V=Rows')
ax_blue_3.plot(x_blue_h,y_blue_h, linewidth=2.0); ax_blue_3.set_title("Horizontal Cut");
ax_blue_3.grid(True); ax_blue_3.set_ylim(ymin=0, ymax=260); ax_blue_3.set_yticks(yticks); ax_blue_3.set_xlim(0,xlim_max_h)
ax_blue_3.set_xlabel('Width=H=Columns'); ax_blue_3.set_ylabel('Pixel Value')
ax_blue_4.plot(x_blue_v,y_blue_v, linewidth=2.0); ax_blue_4.set_title("Vertical Cut");
ax_blue_4.grid(True); ax_blue_4.set_ylim(ymin=0, ymax=260); ax_blue_4.set_yticks(yticks); ax_blue_4.set_xlim(0, xlim_max_v)
ax_blue_4.set_xlabel('Heigth=V=Rows'); ax_blue_4.set_ylabel('Pixel Value')
# Calculate overall brightness per pixel of the image. Mittelere Helligkeit pro pixel berechnen.
arithmetic_mean_of_brightness_per_pixel_relative = calc_arithmetic_mean_of_brightness_per_pixel(r,g,b)
if arithmetic_mean_of_brightness_per_pixel_relative >= 0.01:
msg1_brightness = f"Overall brightness per pixel: {round(arithmetic_mean_of_brightness_per_pixel_relative*100,2)} %" #value in percent
elif arithmetic_mean_of_brightness_per_pixel_relative < 0.01:
msg1_brightness = f"Overall brightness per pixel: {round(arithmetic_mean_of_brightness_per_pixel_relative*10e3,2)} per mil" # value in promille
print(msg1_brightness)
# add pixel stats under Figure
pixelstats_red= '\n'.join([msg1_red, msg2_red, msg3_red, msg4_red])
pixelstats_green= '\n'.join([msg1_green, msg2_green, msg3_green, msg4_green])
pixelstats_blue= '\n'.join([msg1_blue, msg2_blue, msg3_blue, msg4_blue])
pixelstats_overall_brightness = '\n'.join([msg1_brightness])
pixelstats = '\n\n'.join([f"pixel stats: {msg_dominating_colourchannel} channel dominating",
pixelstats_red, pixelstats_green, pixelstats_blue, pixelstats_overall_brightness])
text_x_pos = 0.1; text_y_pos = -0.015 # text position: 0,0 is lower-left and 1,1 is upper-right)
fig1.text(text_x_pos, text_y_pos, pixelstats, ha='left')
# add Comment under Figure
text_x_pos = 0.5; text_y_pos = -0.025 # text position: 0,0 is lower-left and 1,1 is upper-right)
log_filename=None
try:
log_filename=[f for f in os.listdir(PATH_IMAGE_FOLDER) if f.endswith('.txt')][0]
if log_filename:
with open(os.path.join(PATH_IMAGE_FOLDER,log_filename), encoding='utf-8') as f:
log_text = f.readlines()
if COMMENT != "":
COMMENT = '\nPlot Comment: '+COMMENT
log_text.append(COMMENT)
txt=''.join(log_text)
fig1.text(text_x_pos, text_y_pos, txt, ha='left')
except IndexError:
if COMMENT != "":
COMMENT = '\nPlot Comment: '+COMMENT
fig1.text(text_x_pos, text_y_pos, COMMENT, ha='left')
else:
pass
# handle numpy memmory error on Windows:
switch_overwrite=0 # do not overwrite files, if they exist
if switch_overwrite == 1:
fig1.savefig(os.path.join(PATH_IMAGE_FOLDER,f'{image_name}.pdf'), bbox_inches='tight') #save plot
print('Save pdf')
else:
if os.path.isfile(os.path.join(PATH_IMAGE_FOLDER,f'{image_name}.pdf')):
pass # skip this pdf file, because it already exists
else:
fig1.savefig(os.path.join(PATH_IMAGE_FOLDER,f'{image_name}.pdf'), bbox_inches='tight') #save plot
print('Save pdf')
plt.close('all') # close all figures
print('') # new line for better readability in console