CS 448A - Computational photography (Winter 2010)

"Hello Camera" Assignment

Due January 26, 2010 at 2:00 p.m.

Introduction: This assignment is an exercise intended to introduce you to the Frankencamera API and Nokia N900, and should get your feet wet and your brain rolling for the term project. You and your partner will implement an autofocus algorithm for N900, and in doing so, you will gain understanding of the challenges involved in interfacing with a camera and making efficient use of the available computational resource.

In fact, if you can come up with an excellent algorithm, it may just become the default implementation provided in the Frankencamera API, or in Nokia N900 in the future!

Steps:

  1. Getting Started (PLEASE READ IN FULL): How to get set up.

  2. Hello World!: Gain some comfort by ensuring that your build environment and device are good to go.

  3. Hello Camera!: Compile and run the (provided) skeleton code to ensure that the camera module works. Study the code and make sure to understand what it does.

  4. Writing an autofocus algorithm: This is the actual meat of the assignment. Have fun!

  5. Writing a touch-to-focus algorithm: Have more fun!

  6. Making your own scene mode: did someone say macro?

  7. Focusing on two subjects: Need we say more?

Deliverables: If you have a pair team, all of TASKS (A)-(I) and write-up questions Q1-7 are required; if you have a singleton team, the last task and the last write-up question are optional.

Useful link:


Getting Started

Developing for N900 will require a cross-compilation environment, such as Scratchbox. We have created a vanilla virtual machine (loaded using VMWare Player or Fusion) that has everything installed. You can obtain the VM by the following means:

  1. Downloading (Warning: 2.4 GB zipped / 6.1 GB unzipped)
  2. Visiting Rm. 360 for a direct transfer.
  3. Visiting Rm. 360 to check out an installation disk (a DVD containing a tarball.)

[Not recommended] If you prefer to create your own VM, or install directly on a physical machine, follow these instructions.

If you are enrolled in the course, you should have received an N900 which has already been configured with the necessary modules and updates. You can gain root privileges by entering root (password: root) in a terminal.

Managing your N900 [PLEASE READ]: The distribution of the N900's is made possible by the generosity of Nokia. Please take good care of these devices!

Tips for using your N900:

Your N900 should already have ssh installed. To find out the IP address of your N900, you may either visit sites that tell your IP, such as this, or open an X-terminal and do the following:

~ $ root
Nokia-N900-XX-XX:~# ifconfig
Now scroll up and find the field "inet addr". Once you know your IP address, you can log onto your N900 remotely from your own machine.
cs448a@ubuntu:~$ ssh root@XXX.XXX.XXX.XXX
Nokia-N900-XX-XX:~# 

You may now login to Scratchbox as follows:

cs448a@ubuntu:~$ scratchbox
[sbox-FREMANTLE_ARMEL: ~] >
Scratchbox is a chroot environment, meaning that the root directory has been mounted from the filesystem. The path to this directory in the VM itself is given by the symbolic link called scratchbox-root in your home directory of the VM. Likewise, the home directory in Scratchbox is pointed to by a symbolic link called scratchbox-home. Therefore,
[sbox-FREMANTLE_ARMEL: ~] ls
and
cs448a@ubuntu:~$ cd scratchbox-home
cs448a@ubuntu:~/scratchbox-home$ ls
will return the same results. This is useful because Scratchbox does not come with a good text editor. So you will most likely be editing file on cs448a@ubuntu:~/scratchbox-home in your VM.

Running binaries built in Scratchbox is now easy. scp the file onto your N900 from Scratchbox, and run the binary from an ssh terminal. For instance (hypothetically), in Scratchbox,

[sbox-FREMANTLE_ARMEL: ~] > g++ myapp.cpp -o myapp
[sbox-FREMANTLE_ARMEL: ~] > scp myapp root@XXX.XXX.XXX.XXX:/home
[Note] Try to put your files in /home, as there is only limited space in the root file system. You may now ssh into your N900, change directory to /home and run your binary:
cs448a@ubuntu:~$ ssh root@XXX.XXX.XXX.XXX
Nokia-N900-XX-XX:~# cd /home
Nokia-N900-XX-XX:/home# ./myapp
You could, of course, open an X terminal on your N900 directly, but you might prefer typing on a full keyboard and reading the console output on a full monitor.


