Hello everybody, my name is Emanuele Zattin and i'm developing a plug-in implementing a texture synthesis algorithm described in a paper ("Texture Synthesis by Non-parametric sampling" by Efros and Leung). Here attached you can see my actual implementation which works on grayscale images. It is anyway VERY slow, which was anyway predictable judging from the complexity of the algorithm. I was wondering if translating it to C would make it much faster or if there are some more speedup techniques i'm just missing. Thank you very much!! Emanuele Zattin
#!/usr/bin/python import math from gimpfu import * from Numeric import * def getpixel(drawable, x, y): tile = drawable.get_tile2(FALSE, x, y) x_offset = x % 64 y_offset = y % 64 pixel = tile[x_offset, y_offset] values = [] for i in range(len(pixel)): values.append(ord(pixel[i])) if len(values) == 1: values.append(255) return values def putpixel(drawable, x, y, value): tile = drawable.get_tile2(FALSE, x, y) x_offset = x % 64 y_offset = y % 64 tile[x_offset, y_offset] = chr(value) + chr(255) return def texture_synthesis(image, drawable, w): # first let's retrieve some useful stats about the current layer layer = image.active_layer height = layer.height width = layer.width gimp.tile_cache_ntiles(2 * (width + 63) / 64) # where are the transparent pixels? gimp.progress_init("Gathering stats...") transparent = [] for i in range(width): for j in range(height): pixel = getpixel(layer, i, j) if pixel[1] < 255: transparent.append([i, j]) gimp.progress_update(float(i-w)/(width-1-2*w)) if len(transparent) == 0: return while len(transparent) > 0: # which is the next pixel to synthetize? neighbours = [] for index in range(len(transparent)): count = 0 pixel_pos = transparent[index] for x in range(max(0, pixel_pos[0]-w), min(width, pixel_pos[0]+w)): for y in range(max(0, pixel_pos[1]-w), min(height, pixel_pos[1]+w)): pixel = getpixel(layer, x, y) if pixel[1] == 255: count = count + 1 neighbours.append(count) trans_index = neighbours.index(max(neighbours)) next_pixel_pos = transparent[trans_index] # create the pattern around that pixel pattern = arrayrange((4*w*w+4*w+1)) pattern.shape = (2*w+1, 2*w+1) for i in range(2*w+1): for j in range(2*w+1): # where's the pixel we're gonna check? px = next_pixel_pos[0]+i-w py = next_pixel_pos[1]+j-w # is it in the image? if px<0 or px>=width or py<0 or py>=height: pixel = [-1, 0] else: pixel = getpixel(layer, px, py) if pixel[1] == 255: pattern[i,j] = pixel[0] else: if pixel[0] == -1: pattern[i,j] = -1 else: pattern[i,j] = 0 # let's find the closest matches max_result = 0 values = [] positions = [] gimp.progress_init("Computing pixel: " + str(len(transparent)) + " more to go") for i in range(width): for j in range(height): result = 0 dist = pow((next_pixel_pos[0]-i),2) + pow((next_pixel_pos[1]-j),2) if dist > 0: for x in range(2*w+1): for y in range(2*w+1): px = i+x-w py = j+y-w if px>=0 and px<width and py>=0 and py<height: pixel = getpixel(layer, px, py) if pixel[1] == 255 and pattern[x,y] >=0: result = result + 255-abs(pixel[0]-pattern[x, y]) if result > max_result: print "Matching: " + str(float(result)/(255*((2*w+1)*(2*w+1)))) +" ("+ str(i) +","+ str(j) + ")" max_result = result pixel = getpixel(layer, i, j) values = [] values.append(pixel[0]) positions = [] positions.append([i, j]) elif result == max_result: pixel = getpixel(layer, i, j) values.append(pixel[0]) positions.append([i, j]) gimp.progress_update(float(i)/(width-1)) distances = [] for i in positions: distances.append(pow((next_pixel_pos[0]-i[0]),2) + pow((next_pixel_pos[1]-i[1]),2)) min_distance_index = distances.index(min(distances)) min_distance_value = values[min_distance_index] putpixel(layer, next_pixel_pos[0], next_pixel_pos[1], min_distance_value) layer.update(next_pixel_pos[0], next_pixel_pos[1], 1, 1) transparent[trans_index:trans_index+1] = [] register( "TextureSynthesis", "Synthetize transparent pixels of the current layer", "Synthetize transparent pixels of the current layer", "Ling Xu, Emanuele Zattin", "Ling Xu, Emanuele Zattin", "2006", "<Image>/Python-Fu/Texture/Synthesis", "GRAY*", [ (PF_INT, "w", "Window Size", 9) ], [], texture_synthesis) main()
_______________________________________________ Gimp-developer mailing list Gimp-developer@xxxxxxxxxxxxxxxxxxxxxx https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer