#!/usr/bin/env python # -*- coding: utf-8 -*- from gimpfu import * import ctypes import os from datetime import datetime def mapload(image, drawable): # Settings reportfile = True # generate a line report in the text file labels = True # label map load visualisation grid (time-consuming) cellcount = 10 # number of cells for map load visualization on the shortest dimension of the map # Merging steps pdb.gimp_image_undo_group_start(image) # Image size recognition and layer creation filename = pdb.gimp_layer_get_name(image.layers[0]) sizewidth = drawable.width sizeheight = drawable.height select = pdb.gimp_selection_save(image) layer1 = pdb.gimp_layer_new_from_drawable(drawable, image) # Recognising if selection was made pixels_selection = pdb.gimp_drawable_histogram(drawable, 0, 0, 1)[3] pdb.gimp_selection_all(image) pixels_all = pdb.gimp_drawable_histogram(drawable, 0, 0, 1)[3] selected_all = pixels_selection == pixels_all # Adding alpha channel if not pdb.gimp_drawable_has_alpha(drawable): pdb.gimp_layer_add_alpha(drawable) # Cropping the background if not selected_all: pdb.gimp_selection_load(select) pdb.gimp_selection_invert(image) pdb.gimp_edit_clear(drawable) pdb.gimp_selection_all(image) # Edge detection using Sobel operator pdb.plug_in_edge(image, drawable, 1, 0, 0) # Converting to greyscale according to the value parameter r_gain = 0.299 g_gain = 0.587 b_gain = 0.114 pdb.plug_in_colors_channel_mixer(image, drawable, True, r_gain, r_gain, r_gain, g_gain, g_gain, g_gain, b_gain, b_gain, b_gain) # Converting to monochrome pdb.gimp_image_convert_grayscale(image) # Bit depth recognition bytres = drawable.bpp depth = 256 ** (bytres / 2) - 1 resolution = (int(pdb.gimp_image_get_resolution(image)[0]) + int(pdb.gimp_image_get_resolution(image)[1])) / 2 # Average map load calculation pdb.gimp_selection_load(select) histogram = pdb.gimp_drawable_histogram(drawable, 0, 0, 1) if bytres == 2: ml = histogram[0] * 100 / depth elif bytres > 2: ml = histogram[0] * 100 else: ctypes.windll.user32.MessageBoxW(0, unicode("Too low bit resolution of the input file :-(", "utf-8"), u"ERROR", 0x10) exit() # Distribution grid creation pdb.gimp_selection_all(image) if sizewidth > sizeheight: cellsize = sizeheight // cellcount + (sizeheight % cellcount > 0) gridheight = cellcount gridwidth = int(sizewidth * gridheight / sizeheight) else: cellsize = sizewidth // cellcount + (sizewidth % cellcount > 0) gridwidth = cellcount gridheight = int(sizeheight * gridwidth / sizewidth) pdb.gimp_image_scale_full(image, gridwidth, gridheight, 1) cellsize_width = sizewidth / gridwidth cellsize_height = sizeheight / gridheight # Considering the cells' surroundings #pdb.plug_in_convmatrix(image, drawable, 25, [0,0,0,0,0, 0,1,2,1,0, 0,2,4,2,0, 0,1,2,1,0, 0,0,0,0,0], False, 16, 0, 5, [True, True, True, True, True], 0) # Map load calculation in grid if labels: mls = [] # map load values of cells trs = [] # transparencies of cells if bytres == 2: for grid_y in range(0, gridheight): for grid_x in range(0, gridwidth): pixel_value = pdb.gimp_drawable_get_pixel(drawable, grid_x, grid_y) mls.append(pixel_value[1][0] * 100 / depth) trs.append(pixel_value[1][1] * 100 / depth) else: for grid_y in range(0, gridheight): for grid_x in range(0, gridwidth): pixel_value = pdb.gimp_drawable_get_pixel(drawable, grid_x, grid_y) mls.append(pixel_value[1][0] * 100) trs.append(pixel_value[1][1] * 100) # SD recognition pdb.gimp_selection_load(select) if reportfile: histogram2 = pdb.gimp_drawable_histogram(drawable, 0, 0, 1) if bytres == 2: sd = histogram2[1] * 100 / depth else: sd = histogram2[1] * 100 pdb.gimp_selection_all(image) # Visualisation pdb.gimp_context_set_background((0, 0, 0)) pdb.gimp_layer_flatten(drawable) pdb.gimp_image_scale_full(image, sizewidth, sizeheight, 0) pdb.gimp_image_convert_rgb(image) pdb.gimp_image_insert_layer(image, layer1, None, -1) pdb.gimp_layer_set_opacity(layer1, 5) # Value notification message = "" if not(99 <= resolution <= 101): message = "Warning: Image resolution is " + str(resolution) + " DPI while 100 DPI is recommended.\n\n" if selected_all: intro = "Graphic map load value: " else: intro = "Graphic map load value of your selection: " message = message + intro + str(round(ml, 1)) + " %" ctypes.windll.user32.MessageBoxW(0, unicode(message, "utf-8"), u"MEASUREMENT RESULTS", 0x40) # Grid labels if labels: position_y = sizeheight / gridheight / 3 array_index = 0 row = 1 while position_y < sizeheight: position_x = cellsize_width / 3 col = 1 while position_x < sizewidth: # Defining label colours if mls[array_index] >= 50: green = int(255 - (mls[array_index] - 50) * 5.1) pdb.gimp_context_set_foreground((255, green, 0)) else: blue = int(255 - mls[array_index] * 5.1) pdb.gimp_context_set_foreground((255, 255, blue)) # Converting numbers to labels if trs[array_index]: mls[array_index] = "!!" if mls[array_index] > 100 else int(mls[array_index]) else: mls[array_index] = "" text = pdb.gimp_text_fontname(image, drawable, position_x, position_y, str(mls[array_index]), -1, False, cellsize / 3, 0, "Calibri") position_x = cellsize_width / 3 + col * cellsize_width array_index += 1 col += 1 position_y = cellsize_height / 3 + row * cellsize_height row += 1 pdb.gimp_floating_sel_anchor(pdb.gimp_image_get_floating_sel(image)) # Writing a report file if reportfile: now = datetime.now() current_time = now.strftime("%Y%m%d_%H%M%S") if not (os.path.isfile("gmlmt_report.txt") and os.path.getsize("gmlmt_report.txt") > 0): reportfile = open("gmlmt_report.txt", "a") reportfile.write("time_stamp\tfile_name\tmap_load_perc\tstd_dev_perc\tpixel_count\tresolution\n") reportfile.close() reportfile = open("gmlmt_report.txt", "a+") reportfile.write(current_time) reportfile.write("\t") reportfile.write(str(filename)) reportfile.write("\t") reportfile.write(str(round(ml, 1))) reportfile.write("\t") reportfile.write(str(round(sd, 1))) reportfile.write("\t") reportfile.write(str(int(pixels_selection))) reportfile.write("\t") if resolution == 100: reportfile.write("ok") else: reportfile.write(str(resolution)) reportfile.write("\n") reportfile.close() # Finishing merged steps pdb.gimp_image_undo_group_end(image) register( "MAPLOAD_1-5", "Experimental tool for graphic map load measurement based on edge detection", "Experimental tool for graphic map load measurement based on edge detection using Sobel operator, developed at the Department of Geoinformatics, Palacký University Olomouc (RGB images with resolution 100 DPI prefered)", "Radek Barvíř", "CC BY-SA", "v 1.5, build 240529, 2024", "GMLMT 1.5 en", "RGB*", [ (PF_IMAGE, "image", "takes current image", None), (PF_DRAWABLE, "drawable", "Input layer", None) ], [], mapload, menu="/Filters/Edge-Detect") main()