Searching for python script islands to layers - Printable Version +- Gimp-Forum.net (https://www.gimp-forum.net) +-- Forum: GIMP (https://www.gimp-forum.net/Forum-GIMP) +--- Forum: Extending the GIMP (https://www.gimp-forum.net/Forum-Extending-the-GIMP) +--- Thread: Searching for python script islands to layers (/Thread-Searching-for-python-script-islands-to-layers) |
RE: Searching for python script islands to layers - Ofnuts - 01-22-2018 1) No, I don't know what you mean. Are you taking in account the fact that the Y coordinates go down and not up? 2) The layer variable is actually a Python object(*) with a writable "name" attribute, so you can do something like: Code: layer.name="Layer %03d" % some_sequence_number or even Code: layer.name="Object @(%3d,%3d)" % (i*sample,j*sample) Speaking of "i*sample", a seasoned Pythonista would loop like this: [code] for x in range(0,img.width,sample): for y in range(0,img.height,sample): # and use x,y instead of i*sample,j*sample [code] (*) Most things you manipulate are: image, drawable, layer (subclass of drawable), channel... and they have methods that wrap the most used pdb.* calls. See this not so complete doc and if you are curious, do a "dir(image)" or "dir(layer)" or "dir(gimp)" in your Python console. RE: Searching for python script islands to layers - mich_lloid - 01-22-2018 (01-22-2018, 10:52 PM)Ofnuts Wrote: 1) No, I don't know what you mean. Are you taking in account the fact that the Y coordinates go down and not up?Thanks for the tips 1) The selection went vertically instead of horizontally, i had to switch image.height loop with image.width, very counter intuative. I also have to apply the mask layer for this script to work, thankfully the color data of the transparent pixels is preserved. The code now looks like this: Code: img = gimp.image_list()[0] Could you make it go faster? RE: Searching for python script islands to layers - Ofnuts - 01-23-2018 (01-22-2018, 11:30 PM)mich_lloid Wrote: 1) The selection went vertically instead of horizontally, i had to switch image.height loop with image.width, very counter intuitive. Well, *you* wrote the inner loop on Y so the computer abides There is nothing "intuitive" in programming, at least not at the beginning. (01-22-2018, 11:30 PM)mich_lloid Wrote: I also have to apply the mask layer for this script to work, thankfully the color data of the transparent pixels is preserved. get_pixel() is possibly somewhat faster than pdb.gimp_color_picker(img, layer, x, y, 0,0,0) Set a variable to the initial active layer and stop wondering what layer is the active one after that. "bounds = pdb.gimp_selection_bounds(img)" is better written "_, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image)" and then use x1,x2,y1,y2... instead of indexing bounds[]. Not much faster but easier to read. "_" is by convention the nale of a variable you won't use. You are playing with fire, what if you sample in the hole inside an object? RE: Searching for python script islands to layers - mich_lloid - 01-23-2018 "get_pixel() is possibly somewhat faster than pdb.gimp_color_picker(img, layer, x, y, 0,0,0)" Wow, drawable.get_pixel() is approximately 6,5 times faster than pdb.gimp_color_picker, thanks for pointing me to that. the script looks like this now: Code: import time results as to speed with samples of 10, 5 and 1 pixels for a 1024x1024 image with 5 objects: ➤> objects_to_layers(img) time taken: 2.11100006104 seconds. ➤> objects_to_layers(img, 5) time taken: 7.57000017166 seconds. ➤> objects_to_layers(img, 1) time taken: 181.577000141 seconds. Also your script "Layer > Extract Objects > Extract objects to layers..." gives these results with holes as objects: My script result: I thought for a while that gimp crashed with samples of 1 pixels, that's how long it took. I read that python's array module will get even faster results in Akkana Peck's blog: http://shallowsky.com/blog/gimp/pygimp-pixel-ops.html How do I implement that into my script? RE: Searching for python script islands to layers - Ofnuts - 01-23-2018 What Akkana is mentioning is the "pixel region" thing I alluded to in post #9 of this thread. Not sure it helps you here because it is just a raw interface to the layer data, which is *copied* to the Python variable, so if you use Gimp calls to update the layer, you may have to extract it again, or update the array all by yourself, so the final result may not be that much faster. PS; Post you test image, so that I can try my fixes RE: Searching for python script islands to layers - mich_lloid - 01-23-2018 (01-23-2018, 03:17 PM)Ofnuts Wrote: What Akkana is mentioning is the "pixel region" thing I alluded to in post #9 of this thread. Not sure it helps you here because it is just a raw interface to the layer data, which is *copied* to the Python variable, so if you use Gimp calls to update the layer, you may have to extract it again, or update the array all by yourself, so the final result may not be that much faster. You can reproduce my image very easily, I just made 5 doodles, four in each corner and one in the middle with a brush on a transparent image as you see them in my previous post, just make sure you make objects with holes in them to see what I mean with your script that they (the holes) are counted as objects. I think the speed bottleneck is the 2 standard for loops and the get_pixel(), I'll have to study that some more RE: Searching for python script islands to layers - Ofnuts - 01-23-2018 Updated the script on SourceForge. Actually just needed a single call to gimp_histogram(). RE: Searching for python script islands to layers - mich_lloid - 01-23-2018 Ok, so I've been looking at sample scripts of jfmdev at "http://registry.gimp.org/node/28124" very insteresting are scripts "test-discolour-layer-v3.py" which loops over pixels with arrays and "test-discolour-layer-v4.py" which loops over pixels with tiles. Looping over pixels with array module: Code: import time looping over pixels with tiles: Code: import time Wow, 0.21 seconds, looping over pixels with tiles is definitely the way to go. Ok, so now my questions are: 1) How do I translate a tile's pixel position to it's layer's global pixel position so I can select it with "pdb.gimp_fuzzy_select(img.active_layer, <x_position_of_pixel>, <y_position_of_pixel>, 254.9 , 2,0,0, 0,0)" ? 2) How do I exit the loop, update the layer by clearing selection, update layer, and resume the loop from last tile? f.e. I want to accomplishthese steps for a 1024x1024 image with 16x16 tiles: -I find a non-transparent pixel at tile(3,4) -I exit the tile loop -select that pixel and neighboring non-transparent pixels with 'pdb.gimp_fuzzy_select' -do some stuff -update the layer -and then resume tile loop at tile(3,4) until tile(16,16). -script hopefully ends succesfully. RE: Searching for python script islands to layers - Ofnuts - 01-24-2018 You are jumping to conclusions. The problem isn't accessing the region, it is looping... and you don't really need to copy to an array you can loop of the region directly (but it is only marginally faster). Looping on tiles is fast, if you don't need to reload the tiles. Tiles are to Gimp what RAM pages are to your system. If your algorithm can use a tile, put it back, and never need to come back to it, it's fast. If you load tiles at random, performance will degrade. 1) How do I translate a tile's pixel position to it's layer's global pixel position so I can select it with "pdb.gimp_fuzzy_select(img.active_layer, <x_position_of_pixel>, <y_position_of_pixel>, 254.9 , 2,0,0, 0,0)" ? Just add the "layer.offsets" to the layer-relative X and Y position. 2) How do I exit the loop, update the layer by clearing selection, update layer, and resume the loop from last tile? f.e. I want to accomplishthese steps for a 1024x1024 image with 16x16 tiles: -I find a non-transparent pixel at tile(3,4) -I exit the tile loop -select that pixel and neighboring non-transparent pixels with 'pdb.gimp_fuzzy_select' -do some stuff -update the layer -and then resume tile loop at tile(3,4) until tile(16,16). -script hopefully ends succesfully. Why do you need to exit the tile loop? Just reload the tile when you are done with "some stuff/update the layer" RE: Searching for python script islands to layers - mich_lloid - 01-24-2018 Thanks Ofnuts! Wow, looping over tiles is ridiculously faster than standard looping with python, 5 seconds versus 3 minutes with a 1024x1024 image with 5 objects sampling every pixel. The script now looks like this, any suggestions to make script better would be really welcome: Code: import time I tested with a large 4096 x 4096 image with 194 objects on them, took 24 seconds to get them to seperate layers, I won't test with old script, will probably take at least 10 minutes... I tried to update tiles directly with active layer in image, but the tiles wouldn't update, that's why i used a temp_layer copy of active_image. Can you tell me why this is or what I probably did wrong? |