Hello World!

If you have completed setting up your N900, this step is relatively easy. Write a very simple command-line program, like Hello World. Compile your code in Scratchbox, transfer the binary onto your N900, and confirm that it runs.

There are a couple of Qt examples in sample directory of Scratchbox. If you built your own Scratchbox, you can find these files here. (They are from Nokia's official Qt examples.) To build these, run qmake -project in the appropriate folder, followed by qmake XXXXXX.pro and make, where XXXXX is the name of the .pro file that resides in the respective folder. This will generate an executable of the same name. For instance, the following would work:

cs448a@ubuntu:~$ scratchbox
[sbox-FREMANTLE_ARMEL: ~] > cd sample/analogclock
[sbox-FREMANTLE_ARMEL: ~/sample/analogclock] > qmake -project
[sbox-FREMANTLE_ARMEL: ~/sample/analogclock] > qmake -unix analogclock.pro
[sbox-FREMANTLE_ARMEL: ~/sample/analogclock] > make
[sbox-FREMANTLE_ARMEL: ~/sample/analogclock] > scp analogclock root@XXX.XXX.XXX.XXX:/home

Take a minute to familiarize yourself with basic Qt. You will presumably need some minimal experience with Qt to build a reasonable interface to whatever application you make, but no more than what is involved in the examples, unless you intend to use other features, such as multi-threading, event handling via signals and slots, networking, et cetera. A set of examples and their source code can be found here. There is a more serious tutorial from Nokia, released two weeks ago. They would appreciate any feedback, in fact!


Hello Camera!

In ~/sample/camera of the VM, you will find a skeletal implementation of a camera application. Compile via make and run the binary on your N900. (Note for those of you with custom VM: If you placed libFCam.a somewhere particular, then you should add the appropriate linker flags.)


N900 focused near


N900 focused afar

At first glance, the skeletal implementation has a working viewfinder, a slider widget for setting exposure and three buttons. Play around with the slider and buttons and observe what they do. The slider should change the exopsure of the incoming frames, and the two buttons on top should change the focus setting. Both the LED flash and the shutter button are hooked up as well. The (physical) shutter button takes a snapshot and saves it on disk. However, no autofocusing takes place currently when you take a snapshot.

The code is not long, and is heavily commented. Here's a quick description:

  • main.cpp: a Qt wrapper to launch an application.
  • MyCamera.h/cpp: a Qt widget that contains all the widgets you see on screen.
  • MyCameraThread.h/cpp: a thread that communicates with the camera daemon and fetches frames.
  • MyViewfinderX.h/cpp: a widget that displays frames.
  • MyInfoWidget.h/cpp: an OpenGL ES widget you can use to display information on the screen.

You will be making changes mostly on the two files marked in red, and possibly be adding your own files. Your task is described in detail in the following section.

NOTE: You should realize that the N900 does not have controllable aperture. Also, its depth of field is not as controllable as that of your DSLR. From the images to the left, observe that when focused afar, the depth of field is very large.

This application uses the Frankencamera API to interface with the camera hardware. The header files can be found at /usr/include/FCam. You will, throughout the assignment, need to refer to the full API documentation.


Writing Autofocus

Write-up:


Writing Touch-to-focus


Modal Autofocus

Write-up:


"Two-Focus"

TIP for TASK (I): Given two taps by the user, finding d_1 and d_2 is not an easy problem. It is called in literature "depth from focus" or "depth from defocus." An alternative approach is to choose a focus setting that makes the two objects equally sharp. This would fail if the two objects have different amount of texture, however, so you may want to focus on them individually to determine how sharp each of them is when in focus, and use this information as a normalizer. If you have other ideas, feel free to discuss them with the staff and/or implement them. We honestly do not know how well it will work on the N900, so it is not imperative that it works well, but be sure to approach the problem with rigor.

NOTE: Task (I) and Q7 are optional for singleton teams.

Write-up:


Hints:


Troubleshooting

Consult the class newsgroup su.class.cs448a if all else fails.


© 2010 Marc Levoy, Fredo Durand and Jongmin Baek
Last update: February 11, 2010 09:28:12 PM