Monday, December 31, 2012

Download YouTube video and convert it for Android

For downloading videos from YouTube I am using YouTubeDownloader2 and you can find it here http://sourceforge.net/projects/ytd2/. Why I am using that and not using Firefox add-ons? YouTubeDownloader2 is standalone program written in Java which is not storing my browsing habits in some remote DB. How do I know that? That is OSS, downloaded code, checked what it does, compiled it. If you don’t do Java, trust others who do ;-)
Once video is on file system we can encode it. It should be easy on Linux unless you are have common repo FFmpeg which is compiled without support for H.264, mp3 and few others codecs. If you are experienced Linux user you will visit FFmpeg wiki where is detailed instruction https://ffmpeg.org/trac/ffmpeg/wiki/UbuntuCompilationGuide how to configure and build FFmpeg. I am on Mint so that is valid set of instructions for me, people using other distro will look for their set of instructions. If you are not experienced user maybe mencoder which comes by default with everything enabled is better option. So, install libavcodec-extra-53 or maybe 54 and mencoder. We can ask mencoder what is supported if in terminal we execute:

~ $ mencoder -ovc help
MEncoder svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team

Available codecs:
copy     - frame copy, without re-encoding. Doesn't work with filters.
frameno  - special audio-only file for 3-pass encoding, see DOCS.
raw      - uncompressed video. Use fourcc option to set format explicitly.
nuv      - nuppel video
lavc     - libavcodec codecs - best quality!
xvid     - XviD encoding
x264     - H.264 encoding


and it produces video codecs list. For audio, query looks like this:

~ $ mencoder -oac help
MEncoder svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team

Available codecs:
   copy     - frame copy, without re-encoding (useful for AC3)
   pcm      - uncompressed PCM audio
   mp3lame  - cbr/abr/vbr MP3 using libmp3lame
   lavc     - FFmpeg audio encoder (MP2, AC3, ...)
   faac     - FAAC AAC audio encoder


There is small problem with mencoder, there is no WinFF for it and one have to do quite a bit of reading to assemble proper set of parameters. To save you from learning, here is what I do:

~ $ mencoder -of lavf -lavfopts format=mp4 -oac lavc -ovc lavc -lavcopts vbitrate=480:aglobal=1:vglobal=1:acodec=libfaac:abitrate=64:vcodec=mpeg4:keyint=25 -ofps 15 -af lavcresample=44100 -vf harddup,scale=480:320 -mc 0 "/home/yourlogin/in.flv" -o "/home/yourlogin/out.mp4"

I want H.263 video and AAC audio in MP4 container. Video should have bitrate up to 480kb/s and must be resized to 480x320 pixels, also frame rate is 15 frames per second.  For audio requested was resampling at 44.1 KHz and bit rate up to 64kb/s. It is not requirement that input video must be FLV, it should work for any container which you can find at YouTube. If your screen is different from 480x320, you may want to resize video differently. For example for 320x240 screen, vbitrate=256 and scale=320:240 should be good choice.
Not so nice as WinFF but not very complicated either.

Saturday, December 15, 2012

How to stack images using G’MIC

After chat on Astophotography Google+ community https://plus.google.com/u/0/communities/118208937662082340807 I concluded that it may be enough interest for 16 bit image processing using G’MIC tutorial and here it is.
G'MIC stands for GREYC's Magic Image Converter and we know it as plugin for GIMP. It is less known that G'MIC framework can be used on it’s own through simple shell scripting or possible C++ or web interface. What is very important it supports 16 bits integers per channel and that is something what GIMP is lacking.
So, what we are going to do here is to take a look at G’MIC tutorial http://gmic.sourceforge.net/tutorial.shtml and load images into stack average them and save them as 16 bit TIFF.
Tutorial says if you are using G’MIC as GIMP plugin and set logging to verbose it will print what it does.

I prefer writing output to log file to suggested running GIMP from terminal (command line for Windows users). Standard path and name for log file is /tmp/gmic_log
Also from tutorial we see that 16 bit processing starts with division with 256 and ends with multiplication with 256. While that represents reduction to 8 bit it is important to note that G’MIC internally works with floating point numbers and there is no loss of precision when we convert it back to 16 bit integers. Once when we are done with processing it is important how we are going to specify TIFF output. G’MIC will pick format from extension but it by default writes 32 bit TIFF. So, to get 8 bit TIFF we need to specify output type uchar and to get 16 bit TIFF we need to specify output type ushort.
Typical operations which we are going to use are:
  1.     -gimp_haar_smoothing 0.1,10,2,0,0 what is Smooth [wavelets] under Enhancements
  2.     -gimp_compose_average 1,0 what is Blend [average]  under Layers
  3.     -gimp_compose_screen 1,0 what is Blend [screen] under Layers
So complete workflow is we pick nicer RAWs export them as 16 bit PPMs using darktable as in http://grumpyoldprogrammer.blogspot.com/2012/11/more-about-stacking.html then we align them using align_image_stack from hugin-tools as in http://grumpyoldprogrammer.blogspot.com/2012/12/how-to-align-image-stack.html and finally we process them with G’MIC.
Averaging layers will produce at the end two layers, if we want we can save them as separate pictures, like this:

$ gmic tif0000.tif tif0001.tif tif0002.tif tif0003.tif -div 256 -gimp_compose_average 1,0 -mul 256 -c 0,65536 -type ushort -output[1] imageA.tiff -output[0] imageB.tiff

