Taking "Cantor" beamshots

I use _ceiling_ instead of wall. Below in blue are input parameters - they must be provided by you and passed to the get_LID script.


Camera must have raw output (and apparently, also manual exposure mode). You must know what raw means, how to process it etc.

Find a room. Ceiling - plaster (matte), uniform. Distance (height) from headlight to the ceiling h_cam (all lengths in cm) - the larger the better. Let's say ratio of the headlight aperture (size of the hole from which light goes out) over this height should be around 0.01-0.05, the smaller the better (makes headlight point-like). The room must be dark (not externally lit). Room's walls ideally should be either black, or far away (mine are not). Ceiling area should be big enough so that the beam pattern fits into it.

The camera must be aimed straight up vertically, i.e., perpendicular to the ceiling (I just estimated it by my eyes). It should be placed nearby with the headlight, the closer the better. Its lens should be zoomed-out (= wide-angled = focal distance small) so that (with the above conditions) it captures the whole pattern. The headlight does not have to aim straight up, some angle is OK.

Make a comfortable "cradle" for the camera - so that you can reliably make several shots with identical geometrical settings. How I did:

The basement weights - to allow me to see the camera screen from underneath (yes, very awkward, but OK to discern the needed settings). I put some (rubber) pads to put the camera horizontally (and to not scratch the screen) - first image. Then I pressed the camera down with two other dumbbell weights - second image. Now when I push camera buttons carefully, the camera won't move - at all.

Distances from camera to light are d1_hl, dz_hl. d1=in horizontal plane (up/down on the floor on the pictures). The corresponding d2 (right/left on the floor) is hard-coded to be zero, so place headlight "right below" the camera. dz=along optical axis. Both are positive for headlight "below" the camera - like on the second image.

Once happy with geometry (make test shots), record all the settings (for yourself): the horizontal (on the floor) camera/headlight position, and how you set up the "cradle" (whatever) - in case you'll need to re-shoot, it'll be easy.

Put a ruler on the ceiling (e.g., by pressing it with some long pole), around optical axis of the camera. Make a shot of the ceiling (with your final geometry settings), remove the ruler, convert raw to jpeg, open it in an image editor and find the corresponding length of the ruler in pixels (in Gimp - "Measure tool"). It is important to use raw here because built-in camera software may cheat something with resolution (mine does). The ratio of lengths (cm/pixels) is scale_cm_px. (remove the ruler)

You should calibrate your camera sensor. It's somewhat advanced topic, and optional (you will only loose the normalization; the most important - the relative brightness of different pattern areas - will be captured), so I moved it outside. If you skip calibration, set the first element of rEVs to 1.

Camera settings

Skippable exposure primer in brown.

