I got four 120 seconds ISO 800 RAW frames. Better option would be to go for 60 seconds ISO 1600 and minimize tracking errors, stacking should eliminate noise anyway. Since pictures are taken under suburban sky, they are overexposed and have ugly orange background color. When we open them in Darktable default white balance preset is camera white balance and that looks like this.
Now we want to eliminate that ugly orange background and we switch from camera white balance to spot white balance.
If images were saved as JPEG, camera white balance would be applied, colors shifted to allow better compression and we won’t be able to do much processing. Before exporting images to TIFF, to export hit Ctrl+e, we will tweak exposure as on picture:
I export them as 16 bit integer per channel TIFF, if you do not know how to manage export settings it is explained in previous blog entries.
Now to do stacking I will open terminal and execute magic formula:
align_image_stack -a tif *.tiff
gmic tif0000.tif tif0001.tif -div 256 -gimp_blend 3,1,0 -mul 256 -c 0,65536 -type ushort -output one.tiff
gmic tif0002.tif tif0003.tif -div 256 -gimp_blend 3,1,0 -mul 256 -c 0,65536 -type ushort -output two.tiff
gmic one.tiff two.tiff -div 256 -gimp_blend 3,1,0 -mul 256 -c 0,65536 -type ushort -output tutorial.tiff
If you compare it with previous blog entries about G’MIC stacking you will see that new version of G’MIC is not completely backward compatible. Some people would maybe like to use DSS instead and that is also OK. Finally we open image in GIMP bump up contrast and LAB color decompose image. We duplicate A and B component, set copy mode to overlay and then merge them down. Do not flatten layers, there should be L, A and B layers. L layer can be slightly stretched or left how it is. When we LAB compose layers back into RGB image we will have nice saturated colors. Now, some people will proceed playing with curves but I will just add background gradient. I am not really using it as intended. I switch from divide to overlay and reduce opacity to 50%. That background gradient is part of astronomy plugin for GIMP by Georg Hennig and 2.8 compatible version is available from here git://gitorious.org/gimp-plugins-ambulance/gimp-plugin-astronomy.git. Building plugin is trivial. Here is result:
Complete damage control was done in Darktable in three straightforward steps and that is why I call it easy. If level of black was lower and and for example exposure was reduced only -0.5EV, we could further increase contrast and get more of that Flame nebula. Though it will be more fiddling in GIMP and may be not so simple as it sounds.
Sunday, March 24, 2013
Thursday, March 21, 2013
Homework: Towers of Hanoi
This puzzle was popularised in Europe by French mathematician Edouard Lucas. There are three poles, 64 disks of different sizes and number of monks trying to move those disks from first to third pole, respecting the following rules:
1) You can move only one disk at the time.
2) You can pick only top disk and place it on top of other disks on different pole.
3) You can place disk only on bigger disk.
When monks finish moving those 64 disks and puzzle is solved, end of the world will come. According to Lucas all that takes place in Vietnam. Now, this puzzle is known in India as Towers of Brahma and there could be other versions of it, for example Chinese, over last seven thousands years they invented many puzzles. One may be under impression that end of the world is near but to solve 64 disk puzzle, 2^64-1 moves are required and that is quite big number 18446744073709551615. Though end of the world may come before puzzle is solved for many other reasons.
Puzzle is quite interesting because it allows to develop simple algorithm. Now we will name poles start, aux and end. With single disk, we take it from start and place on end. With two disks, we take small to aux, big to end and finally smal from aux to end. Now with three disks we already see that we should move top two to aux, big disk to end and after that top two to end. So, moving top two to aux is like previous case, but aux and end are swapping places. Moving top two from aux to end is again the same as previous case, but start and aux are swapping places. We can even write moves, so it is easy to see what is going on:
One disk: start to end
Two disks: start to aux, start to end, aux to end
Three disks: (start to end, start to aux, end to aux), start to end, (aux to start, aux to end, start to end)
We can generalize and say that solution is moving n-1 disks to aux, moving bottom disk to end and moving n-1 disks from aux to end. So we got self algorithm for solving puzzle. Turning it into code is more than simple:
That was Python implementation. If you do not know Python, here is Java implementation:
Very simple. There are many other ways to solve this puzzle but recursion is simplest and most logical. Also excellent interview question, if candidate is not capable of developing simple algorithm and understanding recursion, then candidate is not really programmer.
1) You can move only one disk at the time.
2) You can pick only top disk and place it on top of other disks on different pole.
3) You can place disk only on bigger disk.
When monks finish moving those 64 disks and puzzle is solved, end of the world will come. According to Lucas all that takes place in Vietnam. Now, this puzzle is known in India as Towers of Brahma and there could be other versions of it, for example Chinese, over last seven thousands years they invented many puzzles. One may be under impression that end of the world is near but to solve 64 disk puzzle, 2^64-1 moves are required and that is quite big number 18446744073709551615. Though end of the world may come before puzzle is solved for many other reasons.
Puzzle is quite interesting because it allows to develop simple algorithm. Now we will name poles start, aux and end. With single disk, we take it from start and place on end. With two disks, we take small to aux, big to end and finally smal from aux to end. Now with three disks we already see that we should move top two to aux, big disk to end and after that top two to end. So, moving top two to aux is like previous case, but aux and end are swapping places. Moving top two from aux to end is again the same as previous case, but start and aux are swapping places. We can even write moves, so it is easy to see what is going on:
One disk: start to end
Two disks: start to aux, start to end, aux to end
Three disks: (start to end, start to aux, end to aux), start to end, (aux to start, aux to end, start to end)
We can generalize and say that solution is moving n-1 disks to aux, moving bottom disk to end and moving n-1 disks from aux to end. So we got self algorithm for solving puzzle. Turning it into code is more than simple:
That was Python implementation. If you do not know Python, here is Java implementation:
Very simple. There are many other ways to solve this puzzle but recursion is simplest and most logical. Also excellent interview question, if candidate is not capable of developing simple algorithm and understanding recursion, then candidate is not really programmer.
Saturday, March 16, 2013
Recursion in Python
And now something completely different. During last week I was busy polishing my Python skills or rather removing rust from them. I went through book Think Python: How to Think Like a Computer Scientist by Allen Downey. Mentioned book is available for download from http://www.thinkpython.com. My impression is that book is intended for army of different bookkeepers and alike trying to learn programming. So author is threading rather gently and slowly. It reminds me of joke from Monty Python where accountant, Palin, wants to go directly into taming lions, but career consultant, Cleese won’t let him, he must do that gradually, first investment banking. Now I will be kind and let accountant do lion taming without going first into investment banking.
In one of introductory chapters recursion is introduced and stack transition is explained. For example we can use factorial:
It is easily readable and looks good. If we call it with n=6 this will happen:
6*(5*(4*(3*(2*1))))
CPU pushes on stack value for n and * operation and dispatches call to the same function but with n-1 parameter, when right brace is closed, pops frame from stack and finishes multiplication. Problem with recursion and Python is that depth of stack is rather small, only thousand frames. If you try to calculate factorial for 2^10 using this function it will cause stack overflow. So instead of doing recursive calls one can rewrite factorial and use iterations:
Still simple and shallow stack problems are avoided, but that is so investment banking. What else could be done? We can use binary splitting. Story about binary splitting comes from Xavier Gourdon and Pascal Sebah and you can find it here. Instead of multiplying accumulator with all numbers in range we do recursive preparation similar to binary search and build tree like flow to multiply partial products between themselves. We define product like this:
P(a, b) = P(a, (a+b)/2)*P((a+b)/2, b)
Then we divide each range in half until distance between upper and lower bound is small. Here is the code:
If we say a is 0 we will get factorial b as result. I tested it for b up to 2^16 and it went through without stack overflow as expected. While it theoretically could be used for values up to 2^1000, try not to exceed 2^16 unless your box have really good cooling and plenty of time to wait for result. Tree is not tall, but there is quite few branches. Python is partly functional language and that bring us to yet another idea. Functional languages have compilers which will optimize recursive calls into so called tail calls if function is written in certain way. For example this could be optimized:
But Python compiler is not that much functional and it will not generate tail calls. Through the years people are bothering Guido with tail call optimisations but he just doesn’t want to implement it. When gccpy front-end is released, there will be tail call optimisation since GCC is doing it anyway. Instead of waiting for gccpy we can help ourselves with generators and so called trampolining. We should also switch from factorial to Fibonacci numbers, due to size of result. Plain Fibonacci looks like this:
In order to get generators we will replace return with yield and rewrite function so it ends with single function call:
def fibo(a, b, c):
if c==0:
yield b
else:
yield fibo(a+b, a, c-1)
and one would like to call it like this fibo(1, 0, n). Now we just need trampoline to execute those tail calls and we can calculate first thousand or so Fibonacci numbers:
import types
def trampoline(func, *args, **kwargs):
f = func(*args, **kwargs)
while isinstance(f, types.GeneratorType):
f=f.next()
return f
def fibo(a, b, c):
if c==0:
yield b
else:
yield fibo(a+b, a, c-1)
for x in range(1024):
print "F(", x, ") =", trampoline(fibo, 1, 0, x)
There is user friendly version of trampoline where decorator is used, so no need to replace return with yield and normal function call is used, but is more difficult to understand, you can download it from here.
In one of introductory chapters recursion is introduced and stack transition is explained. For example we can use factorial:
It is easily readable and looks good. If we call it with n=6 this will happen:
6*(5*(4*(3*(2*1))))
CPU pushes on stack value for n and * operation and dispatches call to the same function but with n-1 parameter, when right brace is closed, pops frame from stack and finishes multiplication. Problem with recursion and Python is that depth of stack is rather small, only thousand frames. If you try to calculate factorial for 2^10 using this function it will cause stack overflow. So instead of doing recursive calls one can rewrite factorial and use iterations:
Still simple and shallow stack problems are avoided, but that is so investment banking. What else could be done? We can use binary splitting. Story about binary splitting comes from Xavier Gourdon and Pascal Sebah and you can find it here. Instead of multiplying accumulator with all numbers in range we do recursive preparation similar to binary search and build tree like flow to multiply partial products between themselves. We define product like this:
P(a, b) = P(a, (a+b)/2)*P((a+b)/2, b)
Then we divide each range in half until distance between upper and lower bound is small. Here is the code:
If we say a is 0 we will get factorial b as result. I tested it for b up to 2^16 and it went through without stack overflow as expected. While it theoretically could be used for values up to 2^1000, try not to exceed 2^16 unless your box have really good cooling and plenty of time to wait for result. Tree is not tall, but there is quite few branches. Python is partly functional language and that bring us to yet another idea. Functional languages have compilers which will optimize recursive calls into so called tail calls if function is written in certain way. For example this could be optimized:
But Python compiler is not that much functional and it will not generate tail calls. Through the years people are bothering Guido with tail call optimisations but he just doesn’t want to implement it. When gccpy front-end is released, there will be tail call optimisation since GCC is doing it anyway. Instead of waiting for gccpy we can help ourselves with generators and so called trampolining. We should also switch from factorial to Fibonacci numbers, due to size of result. Plain Fibonacci looks like this:
In order to get generators we will replace return with yield and rewrite function so it ends with single function call:
def fibo(a, b, c):
if c==0:
yield b
else:
yield fibo(a+b, a, c-1)
and one would like to call it like this fibo(1, 0, n). Now we just need trampoline to execute those tail calls and we can calculate first thousand or so Fibonacci numbers:
import types
def trampoline(func, *args, **kwargs):
f = func(*args, **kwargs)
while isinstance(f, types.GeneratorType):
f=f.next()
return f
def fibo(a, b, c):
if c==0:
yield b
else:
yield fibo(a+b, a, c-1)
for x in range(1024):
print "F(", x, ") =", trampoline(fibo, 1, 0, x)
There is user friendly version of trampoline where decorator is used, so no need to replace return with yield and normal function call is used, but is more difficult to understand, you can download it from here.
Tuesday, March 5, 2013
How Java and C or C++ can talk on Linux
Linux is all about interoperability. That is more of IPC stuff. Without any type safety we can open pipe and pass arbitrary chunk of data between native process and Java process. No need for JNI, let the data flow. Secret of our success is function popen(), for more info invoke man popen from terminal. All actions are initiated from native code, so here is declaratively C++ native code to start Java listener and send chunk of data to it:
Without that C++ include statement it would look like plain C. It will create process java SomeOtherClass and open pipe to it for writing. Naturally before we run native part of system we should compile Java code. Here is Java listener:
import java.io.BufferedInputStream;
class SomeOtherClass {
public static void main(String args[]) throws Exception {
BufferedInputStream bis = new BufferedInputStream(System.in, 132);
StringBuffer sb = new StringBuffer();
int i;
while ((i = bis.read()) != -1) {
sb.append((char) i);
}
System.out.println("SomeOtherClass got message : " + sb.toString());
}
}
When we run native binary it will start Java class and send to it message. In its turn Java class will use BufferedInputStream to read standard input and turn stream of integers into String. If we want we can make C++ listening and Java talking. Here is the now really C++ code:
As last time Java code must be compiled prior to executing native one. Here is Java code:
public class SomeClass {
public static void main(String[] args) {
String msg = "Greetings from Java no: ";
for (int i = 0; i < 10; i++) {
System.out.println(msg + i);
}
}
}
We have less code but more output, obvious rise in productivity due to OO approach.
Not very useful, but things could be done this way.
I was greeted with error message:
invalid conversion from ‘int’ to ‘const char*’
C FILE* was expelled from ISO/ANSI C++ streams. Luckily there is workaround, one can subclass std::streambuf as described here. Sometimes one can find useful things on StackOverflow ;-)
Without that C++ include statement it would look like plain C. It will create process java SomeOtherClass and open pipe to it for writing. Naturally before we run native part of system we should compile Java code. Here is Java listener:
import java.io.BufferedInputStream;
class SomeOtherClass {
public static void main(String args[]) throws Exception {
BufferedInputStream bis = new BufferedInputStream(System.in, 132);
StringBuffer sb = new StringBuffer();
int i;
while ((i = bis.read()) != -1) {
sb.append((char) i);
}
System.out.println("SomeOtherClass got message : " + sb.toString());
}
}
When we run native binary it will start Java class and send to it message. In its turn Java class will use BufferedInputStream to read standard input and turn stream of integers into String. If we want we can make C++ listening and Java talking. Here is the now really C++ code:
As last time Java code must be compiled prior to executing native one. Here is Java code:
public class SomeClass {
public static void main(String[] args) {
String msg = "Greetings from Java no: ";
for (int i = 0; i < 10; i++) {
System.out.println(msg + i);
}
}
}
We have less code but more output, obvious rise in productivity due to OO approach.
Not very useful, but things could be done this way.
Nostalgic moments
While trying to do:I was greeted with error message:
invalid conversion from ‘int’ to ‘const char*’
C FILE* was expelled from ISO/ANSI C++ streams. Luckily there is workaround, one can subclass std::streambuf as described here. Sometimes one can find useful things on StackOverflow ;-)
Monday, March 4, 2013
Pipes and even more interesting Named Pipes
Pipes are very user friendly form of IPC on Linux. We are frequently using them in terminal, for example on Debian:
$ dpkg -l | grep gimp
We want to see only installed packages which are containing gimp in its name. Easy way to get pipe is to declare integer array and fork. Since child process gets all variables from parent it gets pipe as well.
Naturally such client server code is clumsy to write and creators of UNIX invented named pipes. Those are nothing but files and we can create them from terminal using mknod command and p switch, we want FIFO - first in first out storage:
$ mknod TESTFIFO p
Now if we do ls -l on our FIFO we will see that it got different color from other files and additional markings, letter p:
prw-r--r-- 1 borg borg 0 Mar 4 22:28 TESTFIFO
You do not have to be programmer to create FIFO. One can go even further and open two terminals, in the first execute cat > TESTFIFO and in the second one cat TESTFIFO, now everything what you write in the first one will appear in the second one, after you hit enter.
After all that fun we may go back to programming and create simple client and server which will use FIFO to talk. Client code:
Then server code:
Whoever starts first will be blocked until other side of pipe is open. When server exits, client exits as well. Very simple and user friendly.
Those examples are very much influenced by Linux Programmer's Guide by Scott Burkett and Beej's Guide to Unix IPC. The second one is quite entertaining and you can find it here with few other books and tutorials.
Next couple of posts will be about Java and pipes and Android and pipes and finally about NDK and pipes.
$ dpkg -l | grep gimp
We want to see only installed packages which are containing gimp in its name. Easy way to get pipe is to declare integer array and fork. Since child process gets all variables from parent it gets pipe as well.
Naturally such client server code is clumsy to write and creators of UNIX invented named pipes. Those are nothing but files and we can create them from terminal using mknod command and p switch, we want FIFO - first in first out storage:
$ mknod TESTFIFO p
Now if we do ls -l on our FIFO we will see that it got different color from other files and additional markings, letter p:
prw-r--r-- 1 borg borg 0 Mar 4 22:28 TESTFIFO
You do not have to be programmer to create FIFO. One can go even further and open two terminals, in the first execute cat > TESTFIFO and in the second one cat TESTFIFO, now everything what you write in the first one will appear in the second one, after you hit enter.
After all that fun we may go back to programming and create simple client and server which will use FIFO to talk. Client code:
Then server code:
Whoever starts first will be blocked until other side of pipe is open. When server exits, client exits as well. Very simple and user friendly.
Those examples are very much influenced by Linux Programmer's Guide by Scott Burkett and Beej's Guide to Unix IPC. The second one is quite entertaining and you can find it here with few other books and tutorials.
Next couple of posts will be about Java and pipes and Android and pipes and finally about NDK and pipes.
Subscribe to:
Posts (Atom)