or we can stack those two layers in screen mode to boost light and stretch contrast, like this:

$ gmic tif0000.tif tif0001.tif tif0002.tif tif0003.tif -div 256 -gimp_compose_average 1,0 -gimp_compose_screen 1,0 -mul 256 -c 0,65536 -type ushort -output imageS.tiff

If we want to do resizing we can as in G’MIC tutorial use -resize2dx 1600,5 what is bi-cubic resizing to 1600 pixels width.
Instead of averaging we can try other options like -compose_median what is median or any other available filter or combination of filters, we try in GIMP, set logging to verbose and later run it in terminal without loss of data.

Monday, December 10, 2012

How to align image stack

Aligning images in GIMP is not very difficult if we do not have rotation to attend to, if rotation is present we rather leave that task to computer.
Aligning stack of images is not only used in astrophotography, it is common task in creation of HDR images. So, we can use align_image_stack from hugin-tools to align images. Installation procedure on Mint or Ubuntu is simple, we find it:

$ apt-cache search hugin
enblend - image blending tool
enfuse - image exposure blending tool
hugin - panorama photo stitcher - GUI tools
hugin-data - panorama photo stitcher - common data files
hugin-tools - panorama photo stitcher - commandline tools


and after that we install it:

$ sudo apt-get install hugin

It is available from repositories and there is no need to compile it from source. People using different operating system from Linux should visit Hugin website http://hugin.sourceforge.net/download/ and download installer for their operating system.
Once Hugin is installed align_image_stack should be available and we can align image stack. If you do not have own images in this tutorial http://grumpyoldprogrammer.blogspot.com/2012/11/even-more-astrophotography.html you will find download links.
We place in some empty directory JPEGs, if you have RAWs convert them, cd to that directory and execute:

$ align_image_stack -a tif *.JPG

Option -a tif means we want tif indexed output, so after a while we will see tif0000.tif, tif0001.tif and so on. Parameter *.JPG is input list, align all JPEGs. Alternatively we can specify file by file. Once alignment is done we can start GIMP and open all images as layers.



In order to check alignment we can change mode for top layer from Normal to Difference in Layers - Brushes floating window. To check further we make top layer invisible and repeat the same procedure for next layer.



Once we are happy we can stack images as described in previous tutorials or we can use GMI’C plugin. GMI’C is located under Filters and it opens as separate window. We expand Layers, select Average and set Input layers to All and Output mode to New image.



Clicking Apply or OK button will create new image. If you have new version of GIMP Median is also interesting. Average produces two layers and Median only one, we can stack them again. For final processing you may like to do some contrast stretching, maybe some curves as well.

Thursday, December 6, 2012

RESTful web service for picture upload Android client

In previous tutorial http://grumpyoldprogrammer.blogspot.com/2012/11/image-upload-via-restful-web-service.html I described how to create simple server application and deploy it on Tomcat. Now we are going to take a look at client application.
Simplest is to use Apache HttpComponents Client. It is possible to convert HttpMime jar for Android and import it as library. Since not all classes are required for picture upload we can download source and add the following files to project:

AbstractContentBody.java
ByteArrayBody.java
ContentBody.java
ContentDescriptor.java
FormBodyPart.java
Header.java
HttpMultipart.java
HttpMultipartMode.java
MIME.java
MinimalField.java
MultipartEntity.java
StringBody.java


Naturally whole project like this becomes Apache licensed. Some of those Java files are in org.apache.http.entity.mime.content package and others are in org.apache.http.entity.mime.
In this way we avoid compiling two files FileBody.java and InputStreamBody.java
Now will we go refactoring package names to fit them into project is of minor relevance, I usually do.
We create new Android project and we code onCreate like this:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
        bm = BitmapFactory.decodeFile("/sdcard/DCIM/FinalM8.JPG");
        if(bm==null)
            throw new Exception("no picture!");
        new FetchItemsTask().execute();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


Please note that image path is hardcoded, so change it accordingly. Bitmap bm is loaded, defined as field, and if it is different from null we create and execute AsyncTask to upload picture. To keep things simple as possible we will implement only doInBackground, like this:

protected Void doInBackground(Void... arg0) {
    // TODO Auto-generated method stub
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bm.compress(CompressFormat.JPEG, 50, bos);
        byte[] data = bos.toByteArray();
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost postRequest =
            new HttpPost("http://localhost:8080/WebApplication3/xyz/generic/images");
        ByteArrayBody bab = new ByteArrayBody(data, "FinalM8.JPG");
        MultipartEntity reqEntity = new MultipartEntity(
                HttpMultipartMode.BROWSER_COMPATIBLE);
        reqEntity.addPart("image", bab);
        postRequest.setEntity(reqEntity);
        HttpResponse response = httpClient.execute(postRequest);
        System.out.println("Status is "+response.getStatusLine());
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent(), "UTF-8"));
        String sResponse;
        StringBuilder s = new StringBuilder();
        while ((sResponse = reader.readLine()) != null) {
            s = s.append(sResponse);
        }
        System.out.println("Response: " + s);
    } catch (Exception e) {
        // handle exception here
        e.printStackTrace();
    }
    return null;
}


Image is compressed on 50%, loaded into byte array and upload is attempted. In order to run code just push onto emulator some image and change path.