Related to optics (a bit physics), and is a big topic in itself.. So very briefly. Exposure is determined by a triple of parameters: sensitivity, aperture, shutter. To get some exposure value (1 #), if given two parameters (2 #s), you have a freedom in choosing 1 of them. If there are 3 parameters, there are two freedoms. Each freedom is a trade-off. It is these freedoms/trade-offs that make the photography a rich creative subject. And makes it difficult for me to guide you.

Sensitivity is a control of internal amplifier. Minimum turns the amplifier off. Higher settings let you see the darks under very dim light, but add more noise. A trade-off #1. I set to min, e.g. ISO100.

Aperture is the size of the lens hole. Determines depth of field = DOF = the range of distance that appears acceptably sharp. The smaller aperture (=closed, numbers high, like F/16) - both near objects, and far objects will be in focus, sharp. Good for beamshots, bad for portraits. The larger (=opened, numbers small, like F/2.8) - only some objects will be sharp in focus, background will be blurred. Bad for beamshots, good for portraits. A trade-off #2. (also there's a complication: the more it is open - the more optical artifacts and distortions/aberrations). Set it to max open (to not wait long times), then close it to get the whole pattern in focus.

Shutter. No trade-off.

For example, to get everything focused if it's a little out of - close aperture. Or if you are tired to wait minutes, increase sensitivity to make it faster, or try opening aperture - and check that everything is still in focus.

Note also that aperture=F/2.8 and sensitivity ISO=100 on a cheaper compact camera may give depth of field and noise roughly the same as aperture=F/16 and sensitivity ISO=3100 on a full-frame DSLR. Not going into it.. I'll just mention the keyword: "crop factor", in this case it was 5.6.

Focus method - depends on camera. I guess better use automatic. On my camera I chose manual mode, but pre-set it using auto. So I verified only on one shot that it's in focus, and all other shots will then also be in focus.

Experiment a bit.. obvious goals - ceiling focused (actually a bit unfocused is also OK), sensels values high, but not over-exposed. The camera may have some over-exposure helpers, but the definite way to check this is in a raw converter (in ufraw - zoom 1:1, pan to brightest area and press the appropriate button at the bottom)

Use self-timer on the camera (1-2s) - to not shake it while pressing the "Shoot!" button.

White balance is irrelevant, use any. (the internal camera flash light must of course be disabled)

Beam shooting

Charge the headlight batteries, to have stability in beam intensity (just in case). Decide on the brightness mode you'll shoot. Brighter better, but batteries will drain faster. Record it for later repeat-ability. Ideally measure the consumed current and voltage to get power. The output zM can then be divided by this power to get per 1W LID (I like this normalization).

You really need to make at least two beamshots with different exposures. For a high-contrast cutoff headlight I found I needed three beamshots. The first beamshot captured brights, the second beamshot - middles (with brights over-exposed), third - lows (brights and middles over-exposed).

Length of rEVs array equals to the number of shots (e.g., 2,3). The 2nd element is ratio of exposure value (EV) of 2nd beamshot over EV of the 1st one. In other words, it is 2nd shot EV in units of 1st one. For example, if 1st beamshot used 1/8s, 2nd 1s, then rEVs(2)=1/(1/8)=8. Similarly rEVs(3) is 3d shot EV in units of 2nd: if the 3d beamshot was made with 10s, rEVs(3)=10/1=10. If you change aperture or sensitivity as well as shutter, account for it accordingly in the rEVs. (first element rEVs(1) is about calibration - see above).

Pre-processing (raw)

Make sure the converter settings are sane, e.g., it doesn't adjust exposure after your previous GUI session (I delete config files). Adjust white balance to have all channels about same values. Make it grayscale (any method should be fine). There's always some angular discoloration, I ignore it. Gamma encoding must be off, i.e., gamma=1, i.e., image must be linear. Rotate if necessary. I found batch processing (after manual inspection) is great - all your actions are easily repeatable. See my examples (for ufraw) in image_proc_commands.txt

The jpeg file names need to be passed to get_LID() as cell array in the fns parameter, brightest first.

Open well-over-exposed jpeg (converted) image in an editor, and determine the usable area of the ceiling (in Gimp - rectangle select tool): crop_2,crop_1,crop_sz2,crop_sz1. First pair=coordinates of upper left corner, second pair=size, 2=horizontal, 1=vertical. Make size multiple of 10.

NF - just pass [120 30] in most cases. It defines how much smoothing will be done. Larger #s will make more detailed (and noisy) image, smaller - smoother. Two numbers - for the two dimensions of the image.


With all the necessary input gathered, put all script sources somewhere, together with jpeg images. The order of the input parameters: get_LID(fns,rEVs,NF, crop_2,crop_1,crop_sz2,crop_sz1, h_cam, d1_hl,dz_hl, scale_cm_px) - see the top of the get_LID.m for a summary. Run (in Matlab/Octave; example, put your own numbers):

[zM,bes,alsM]=get_LID({'testA-1.jpg','testA-2.jpg','testA-3.jpg'}, [1 8 8],
[60 30], 216,254,2990,2020, 265-20, 10,10, 33.3/393);
If all is well, visualize:
main_vis(zM/1.2345,bes,alsM, 2.4, 'testA');
(intensity divided - to give per-1W normalization) The first three parameters are from get_LID() output, 4th is tilt angle (not needed for wall visualization), and 5th is title string. What to visualize (wall, 3D, road, etc) - is determined by vis_* flags (=0 or 1) at the very beginning of main_vis().

You may manually change limits of displayed region in appropriate places with: xlim([-20 20]); ylim([-8 17]); (this is for wall vis). It's also easy to get camera zoom for better far view (the camera_tilt and vis_zoom variables).

See run_all.m for my examples.

If you want to just try the scripts without shooting and raw-processing, there are 3 example jpgs in jpgs_for_sim directory. (and the rest of jpgs_for_sim/*.jpg files are in big-files archive).

Consider thinking about physics and studying the code - to double-check me. Main part is the get_LID() function, it's short really. And despite the length of this page - it's all not difficult really.