Saturday, April 12, 2008

How to capture shots from camera and make mpegs

INTRODCTION
Despite the technology looks good, the interoperability (connecting gadgets to PC) sucks. I've tried a high quality canon photo camera, which could make over 1000 shots offline, connected over USB and using custom drivers it has it battaries discharged immediately, instead of expected charging the batteries from USB. Why don't they make a standard still image device class and enable standard applications instead of writing custom shit drivers and applications for all the platfroms and all the vendor?

Now, I have switched to a panasonic camera. It can record both video and make high quality shots and also work as a web cam. Surprisingly, it exposes standard audio-video interfaces to the host so that standard SW can be used to work with it. The only problem is that web cam quality is poor 320 x 200 and shot capturing to personal computer is disabled! What I mean by limited interoperability is possession of expensive facility which can be used in no more than corporation-prescribed way. So, for instance, if you have an apple-gathering machine, which can also gather all the other fruits, you are not allowed to gather the other fruits.

Another problem I've experienced is to make a series of shots from a camera, which can be sideshow-reviewed. I have photographed the cloud-formation. Exposing fast cars is also a fun. Here is the solution.

SOLUTION
Microsoft provides Timershot Powertoy, which captures a jpeg at specified interval. The jpeg is gived a constant nacme. To derive a sequence of files, I have written a short C# program:

using System.IO;

class RenameSerializer {
 
 static void log(string msg) {System.Console.Write(msg);}
 
 public static void Main(string[] args) {
  
  if (args.Length == 0) {
   log("Supply the file name to watch");
   return;
  }
  
  string file = args[0];
  int n = 1;
  
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Created += delegate(object source, FileSystemEventArgs e) {
   string serialName = Path.GetFileNameWithoutExtension (file) + (n++) + Path.GetExtension(file);
   if (File.Exists(serialName))    
    File.Delete(serialName);
   File.Move(file, serialName); // rename
  };
  
  watcher.Filter = file;
  watcher.NotifyFilter = NotifyFilters.FileName;
  watcher.IncludeSubdirectories = false;
  watcher.Error += delegate (object sender, ErrorEventArgs e) {
   log("ERROR! The FileSystemWatcher has detected an error." + (e.GetException().GetType() == typeof(InternalBufferOverflowException) ?
    " The file system watcher experienced an internal buffer overflow: " + e.GetException().Message : ""));
        };

//  reportWatcher.Path = BagPrinter.baseDir;
  watcher.Path = ".";
   watcher.EnableRaisingEvents = true;
   log("Press any key to stop");
   System.Console.ReadLine();
 }
}


Save it into a file "ReportWatcher.cs" and compile: csc ReportWatcher.cs. Launch the derived exe in the directory Timershot produces its JPEG and supplying the JPEG's name. The newly created file.jpg will be renamed to file.jpg

The last step is to combine the jpegs into avi can be done by jpegtoavi linux program:

  ls *.jpg | jpegtoavi -f 25 800 600 > mjpeg.avi 

The command will create mjpeg.avi sampled at 25 fps composed of all the current directory jpegs of size 800 x 600 (size is specified in Timershot).

No comments: