#!/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 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) floating_sel = pdb.gimp_image_get_floating_sel(image) # Pixel count recognition for selection and image px = pdb.gimp_drawable_histogram(drawable, 0, 0, 1)[3] pdb.gimp_selection_all(image) px2 = pdb.gimp_drawable_histogram(drawable, 0, 0, 1)[3] # Edge detection using Sobel operator pdb.plug_in_edge(image, drawable, 1, 0, 0) # Converting to gryscale according to the value parameter monochrome = TRUE rr_gain = 0.299 rg_gain = 0.299 rb_gain = 0.299 gr_gain = 0.587 gg_gain = 0.587 gb_gain = 0.587 br_gain = 0.114 bg_gain = 0.114 bb_gain = 0.114 pdb.plug_in_colors_channel_mixer(image, drawable, monochrome, rr_gain, rg_gain, rb_gain, gr_gain, gg_gain, gb_gain, br_gain, bg_gain, bb_gain) # Converting to monochrome pdb.gimp_image_convert_grayscale(image) # Bit depth recognition bytres = drawable.bpp if pdb.gimp_drawable_has_alpha(drawable): depth = (256 ** (bytres / 2)) - 1 else: depth = (256 ** bytres) - 1 resolution = (int(pdb.gimp_image_get_resolution(image)[0]) + int(pdb.gimp_image_get_resolution(image)[1])) / 2 # Map load calculation pdb.gimp_selection_load(select) histogram = pdb.gimp_drawable_histogram(drawable, 0, 0, 1) if bytres == 1 or (bytres == 2 and pdb.gimp_drawable_has_alpha(drawable)): ml = histogram[0] * 100 / depth else: ml = histogram[0] * 100 # Grid creation pdb.gimp_selection_all(image) if sizewidth > sizeheight: cellsize = int(sizeheight / cellcount) + (sizeheight % cellcount > 0) gridheight = cellcount gridwidth = int(1.0 * cellcount / sizeheight * sizewidth) pdb.gimp_image_scale_full(image, gridwidth, gridheight, 1) else: cellsize = int(sizewidth / cellcount) + (sizewidth % cellcount > 0) gridwidth = cellcount gridheight = int(1.0 * cellcount / sizewidth * sizeheight) pdb.gimp_image_scale_full(image, gridwidth, gridheight, 1) 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: grid_y = 0 mls = [] while (grid_y < gridheight): grid_x = 0 while (grid_x < gridwidth): pixelvalue = pdb.gimp_drawable_get_pixel(drawable, grid_x, grid_y) if bytres == 1 or (bytres == 2 and pdb.gimp_drawable_has_alpha(drawable)): mls.append(pixelvalue[1][0] * 100 / depth) else: mls.append(pixelvalue[1][0] * 100) grid_x += 1 grid_y += 1 mean = sum(mls) / len(mls) # SD recognition pdb.gimp_selection_load(select) if reportfile: histogram2 = pdb.gimp_drawable_histogram(drawable, 0, 0, 1) if bytres == 1 or (bytres == 2 and pdb.gimp_drawable_has_alpha(drawable)): sd = histogram2[1] / depth * 100 else: sd = histogram2[1] * 100 # Visualisation pdb.gimp_image_scale_full(image, sizewidth, sizeheight, 0) pdb.gimp_image_convert_rgb(image) if px != px2: if not(pdb.gimp_drawable_has_alpha(drawable)): pdb.gimp_layer_add_alpha(drawable) pdb.gimp_image_insert_layer(image, layer1, None, -1) pdb.gimp_layer_set_opacity(layer1, 5) # 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(px))) reportfile.write("\t") if resolution == 100: reportfile.write("ok") else: reportfile.write(str(resolution)) reportfile.write("\n") reportfile.close() # Value notification message = "" if resolution != 100: message = " Warning: Image resolution is " + str(resolution) + " DPI while 100 DPI is recommended.\n\n" message = message + " Graphic map load value: " + 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 arrayindex = 0 row = 1 while (position_y < sizeheight): position_x = sizewidth / gridwidth / 3 col = 1 while (position_x < sizewidth): mls[arrayindex] = mls[arrayindex] * ml / mean if (mls[arrayindex] >= 50): green = int(255 - (mls[arrayindex] - 50) * 5.1) pdb.gimp_context_set_foreground((255,green,0)) else: blue = int(255 - mls[arrayindex] * 5.1) pdb.gimp_context_set_foreground((255,255,blue)) text = pdb.gimp_text_fontname(image, drawable, position_x, position_y, int(mls[arrayindex]), -1, FALSE, cellsize / 3, 0, "Calibri") position_x = sizewidth / gridwidth / 3 + col * sizewidth / gridwidth arrayindex += 1 col += 1 position_y = sizeheight / gridheight / 3 + row * sizeheight / gridheight row += 1 pdb.gimp_floating_sel_anchor(pdb.gimp_image_get_floating_sel(image)) # Finishing merged steps pdb.gimp_image_undo_group_end(image) register( "MAPLOAD_1-3", "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 within the research project Graphic map load evaluation using metrics based od raster format (resolution 100 DPI prefered)", "Radek Barvíř", "CC BY-SA", "v 1.3, build 210401, 2021", "GMLMT 1.3 en", "RGB*", [ (PF_IMAGE, "image", "takes current image", None), (PF_DRAWABLE, "drawable", "Input layer", None) ], [], mapload, menu="/Filters/Edge-Detect") main()