Sunday, May 2. 2010
Besides the fact that it was a pain to find out how ImageMagick’s -average option is to be used, it turned out to operate wrongly. The switch calculates the mean of an image sequence, i.e. the mean color values for every pixel. Say, if you have a bunch of images with file names like img*.jpg and want the average saved into avg.jpg, the command line is:
$ convert img*jpg -average avg.jpg
Pretty intuitive. The problem is that you define the mean image Ī[n] of n images I[k] as
while ImageMagick does it recursively as
(with Ĩ[1]=I[1]),
giving you wrong weights 1⁄2n−k+1 like e.g. for n=8
instead of the intended weights 1⁄n like
.
This misbehaviour can be proven e.g. by taking this sequence of a plain blue, green and red image:
and averaging it with the above command. The result is too reddish:
The solution I found was to call convert recursively like this:
#!/bin/bash
i=0 for file in img*jpg; do echo -n "$file.. " if [ $i -eq 0 ]; then cp $file avg.jpg else convert $file avg.jpg -fx "(u+$i*v)/$[$i+1]" avg.jpg fi i=$[$i+1] done
By this, the average of the above example images correctly becomes gray:
There might be similar problems with the other image sequence operators, but I haven’t examined them. Maybe I should file a bug.
Monday, August 25. 2008
The usenet originally only consisted of text messages, but it soon became a way of exchanging binary files as well. As posts are usually restricted to only a few MB, larger archives have to be split up into several parts, each attached to its own newsgroup posting. But if some parts of these posts aren’t transferred correctly to other usenet hosts, the archive parts are broken. Not necessarily if the poster created PAR2 archives in addition to the actual data archive parts. In a RAID-like manner, parity information is placed redundantly into the additional files. Thus, it is possible to recover the complete archive if some parts of it are incomplete. As I downloaded some image archives (No, they were not p’rn) containing pictures in the PCD format that encapsulates six different resolutions of an image, I also had to find out how to explicitly extract the large (3072×2048) resolution out of it. All in all, I created the following (simple) script that - checks the PAR2 files, and if some of the data archive parts are incomplete, it
- tries to recover them, and
- if check (or recovery) were successful, the PCD images are extracted and converted to JPEG.
I did it this way: #!/bin/bash # Verify, includes *PAR2 automatically par2 v *par2 ret=$? if [ $ret -eq 0 ]; then # Extract unrar x *part01.rar cd “$(find -type d | tail -n 1)” # Convert for file in *PCD; do echo -n “$file ” convert $file[5] $(basename $file .PCD).jpg && rm $file done echo Done. elif [ $ret -eq 1 ]; then echo “PARITY CHECK FAILED, TRYING TO REPAIR.” sleep 2 # Repair, if needed par2 r *par2 && echo “You may now rerun this script.” else echo “REPAIR NOT POSSIBLE.” fi
Thursday, July 17. 2008
Sometimes I take AVI videos with my Canon PowerShot, and I process some
of them with a video editor and export them as MPEG. However, those
video formats can’t be streamed, and so I like to convert them to FLV
to enable a YouTube-like streaming in web galleries by a flash video
player. For convenience, I wanted to use a context menu entry for Nautilus, where I could right-click on a video file and select “Convert video to FLV”. Luckily, Nautilus supports to execute arbitrary scripts from the context menu if you simply place them into ~/.gnome2/nautilus-scripts/. The only disadvantage is that it doesn’t check the file type in advance, thus also showing the video conversion entry for non-video files. However, you can include that logic into the script itself. The script is a little more complicated, as I didn’t know how to better parse the file names. Probably I should have used Perl. Here is my ~/.gnome2/nautilus-scripts/Convert\ video\ to\ FLV:
#/bin/bash zenity --question --title “Convert video to FLV” --text “Really?” || exit IFS=$’\n’ for file in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS; do ext=$(echo $file | awk ’BEGIN {FS=“.”}; {print $NF}’) filebase=$(basename “$file”) path=$(echo $file | sed -e “s/$filebase//”) filebase=$(basename $filebase .$ext) if file -i “$file” | grep -i video >/dev/null; then ffmpeg -y -i “$file” -ar 22050 -ab 32 -b 564k -f flv -s qvga “$path$filebase.flv” & else zenity --error --title “Not a video” --text “Hey, $filebase.$ext is not a video!” fi done
Monday, February 25. 2008
It’s a really good tip to use the -x flag to debug bash scripts. I had a problem that GDM wasn’t starting anymore after the regular aptitude upgrade. I didn’t find a hint in the log files and had a look at its init-script /etc/init.d/gdm, which appeared quite complex to me: It sources various config files and calls macros that are defined in there. How the heck should I trace the problem down? The best way was to change the initial line to #!/bin/sh -x what starts the debug mode when the script is invoked. Here’s what it does: It prints every single command that is executed line by line in a fully expanded form, no matter if macros were defined or several other shell scripts are invoked from within. The lines are indented by a sequence of plus symbols to represent the invocation depth of the other scripts. By this, I saw that the last calls referred to splashy, a bootsplash package that I had installed for test purposes but never had configured. The solution was to simply remove that package. Another tip: Don’t do experiments on a system that is supposed to work! This also means to not install the complete Debian ‘testing’ version on it. If you need a selected number of some more recent software, upgrade it individually, but keep the basic packages ‘stable’. On the other hand, you wouldn’t learn much if you weren’t forced to fix things once in a while.
Saturday, November 4. 2006
For the usage of a local backup host, I defined the following scenario, which could also be used for a printer server or any other type of host, which shouldn’t run 24/7, but:
- The host should be able to be woken up manually by a special signal on the LAN, i.e., it should be capable of WOL. (This is only a hardware issue)
- If it is woken up, it should run at least for 30 minutes before trying to shutdown again.
- It shouldn’t shut down while certain processes are running, such as a backup, i.e., it should be capable of a shutdown-lock. If the lock is removed, it might shutdown.
- The host shouldn’t shut down as long as a certain client, e.g. a backup client, is (still) up and running (pingable)
- If the criteria above aren’t hurt, the host should finally shut down.
And here’s the shell-script which implements the above. It’s enough to have it run every five minutes. The “echoes” are only interesting for debugging purposes.
Continue reading "Host automatically up and down"
Monday, October 9. 2006
#!/bin/bash
# Number of letters as argument, default 7 if [ “$1” != “” ]; then num=$1 else num=7 fi
generate() { # Take 1 block from /dev/urandom, encode it base64, # remove first two and last status line, purge capital letters and # special characters from output, cut desired length from front # sed with [A-Z] doesn’t work with Suse - typical! password=$(dd if=/dev/urandom count=1 2>/dev/null | uuencode -m - \ | head -n 2 | tail -n 1 | sed -e ’s:[/+A-Z]::g’ | cut -c -$num) }
# Repeat until letters AND digits occur while true; do generate if echo $password | grep [a-z] | grep [0-9]; then break; fi done
Friday, December 16. 2005
I do testing in web development in that way, that the public website is stored in the public_html subdirectory, and the test site is located in develop_html. To see whether there are differences between those two sites, I use the following aliases:
alias changes=’dir=$(pwd|sed -e s:develop:public:); echo diff with $(echo $dir|sed -e s:$HOME:\~:); for file in $(for rcsfile in RCS/.??* RCS/*; do echo $rcsfile|cut -d, -f1; done); do echo “>>> $(basename $file):”; colordiff --no-banner $(basename $file) $dir; done’
That way only files I manage with RCS are checked, and I can do that call from any subdirectory of develop_html.
Tuesday, July 26. 2005
If RCS is used separately from CVS (e.g. for system configuration management), I sometimes want to know whether there are any uncommitted changes pending. Here’s my bash alias to get an overview: alias rcschanges=’for file in $(for rcsfile in RCS/.??* RCS/*; do echo $rcsfile|cut -d, -f1; done); do [ -f “$(basename $file)” ] && rcsdiff $(basename $file); done’ Maybe you want rcsdiff to be an alias for a home-made rcscolordiff, which itself simply calls rcsdiff $@ | colordiff --no-banner.
|