[Gimp-developer] McCann Retinex plugin with python
Yesterday I decided to implement the retinex algorithm described by John McCann in 1999 as a gimp plugin. I am using Python (in particular numpy for the main calculations) and consequently chose to put in some modifications to the algorithm to make it more efficient, but it makes generally the same effect as that described in Brian Funt, Florian Ciurea, and John McCann Retinex in Matlab, Proceedings of the IST/SID Eighth Color Imaging Conference: Color Science, Systems and Applications, 2000, pp 112-121. http://www.cs.sfu.ca/~colour/publications/IST-2000/index.html As this is my first foray into gimp plugging in, I'd appreciate if someone could look over the code. Is there a more efficient way of getting out one colour channel of the image at a time? At the moment I read in the whole image which takes a lot of memory. Searching the archives today I notice that Pedro Paf was suggesting implementing it as a Summer of Code project - as the algorithm is very simple (a day to make even starting no numpy or Gimp python knowledge), what enhancements where being contemplated? #! /usr/bin/env python # Implementation of a retinex algorithm similar to that described by # John McCann in 1999 # For more information about the algorithm see http://www.cs.sfu.ca/~colour/publications/IST-2000/index.html # Brian Funt, Florian Ciurea, and John McCann Retinex in Matlab, Proceedings of the IST/SID Eighth Color Imaging Conference: Color Science, Systems and Applications, 2000, pp 112-121. # Copyright (C) 2007 John Fremlin # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import gimp from gimpfu import * import numpy import scipy import scipy.ndimage import struct import Image gettext.install(gimp20-python, gimp.locale_directory, unicode=True) small_amount = 1/1024.0 difference_from_neighbours_kernel = numpy.array([ [-1, -1, -1], [-1,8,-1], [-1,-1,-1]],d) global_logscale = True def shrink(chan,scale): return scipy.ndimage.zoom(chan,1/float(scale),prefilter=False,order=5) def image_clip(chan): if global_logscale: return chan.clip(-numpy.inf,0.0) else: return chan.clip(0.0,1.0) def retinex_at_scale(retinex,orig,scale): assert(orig.size == retinex.size) working = orig diff = scipy.ndimage.convolve(working,difference_from_neighbours_kernel) result = (retinex + diff)/2 working = (retinex + image_clip(result))/2 return working def resize(chan,new_size): orig = chan.shape zoom = [((new+0.9)/float(old)) for old, new in zip(orig, new_size)] ret = scipy.ndimage.zoom(chan,zoom,prefilter=False,order=5) assert(new_size == ret.shape) return ret def process_one_channel(chan): retinex = numpy.array([[chan.mean()]],d) for logscale in range(int(numpy.log2(min(*chan.shape))),-1,-1): scale = 1 logscale orig = shrink(chan,scale) retinex = retinex_at_scale(resize(retinex,orig.shape),orig,scale) return retinex #return numpy.abs(chan-retinex) def retinex(image): if global_logscale: image = numpy.log(image+small_amount) [ width, height, channels ] = image.shape for c in range(channels): gimp.progress_update(c/channels) image[:,:,c] = process_one_channel(image[:,:,c]) if global_logscale: image = numpy.exp(image)-small_amount return image def progress_update(stage,proportion_done): gimp.progress_update(proportion_done*0.10) def read_in(drawable): width = drawable.width height = drawable.height bpp = drawable.bpp pr = drawable.get_pixel_rgn(0, 0, width, height, False) # image = numpy.zeros((height,width,3),d) # for y in range(height): # for x in range(width): # image[y,x,:] = struct.unpack('BBB',pr[x,y][0:3]) # progress_update(read-in, (y / float(height))) a = numpy.fromstring(pr[:,:],B) assert(a.size == width * height * bpp) image = numpy.array(a.reshape(height,width,bpp),d)[:,:,0:min(bpp,3)] return image/256.0 def write_out(drawable,image): byte_image = numpy.array((image*256).round(0),B) width = drawable.width height = drawable.height bpp = drawable.bpp pr = drawable.get_pixel_rgn(0, 0, width, height, True) assert(byte_image.size == width * height * bpp) pr[:,:] =
Re: [Gimp-developer] McCann Retinex plugin with python
On 9/15/07, John Fremlin [EMAIL PROTECTED] wrote: Yesterday I decided to implement the retinex algorithm described by John McCann in 1999 as a gimp plugin. I am using Python (in particular numpy for the main calculations) and consequently chose to put in some modifications to the algorithm to make it more efficient, but it makes generally the same effect as that described in Brian Funt, Florian Ciurea, and John McCann Retinex in Matlab, Proceedings of the IST/SID Eighth Color Imaging Conference: Color Science, Systems and Applications, 2000, pp 112-121. http://www.cs.sfu.ca/~colour/publications/IST-2000/index.html As this is my first foray into gimp plugging in, I'd appreciate if someone could look over the code. Is there a more efficient way of getting out one colour channel of the image at a time? At the moment I read in the whole image which takes a lot of memory. plug_in_decompose decomposes the image into a layer per channel. Searching the archives today I notice that Pedro Paf was suggesting implementing it as a Summer of Code project - as the algorithm is very simple (a day to make even starting no numpy or Gimp python knowledge), what enhancements where being contemplated? I find this odd -- your whole email odd, in fact, because -- there is already a retinex plugin (found at Colours-Retinex; plug-ins/common/retinex.c in the GIMP source tree.). If you want to add some enhancements, perhaps you could check that out first. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] McCann Retinex plugin with python
David Gowers [EMAIL PROTECTED] writes: [...] plug_in_decompose decomposes the image into a layer per channel. Thanks Searching the archives today I notice that Pedro Paf was suggesting implementing it as a Summer of Code project - as the algorithm is very simple (a day to make even starting no numpy or Gimp python knowledge), what enhancements where being contemplated? I find this odd -- your whole email odd, in fact, because -- there is already a retinex plugin (found at Colours-Retinex; plug-ins/common/retinex.c in the GIMP source tree.). If you want to add some enhancements, perhaps you could check that out first. The retinex plugin is not documented. (As far as I can see?) What do the different parameters to it mean? Even after looking at the paper it is supposedly based on (multsclrtx.ps) I don't understand the parameters. There are many different retinex algorithms based on widely different principles; it is true that this one and the McCann one are similar in some respects. Obviously, I experimented with it a few times, but I couldn't get it to work before I gave up. The objective of my implementation of is to brighten dark areas of the image while preserving detail, and it has a very noticeable effect. Compare the outputs. Probably the best way to use my code is to select the non-flatten option and adjust the opacity of the retinex layer afterwards. ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
[Gimp-developer] Gimp 2.4.0 rc2 access violation in WinXP - what to do?
Hi developers: I have several times received an AV crash when double-clicking on a file to open it. From what I've gathered lurking, this is more likely to be a GTK+ problem than a GIMP problem but with 2.4.0 final presumably just around the corner I thought I shouldn't just ignore it. FWIW the main error (per the drmingw dump) is gimp-2.4.exe caused an Access Violation at location 00675c23 in module gimp-2.4.exe Reading from location . (I have the dump if its any use) I searched for product:GIMP Access Violation in bugzilla and only found one hit : 314529 http://bugzilla.gnome.org/show_bug.cgi?id=314529 filed against 2.2.8 in 2005 and with no activity since 2007-07-25 14:29 UTC. As a non-programming, non-developing lurker should I just ignore this, file it against Gimp (since I can't tell where it really belongs) with as much description as possible, mention it somewhere else ? Regards ... Alec -- buralex-gmail -- ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] Gimp 2.4.0 rc2 access violation in WinXP - what to do?
On 9/15/07, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: I have several times received an AV crash when double-clicking on a file to open it. From what I've gathered lurking, this is more likely to be a GTK+ problem than a GIMP problem but with 2.4.0 final presumably just around the corner I thought I shouldn't just ignore it. This problem has been addressed and fixed in SVN, a new pre-release with this crasher fixed should appear soon. /Øyvind K. -- «The future is already here. It's just not very evenly distributed» -- William Gibson http://pippin.gimp.org/http://ffii.org/ ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer
Re: [Gimp-developer] GIMP Vectors Object Documentation
On 9/12/07, Sven Neumann [EMAIL PROTECTED] wrote: Hi Simon, what about the other issue that Barton reported? Apparently the stroke is being made with the background color though the pdb for gimp-edit-stroke-vectors says: This procedure strokes the specified vectors object, painting along the path with the active brush and foreground color David Gowers wrote: I converted the script to python (useful script, btw -- thanks Simon.), and I cannot reproduce this. Going back and repeating my earlier tests I find that I cannot reproduce the background color issue I reported either. I believe that I have identified the problem however: my installation of 2.3.18 is defaulting to the erase tool at start-up. When I open 2.3.18 and run Simon's draw_circle script (in scheme or python) without first selecting the paintbrush tool from the toolbox the path is stroked with the erase tool. Surely this is the intended behavior, but it wasn't obvious to me that the erase tool is considered a paint brush. Would it be helpful to note this in the pdb blurb, or would that amount to clutter? Long story short, I ran my tests on an image with no alpha channel and a white background color and probably jumped to the incorrect conclusion with regard to the cause of the missing circle. FWIW my adaptation to Python of Simon's script-fu is attached. Thanks all, Barton #!/usr/bin/env python # Draws a 150 px radius circle centered in an 800x600 px image # Adapted from a scheme script-fu contributed by Simon Budig from gimpfu import * def draw_circle(img, layer): gimp.set_foreground(0, 0, 0) pdb.gimp_context_set_brush(Circle (03)) vectors = pdb.gimp_vectors_new(img, circle) pdb.gimp_image_add_vectors(img, vectors, -1) pdb.gimp_vectors_bezier_stroke_new_ellipse(vectors, 400, 300, 150, 150, 0) pdb.gimp_image_set_active_vectors(img, vectors) pdb.gimp_edit_stroke_vectors(layer, vectors) pdb.gimp_displays_flush() register( python-fu-draw-circle, N_(Draw a circle), Simple example of stroking a circular path, Simon Budig, Simon Budig, 2007, N_(_Draw Circle), RGB*, GRAY*, [ (PF_IMAGE, image, Input image, None), (PF_DRAWABLE, drawable, Input drawable, None) ], [], draw_circle, menu=Image/Python-fu ) main() ___ Gimp-developer mailing list Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer