Remove dust with 1000 photos using Gimp and Script-Fu

I Think many photographers would have to clean photos from dust on the sensor. Not having full Photoshop-LightRoom a or-a to quickly process large number of photos very difficult.
But we have Gimp and want to write him a script.
On Habre already there was many articles about the possibility of writing scripts in Gimp.
Here the most detailed review of the language Script-fu and the ability to write on it extension to Gimp
Here article about batch processing.
The idea is that after reading these 2 articles, you can do anything. But that's only if the solution to the title problem, I was faced with many nuances, to overcome which took no little time, and are insufficiently described. Even in the English Tutorial-and Help Ah-Ah. About them and speech will go.


the

Retreat


SLR digital cameras, besides all its virtues endowed with a small disadvantage. Dust on the sensor. To eliminate it, there are many physical adaptations, and in some models even built a special in-house system to off dust with matrices (that's big article about all the technology in this direction).

But in real life there are situations when you go on vacation without taking any "swaroski" for sensor cleaning, and even a pear for blowing dust. Well, shot or 1000 shots, and only at home when parsing noticed a huge speck of dust on all pictures and eye-catching.

In this case, most experts use Adobe Photoshop Light Room or latest edition full Adobe Photoshop.
In LR use rich possibilities for batch processing photos .
Full Photoshop — the possibility of creating Action-s.

But ordinary people generally have neither LightRoom nor Photoshop.
But there is Gimp, the ability to write scripts to it, and a little time and userdstvovali.

the

Writing the script


To do this, open it in Gimp and Script-Fu console


The appearance of the console on the right.

The script is better written in any text editor displaying the connection brackets. I used Notepad++. After writing we will insert the script into the console and check how it works.

To implement the idea will be to use a functional clone which in fact should do what copying in the GUI of the Gimp-a. We enter coordinates of our speck of dust on the pictures and to specify the scope from where to clone the site to this speck of dust close.

To test the idea, I did not just write "feature" according to the rules as described here.
For starters, I found the functionality in the procedure browser.

And began to select options.
Then began the most interesting and not documented. The devil is in the details.
As you can see from the description of the function the input it served 7 parameters, the first two of them, it DRAWABLE objects. A little googling you can find examples of scripts that receive these drawabale from the path to the picture

Here is the code
the
( let* 
(
(image (car (gimp-file-load RUN-NONINTERACTIVE "E:/test.png" "E:/test.png")))
(drawable (car (gimp-image-get-active-layer image)))
)
)

The first 2 parameters are (as source and target, we have our picture)
The third parameter displayed in the IMAGE-CLONE, since we want to clone from the same picture and not from any previously created pattern. 4th & 5th too clear — write here the coordinates of our dust.
But the 6th and 7th parameters are not so obvious.

Through trial and error found that this tool works with a brush. And just the 6th and 7th parameters specify the path along which this brush will move. How to ask the right brush will describe below.
the
 (gimp-clone drawable drawable IMAGE-CLONE 50 50 6 #(0 0 10 10 20 30) ) 

6 numbers in the array, but they describe only 3 coordinates. If you need 4 coordinates, we would write 8 and then the array of 8 numbers. and so on.

Now about the brush. Alas, in this version of Gimp (2.8.4) there is a glitch when working with brushes. You cannot select a brush from the already existing and ask her size (this bag). The size will take either a standard or the one that you have in the GUI is now exposed for her.
In this, we will have to do your own brush and set the parameters (which is actually more convenient)

Here's the code opens a test picture, creating a brush and the clone left side of the picture — the right side on a given route (draw a triangle).
the
( let* 
; create variables for get DRAWABLE
(
(image (car (gimp-file-load RUN-NONINTERACTIVE "E:/test.png" "E:/test.png")))
(drawable (car (gimp-image-get-active-layer image)))
)
; create and set brush 
(gimp-brush-new "MyBrush")
(gimp-brush-set-radius "MyBrush" 4)
(gimp-brush-set-shape "MyBrush" BRUSH-GENERATED-CIRCLE)
(gimp-brush-set-hardness "MyBrush" 0.50)
(gimp-brush-set-spacing "MyBrush" 0)
(gimp-brush-set-spikes "MyBrush" 0)
(gimp-brushes-set-brush "MyBrush")
; clones
(gimp-clone drawable drawable IMAGE-CLONE 100 10 8 #(450 10 360 150 540 150 450 10) )
; save result
(gimp-file-save RUN-NONINTERACTIVE image drawable "E:/test_e.png" "E:/test_e.png")
(gimp-image-delete image)
)

Copy the script into the console and press Enter. If all went well — see the following

In the case of error — see the error description.

But the pictures of the script and after.

With the brush settings you can play at your own discretion.

the

Apply the result to thousands of files


Using the code from the above-described article, write a function that will apply to the folder it will use cloning to each photo, and save the result to a new file in a new folder.
The path to the folders (input and output), a point which will close (i.e., our speck of dust) and its size will pass a parameter. Clone going from the field to the right of the motes.

Receive a script
the
(define (script-fu-batch-dust-remove inputFolder outputFolder dustX dustY dustRadius)
(let* ((filelist (cadr (file-glob (string-append inputFolder DIR-SEPARATOR "*") 1))))
; create and set brush 
(gimp-brush-new "DustBrush")
(gimp-brush-set-radius "DustBrush" dustRadius)
(gimp-brush-set-shape "DustBrush" BRUSH-GENERATED-CIRCLE)
(gimp-brush-set-hardness "DustBrush" 0.70)
(gimp-brush-set-spacing "DustBrush" 0)
(gimp-brush-set-spikes "DustBrush" 0)
(gimp-brushes-set-brush "DustBrush")
go throw all files in inputFolder
(while (not (null? filelist))
(let* ((filename (car filelist))
(image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
(drawable (car (gimp-image-get-active-layer image)))
(dustCoordinates (vector dustX dustY))
)
; clone
(gimp-clone drawable drawable IMAGE-CLONE (+ dustX (* dustRadius 2)) dustY 2 dustCoordinates)
; save result to outputFolder
(set! filename (string-append outputFolder DIR-SEPARATOR (car (gimp-image-get-name image))))
(gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
(gimp-image-delete image)
)
(set! filelist (cdr filelist))
)
; remove the just created Brush for brush not spam list
(gimp-brush-delete "DustBrush")
)
)

Insert it into the console. We now have in the console is the function script-fu-batch-dust-remove
Now open our photos with dust, we find with the selection brush size dust particles (hovering the mouse on a speck of dust and so picking up the brush size to cover the speck of dust). To the left from the bottom are written the coordinates of our cursor on the pictures.
Write down the coordinates and radius
Copy all the files that we want to fix in the folder. Copy everything not worth it, I copied only those where the dust is evident, i.e. for example on the background of clear sky or sea or other homogeneous texture. If you copy everything — even those where dust is not visible because of the heterogeneity of images in this place will spoil these pictures don't need cloning.

Run the script in the console
the
(script-fu-batch-dust-remove "E:/toEdit/in" "E:/toEdit/out" 3186 682 15)

And in the folder E:/toEdit/out get all files with the same names — but without the dust!
The result is achieved.

PS
After a series of experiments came to the conclusion that it is better to use the function gimp-clone and gimp-heal. Her better results out of zavisimoti from the surrounding dust of the picture. The parameters are exactly the same, only there is no IMAGE-CLONE
the
(gimp-drawable drawable heal (+ dustX2 (* dustRadius2 2)) dustY2 2 dustCoordinates2)


UPD1
Examples of script work with gimp-heal
Successful processing (a diaphragm 22)
To

After


Not entirely successful processing (a diaphragm 11)
To

After (half the window now instead of dust)


The result at the aperture of 7.0
To

After (you can see that a small aura still remained, it would be necessary perhaps to increase the radius for this photo)


In most cases, the result is as in the first or the third picture is good, because dust is much more evident but surrounded by the monotonous background, and on it they are perfectly closed. With the task copes the script — removes conspicuous dust, and for hanging in a web album such treatment enough. If you want something to print in high resolution, photos of course will be to modify individually.

UPD2
In light of the fact that in the script I used to save the results method gimp-file-save output files turn out smaller than the original. Ie it turns out gimp-file-save presses JPEG at a different quality than the source files. If anyone is critical — you can read in the procedure browser about file-jpeg-save and use it instead offered me a simple solution with gimp-file-save.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Integration of PostgreSQL with MS SQL Server for those who want faster and deeper

Custom database queries in MODx Revolution

Parse URL in Zend Framework 2