qole's Avatar
Moderator | Posts: 7,109 | Thanked: 8,820 times | Joined on Oct 2007 @ Vancouver, BC, Canada
#31
Ok, so there are three steps for making a nice averaged low-light camera pic. You need mencoder, mplayer, and imagemagick on your tablet.

Step 1: Capture the images with mencoder. You should have a moment to position your camera after pressing "enter" on the following command. Then hold your tablet as still as possible for about 30 secs. The more movement, the blurrier your final pic will be.
Code:
mencoder -cache 512 tv:// -ovc copy -tv driver=v4l2:width=640:height=480:noaudio -fps 15 -oac copy -endpos 0.5 -o /media/mmc1/pics.avi
Step 2: Use mplayer to extract the pictures you just took to JPEG images.
Code:
mplayer /media/mmc1/pics.avi -ov jpeg:quality=100:outdir=/media/mmc1/
Step 3: Use ImageMagick to average the images into a final "clean" image.
Code:
convert -average /media/mmc1/*.jpg /media/mmc1/average.jpg
Since we already have ImageMagick on the tablet, I bet we could clean up the image a lot more (White balance, sharpen, etc) using some techniques from this repository.
 

The Following User Says Thank You to qole For This Useful Post:
qole's Avatar
Moderator | Posts: 7,109 | Thanked: 8,820 times | Joined on Oct 2007 @ Vancouver, BC, Canada
#32
I have posted a set on Flickr with three original frames and the final averaged result. Here is frame 8 (the final frame) and the final averaged result, for comparison. Click on the pics to see the full size.

 

The Following 5 Users Say Thank You to qole For This Useful Post:
Benson's Avatar
Posts: 4,930 | Thanked: 2,272 times | Joined on Oct 2007
#33
Originally Posted by qole View Post
Step 2: Use mplayer to extract the pictures you just took to JPEG images.
Code:
mplayer /media/mmc1/pics.avi -ov jpeg:quality=100:outdir=/media/mmc1/
Dumping them to JPEG is bad; lossy compression before averaging means that during the compression, some information is lost to preserve the most visually significant information; as SNR goes down, you wind up losing more of the signal and keeping more of the noise. You can kill the noise with time-domain low-pass (average, median, etc.) filtering, but you can't do anything about the signal that was lost. Once you have the noise discarded, then lossy compression is OK.

Instead, dump them as PNG (or pnm, to save the CPU time, and make them immediately usable with netpbm) and average them, outputting the result to a JPEG, if you like. Have you found a way to median-filter the images with imagemagick? I looked a little, and didn't see anything, but I'm sure it's possible. If I had mplayer on my tablet, I'd try taking 4 images and running the netpbm pipeline I tried earlier, and imagemagick (or netpbm, a mean's a mean) to mean them, and I'd bet the median/average combo comes out ahead. In fact, with lossless (until finished) and median filtering, I'd not be surprised if it beats 8-image jpeg->mean->jpeg.

Still, very nice stuff as it stands.

Oh, and it occurs to me; can't mplayer directly view the stream? Something like:
Code:
mplayer -cache 512 tv:// -tv driver=v4l2:width=640:height=480:noaudio -fps 15 -endpos 0.5 -ov jpeg:quality=100:outdir=/media/mmc1/
I think that should do what you're doing now with steps 1 and 2, and (using pnm instead of jpeg, at least) might be a hair faster/less cpu intensive/less susceptible to trouble from other processes. But a couple of curious questions:
  • Why 512kB cache? Can it not keep up at 15 fps with no compression? (I assume 512kB is the amount 0.5s of video takes up, or a bit more?)
  • Why 15 fps? Is that the maximum you can get from the camera at 640x480? I was hoping to get about 24/30 fps, so that 4 images would be about 1/8 of a second.
Just curious how you came up with these.
And, a suggestion, using -frames 8 instead of -endpos 0.5, you'd remove the framerate dependence, which makes it easier for you or anyone else to fiddle with mplayer and/or mencoder settings without changing other parts of their script.
 
qole's Avatar
Moderator | Posts: 7,109 | Thanked: 8,820 times | Joined on Oct 2007 @ Vancouver, BC, Canada
#34
Originally Posted by Benson View Post
Dumping them to JPEG is bad; lossy compression before averaging means that during the compression, some information is lost to preserve the most visually significant information; as SNR goes down, you wind up losing more of the signal and keeping more of the noise.
I agree. I'll try to keep all compression out of it until the very end. I was using quality=100 on the jpegs to minimize compression, already.

This seems to work to produce uncompressed .png images (use correct file names and paths of course):

Code:
mplayer pics.avi -vo png:z=0
EDIT: I ran the averaging again with the uncompressed PNGs (almost 1MB each), I can't see the difference.

Originally Posted by Benson View Post
Have you found a way to median-filter the images with imagemagick? I looked a little, and didn't see anything, but I'm sure it's possible.
Yes, just use:
Code:
convert *.png -average -median <radius> final.jpg
EDIT: It looks like that just does a blur on the picture. Not terribly useful. What is "median filter"?
EDIT2: Median filter is a blur! Why would you want to do that?

Originally Posted by Benson View Post
Oh, and it occurs to me; can't mplayer directly view the stream? Something like:
Code:
mplayer -cache 512 tv:// -tv driver=v4l2:width=640:height=480:noaudio -fps 15 -endpos 0.5 -ov jpeg:quality=100:outdir=/media/mmc1/
I think that should do what you're doing now with steps 1 and 2, and (using pnm instead of jpeg, at least) might be a hair faster/less cpu intensive/less susceptible to trouble from other processes.
I figured that mencoder's native format is uncompressed AVI, and so it has been optimized for that format. Dumping all the frames into a single uncompressed file strikes me as the most likely way to minimize CPU use. I doubt that writing a separate image file for each frame would be faster. For instance, the mplayer frame extraction command I give above (to png files) is nowhere near real time speed. Please experiment with other techniques.

Originally Posted by Benson View Post
Why 512kB cache? Can it not keep up at 15 fps with no compression? (I assume 512kB is the amount 0.5s of video takes up, or a bit more?)
No, I just set the cache high to try to reduce lag due to file writing, etc. as much as possible. I chose that number fairly arbitrarily, I confess.

Originally Posted by Benson View Post
Why 15 fps? Is that the maximum you can get from the camera at 640x480? I was hoping to get about 24/30 fps, so that 4 images would be about 1/8 of a second.
This number, however, is not arbitrary. I found that 640x480 15fps is pretty much the highest attainable number, and I'm not even sure that it really is hitting that speed. I was able to get better framerates if I used a smaller frame size, but that's not useful in this context. Again, I welcome input here; I want to be proven wrong!

Originally Posted by Benson View Post
And, a suggestion, using -frames 8 instead of -endpos 0.5, you'd remove the framerate dependence, which makes it easier for you or anyone else to fiddle with mplayer and/or mencoder settings without changing other parts of their script.
One of the programs I was working with required a framerate in order to read the V4L2 stream properly. So I began inserting the framerate into all my capture commands. It may work fine without it. As for "-frames" vs. "-endpos", I don't particularly need a specific number of frames, but I do want to limit the amount of time the user is expected to wait for the capture to finish. That's why I chose endpos. Feel free to use frames instead.

Last edited by qole; 2008-04-16 at 18:59.
 
qole's Avatar
Moderator | Posts: 7,109 | Thanked: 8,820 times | Joined on Oct 2007 @ Vancouver, BC, Canada
#35
Ok, a question for Benson. I found a maemo repository with netpbm libraries available. How would I accomplish the stuff you're talking about with netpbm? Also, is there another, better source for the netpbm binaries?
 
qole's Avatar
Moderator | Posts: 7,109 | Thanked: 8,820 times | Joined on Oct 2007 @ Vancouver, BC, Canada
#36
By the way...

Originally Posted by Benson View Post
If I had mplayer on my tablet...
Woah. I didn't know you could use the tablet without mplayer installed.

It is always one of the first things I install after a reflash.
 
Posts: 356 | Thanked: 231 times | Joined on Oct 2007
#37
Impressive results, thanks, but I'll wait to official release of 4.1 to reflash and use all that programs (still on OS2007).
 
Benson's Avatar
Posts: 4,930 | Thanked: 2,272 times | Joined on Oct 2007
#38
Well, now I freed up enough room for an mplayer (qwerty12 build) install, so I'll move from questions to conflicting recommendations in the future.
Originally Posted by qole View Post
Yes, just use:
Code:
convert *.png -average -median <radius> final.jpg
EDIT: It looks like that just does a blur on the picture. Not terribly useful. What is "median filter"?
Takes the median value from a group of pixels; typically a spatial median filter is used, which takes e.g. a 3x3 group of pixels, and replaces one pixel in the output image with the median value. (The median means the central value, when a list of values is sorted. It's useful for rejecting impulse noise with a small filter size, which reduces the amount of blurring.)
That median filter's not what I want; I'm after a temporal filter, i.e. the median of the same pixel in each image, or something combining that and a little (<1px) spatial averaging. By interleaving the images, it's possible to make a spatial filter and downsampling provide temporal filtering.

I figured that mencoder's native format is uncompressed AVI, and so it has been optimized for that format. Dumping all the frames into a single uncompressed file strikes me as the most likely way to minimize CPU use. I doubt that writing a separate image file for each frame would be faster. For instance, the mplayer frame extraction command I give above (to png files) is nowhere near real time speed. Please experiment with other techniques.
Will do; be careful about confusing native and default here. I expect mplayer's native format is a raw 24-bit pixmap. Probably whatever output format matches that closest will take the least time to convert. I believe that png is still doing some transforms, even though it's not actually doing the zlib compression. Ppm and avi should both be close, but I expect a slight advantage of ppm.

This number, however, is not arbitrary. I found that 640x480 15fps is pretty much the highest attainable number, and I'm not even sure that it really is hitting that speed. I was able to get better framerates if I used a smaller frame size, but that's not useful in this context. Again, I welcome input here; I want to be proven wrong!
Hmmm, OK. I think not specifying might work, if the defaults are sane (i.e. v4l hardware driver doesn't default to some unattainable rate, but to maximum possible), or maybe not.
 
Benson's Avatar
Posts: 4,930 | Thanked: 2,272 times | Joined on Oct 2007
#39
Originally Posted by qole View Post
Ok, a question for Benson. I found a maemo repository with netpbm libraries available. How would I accomplish the stuff you're talking about with netpbm? Also, is there another, better source for the netpbm binaries?
I used stock debian etch armel, dpkging with -force stuff (libc version, iirc), but a chinook repo will be nice. I haven't quite got it worked out yet, but I'll post when I do.

As far as not having mplayer, I don't watch videos much, so it was one of the first things to go when I started running oout of room on my tablet, so I uninstalled it. At the moment, I'm waiting to get time to reflash, and this time mmcboot for more room. I already broke my apt trying to move stuff to the mmc with a symlink, and then having mmc troubles...

But Faheem's build and the ability to use the camera make it worth getting even now.
 
qole's Avatar
Moderator | Posts: 7,109 | Thanked: 8,820 times | Joined on Oct 2007 @ Vancouver, BC, Canada
#40
This might be a useful page: ImageMagic's Compose. Blend looks especially interesting...
 
Reply

Thread Tools

 
Forum Jump


All times are GMT. The time now is 15:30.