← Writing / April 20, 2026 / 9 min read
Carrier Lifetime from 49 Photos of an Oscilloscope
An experimental-physics project with a computer-vision twist: no numeric data ever existed, only 49 photographs of a scope screen. I taught a computer to read the decay curves off the photos, fit them, and recover the minority-carrier lifetime of a silicon solar cell.
The whole project rests on a fact that should not have been possible to work with: there was no data. A silicon solar cell had been measured in the lab, its minority-carrier lifetime probed by photoconductive decay across a temperature sweep, and the only surviving record of the entire run was 49 photographs. Not saved waveforms, not a CSV, not a scope dump over GPIB. Forty-nine images of a Tektronix TDS 2024 screen and a Keithley 2182A nanovoltmeter, taken roughly one every 25 seconds over about 20 minutes. Every number I report below, every temperature and every microsecond of lifetime, was recovered from those pixels.
So this is two projects wearing one coat. Half of it is semiconductor physics: what photoconductive decay measures and why the lifetime falls out of an exponential tail. The other half is computer vision: turning a photograph of a glowing trace into a clean, calibrated decay curve you can actually fit. I will take the physics first, because it tells you what the pixels have to give up.
What lifetime is, and why you decay a solar cell to get it
A solar cell works because photons knock electron-hole pairs loose. Those excess carriers are what carry current, but they do not live forever. Each one survives only until it recombines, and the mean time from generation to recombination is the minority-carrier lifetime . It is one of the cleanest single numbers for the electronic quality of the material, because it is set by the density of defects that carriers recombine through.
Photoconductive decay measures about as directly as you can. Shine light on the cell and its conductivity rises as carriers pile up. Cut the light and the excess carriers recombine, so the conductivity, and the voltage proportional to it, decays back toward baseline. In this rig a laser was chopped by a mechanical fan at roughly 70 Hz, and the falling edge after each blocked pulse is the decay. If the excitation is switched off fast compared to , the fall is a pure exponential:
The time constant of that tail is the carrier lifetime. Fit the exponential, read off . That is the plan. The rest of the physics is a story about the word “if” in “if the excitation is switched off fast enough,” and we will come back to it.
Reading physics off a photograph
First I had to get the curve out of the image, and a photo of a scope is a hostile input. The screen is shot at an angle, so the graticule is a trapezoid, not a rectangle. The trace glows and blooms. The dim tail of the decay, which is exactly the part I need, is the faintest thing on the panel. There are two instruments in most frames plus the grey of the room. The pipeline is OpenCV and Python, managed with uv, and it runs in three stages.
Temperature, from the Keithley. The nanovoltmeter reads out on a bright cyan VFD, a very distinctive color against the blue-purple scope and the grey room. I threshold for bright cyan in HSV, restrict to the lower part of the frame where the meter sits, and morphologically close horizontally so the row of digits merges into one wide strip I can crop and upscale. The validation is beautiful in its simplicity: read in chronological order, the recovered temperatures climb monotonically in steps of about 0.49 degrees C with zero reversals. A thermocouple on a warming sample cannot un-warm, so a strictly monotone sequence is strong evidence the reader is correct. The run covers -49.99 to -26.51 degrees C, that is 223.2 to 246.6 K, warming at about 1.19 degrees C per minute.
The trace, from the scope. The TDS 2024 LCD is a vivid blue, so I segment for that hue, but a plain blue panel or the window blinds behind the bench can masquerade as a screen. Two tricks reject the impostors. The scope LCD is a 4:3 rectangle, so I filter candidate contours by aspect ratio, which kills the long strips of blind. And a real scope screen contains the cream-colored trace, so among survivors I prefer the contour whose bounding box actually contains cream pixels. Having found the screen I take its convex hull, approximate it to a quadrilateral to get four clean corners (the hull matters, because the trace and the on-screen menu carve concavities into the blue field that would otherwise corrupt the corner finding), and apply a perspective transform to rectify the trapezoid into a canonical 800 by 600 image.
Now the graticule is square, but I still need to know how many microseconds a pixel is worth. Rather than trust a fixed number, I recover it per image from the grid itself. Running a Sobel profile down the rectified graticule and autocorrelating it finds the repeat period of the grid lines, about 62.5 pixels per division. The scope was on 250 microseconds per division, so that pins the calibration at roughly 4.0 microseconds per pixel, and the fact that the grid period comes out consistent is an independent check that the rectification is honest.
Extracting the trace itself is a column walk. For each column I take the centroid of the cream-colored pixels as the trace height. The subtlety is the tail: as the decay fades, the cream drops below any fixed threshold and the hard mask loses it. So where the mask is empty I fall back to a “cream score,” roughly red plus green minus twice blue, and pick the brightest cream-ish pixel within a window around the previous column’s height. That continuity constraint lets the tracker follow the faint tail without jumping onto a grid line or a menu glyph. The verification overlays, where the extracted points are drawn back onto the original trace, land exactly on the glowing curve.
Fitting the tail, and the trap in the shoulder
With 49 calibrated curves in hand, the exponential fit ought to be routine. It was not, and the reason turned out to be the most interesting physics in the project.
The measured fall is not a clean exponential. It is sigmoidal: it starts nearly flat, bends into its steepest slope partway down, and only then straightens into a decay. A pure has its steepest slope at the very top of the fall, not in the middle, so something is rounding off the top. That rounded top is the shoulder, and it is a genuine artifact you can catch red-handed.
The cause is that “if the light switches off fast enough” caveat. A mechanical fan blade does not chop the beam instantly. Its edge takes a finite time to sweep across the laser spot, so the illumination ramps down rather than stepping down, and the measured signal is the true exponential recombination convolved with that finite optical turn-off. The convolution smears the top of the fall into the shoulder.
Here is the clean proof it is instrumental and not physics. I measure the shoulder width on every image, and it comes out at 162 plus or minus 9 microseconds and stays flat across the entire temperature sweep. A mechanical chopper cannot possibly depend on the sample’s temperature. So a shoulder that is constant while itself changes must be the apparatus, not the recombination. The real lifetime lives in the exponential body below the shoulder.
That dictates the fit. I do not fit the whole fall. I normalize each curve to and fit against only over the body, roughly , a window that sits below the chopper shoulder and above the noise floor and is immune to how long the plateau ran. The log-linear fit is a straight line in semilog with a typical around 0.98 to 0.99. The lifetimes come out in the range 245 to 384 microseconds, median 319, exactly where a crystalline-silicon cell limited by Shockley-Read-Hall recombination through a defect level should sit.
What the sweep actually reveals
The original question was : how does lifetime depend on temperature, and what does that say about the dominant recombination mechanism? The honest answer is that this dataset cannot cleanly say, and finding out why is the payoff.
Lifetime correlates only weakly with temperature, . It correlates strongly, , with the amplitude of the photo-signal, which is proportional to the injection level, the density of carriers you inject with each pulse. Worse, the run splits into two regimes with a simultaneous jump in both and amplitude at image 15, around the midpoint of the session, the fingerprint of someone nudging the laser power or focus mid-run. Regime A, the earlier low-injection images, sits at about 260 microseconds; regime B, higher injection, at about 335. Both regimes fall on a single rising -versus-injection trend.
That is not noise, it is real physics pointing the wrong way for this experiment. In silicon, SRH lifetime genuinely depends on injection level: push more carriers in, the recombination traps saturate, and rises. So injection is a real knob on , and here it moved during the run and co-varied with temperature. The two effects are entangled, which is why a single Arrhenius fit for an activation energy is worthless on this data (, uninterpretable). To isolate you would need to hold injection fixed (stable laser power and focus) and use a faster chopper so the optical turn-off is far shorter than and the shoulder vanishes entirely. Vary temperature and injection independently and you are doing proper temperature-and-injection-dependent lifetime spectroscopy, which is how you pull a defect’s energy level and capture cross sections out.
The result I am happiest about is not the lifetime number. It is that a full quantitative dataset, 49 calibrated decay curves and a monotone temperature record, was reconstructed from nothing but photographs, and that the same photographs caught the apparatus lying about its own turn-off time. The code, the extracted traces, and a Typst report with the figures are all in the repo.
Here is the strange situation I walked into. A physics experiment had been run on a solar cell, measuring how good the cell was over and over as it slowly warmed up. And when it was time to look at the results, there were no results. No spreadsheet, no saved data, nothing to plot. The entire record was 49 photographs. Just pictures of the lab screens, one every 25 seconds or so, like snapshots off a phone. Every number I needed was locked inside those photos as glowing shapes.
So the project became two things at once. Part of it was the physics of how solar cells work. The other part was teaching a computer to read the photos, the way you can glance at a picture of a hospital heart monitor and still see the heartbeat even though you were never in the room.
What the experiment was really about
A solar cell works because light knocks tiny electric charges loose inside it. Sunlight hits the material, and out pop little free charges that can flow as electricity. That is the whole trick of a solar panel.
But those loose charges do not last. Almost as soon as they appear, they start finding each other again and canceling out, like sparks fizzling. Each charge survives only a tiny fraction of a second before it fizzles, and that survival time has a name: the lifetime. It is one of the most important numbers about a solar cell, because the longer the charges live, the more of them you collect as electricity, and the better the cell. A cell full of flaws fizzles its charges fast. A clean, high-quality cell holds onto them longer.
So how do you measure something that survives less than a thousandth of a second? You flash a light at the cell and watch how fast the glow fades. When light shines on it, the cell fills up with loose charges and, in effect, “glows” electrically: it conducts better. The instant you cut the light, the charges fizzle out and that glow fades. Fast fade means short lifetime. Slow fade means long lifetime.
In this lab they did exactly that. They shone a laser on the cell and used a spinning fan blade to chop the beam on and off dozens of times a second, flash, flash, flash. Each time the blade blocked the beam, the glow faded, and that fading curve is what you want to measure. They watched it on an oscilloscope, a screen that draws a wiggling line showing how a signal rises and falls over time. Every fade shows up as a little downward slope.
The part where the data did not exist
And that is where the trouble started, because nobody saved the wiggling lines as data. All that survived was 49 photos of the oscilloscope screen with the glowing curve on it, plus a second little display showing the temperature of the cell at that moment. The physics was all there, sitting in the photos. It just was not in any form a computer could add up.
So I taught a computer to read the photos.
This is harder than it sounds, because a photo of a screen is a mess. The picture is taken at a slight angle, so the screen is a lopsided trapezoid instead of a neat rectangle. The glowing line blooms and smears. And the most important part of each curve, the very end of the fade, is also the dimmest, faintest part, the hardest thing in the whole picture to see.
The computer handles it in steps. First it hunts for the temperature display, which glows a distinctive cyan blue, and reads the number. I knew this was working because the temperatures came out in a perfectly smooth, steadily rising order, exactly what you expect from something slowly warming up. If the reading had been sloppy, the numbers would have jumped around. They did not.
Then it finds the oscilloscope screen by its vivid blue color, locates the four corners, and digitally straightens that lopsided trapezoid back into a clean rectangle, the way you might straighten a photo of a document shot at an angle. The screen has a background grid printed on it, like graph paper, and by measuring the grid spacing the computer works out how much time each step across the screen is worth. Finally it walks across the picture and traces the glowing curve, dot by dot. For the faint dying tail, where the glow almost disappears, it leans on the fact that the curve cannot suddenly jump, so it keeps following gently from where it just was. When you draw the computer’s traced dots back on the real photo, they land right on the glowing line.
The little mystery hiding in the curves
There was one lovely twist. The fading curves did not fade the way pure physics says they should. Instead of dropping fastest right at the top, each one started with a soft, rounded shoulder before it got going, as if the fade hesitated for a moment.
The culprit was the spinning fan blade. It does not block the laser instantly. Its edge takes a brief moment to sweep across the beam, so the light dims gradually instead of snapping off, and that gentle dimming smears a little rounded shoulder onto the top of every curve. I could prove it was the fan and not the cell: that shoulder was exactly the same width in all 49 photos, even as the cell warmed up and its real behavior changed. A fan blade does not care how warm the cell is. Something that stays fixed while everything else changes is the equipment, not the physics. So I simply measured the true fade from the clean part of the curve below the shoulder.
In the end I got what nobody had saved: a full set of numbers, 49 measured fade curves and 49 temperatures, all reconstructed from photographs alone. The lifetime of the charges in this silicon cell came out to a few hundred millionths of a second, right where a decent solar cell should land. And the photos even caught the equipment quietly fibbing about how fast its own shutter closed. Not bad for a pile of pictures of a screen.