⏱️ Lectura: 12 min
A train isn’t a scanner, but that didn’t stop a developer from turning one into one. Philo spent the last few months pointing an industrial line-scan camera out the window of trains and ferries to capture panoramic photographs tens of thousands of pixels wide, and presented the result as a talk at EMFcamp 2026.
📑 En este artículo
The project, documented in detail on Philo’s personal blog on August 17, 2026, solves a problem that conventional digital cameras can’t: producing a continuous, extremely high-resolution image of an entire landscape, line by line, while the vehicle moves at variable speed.
TL;DR
- Philo built an industrial line-scan camera to photograph trains and ferries, published August 17, 2026 on philo.gay.
- The camera used is the Basler ruL2048-19gm, designed to inspect industrial conveyor belts.
- The sensor reads a 1×2048 pixel line up to nearly 19,000 times per second.
- An image taken on the San Francisco to Oakland ferry in February 2026 measured 56,894×2,048 pixels in grayscale.
- The list price of Basler’s most basic model runs around $700; Philo got theirs used on eBay for a tenth of that price.
- The project was presented as a talk at EMFcamp 2026, the UK’s biennial hacker conference.
- Early prototypes used a phone recording video, extracting one column from each frame (a technique inherited from the 1990s).
- The biggest technical challenge was measuring the vehicle’s exact speed: accelerometer data turned out to be too noisy.
Introduction
Photographing an entire landscape from a train window usually means picking a single instant: the phone camera captures one frame and that’s it. Philo’s project flips that logic: instead of freezing a moment, it records the whole journey as a single continuous image, line by line, using the same principle desktop document scanners rely on, but applied to miles of railway track instead of a sheet of paper.
The result is photographs that don’t look like anything a conventional camera produces: extremely wide, almost map-like in appearance, where each horizontal segment corresponds to a distinct stretch of the actual route.
What happened
Philo has been experimenting with line-scan cameras since late last year, industrial sensors that, instead of capturing a full frame, read a single line of pixels many times per second. Pointed out the window of a moving train or ferry, each captured line corresponds to a distinct strip of the landscape. Capture and stitch together enough lines per second, and the result is a continuous image spanning miles of the route in a single shot.
The example Philo uses to showcase the result is an image taken on the ferry connecting San Francisco to Oakland in February 2026: a grayscale photograph measuring 56,894×2,048 pixels, as described in the original article. To put that number in perspective: a 4K screen is only 3,840 pixels wide, so the ferry image is equivalent to nearly 15 4K screens placed side by side.
Context and history
The idea of moving a single line sensor to build a large image isn’t new. In the 1990s, when digital sensors still couldn’t match the resolution of medium or large format film, the photography industry developed so-called scanning backs: devices that moved a single line of pixels (or three for color) across the focal plane of a large-format camera. That technique avoided building a giant sensor and, decades later, remains cheaper than manufacturing a large single-piece sensor: sensors covering the 4×5 inch format exist today, but they’re expensive.
Philo wanted to build their own scanning back for a large-format camera, but never got around to it because of how complicated the mechanical assembly would be. The idea that finally unlocked the project came from watching a video about Gigawipf’s medium-format scanning camera: what if, instead of moving a part of the camera, you move the whole camera and leave the subject still? That’s where the concept of pointing the line sensor out the window of a moving vehicle, instead of moving it inside a fixed camera, came from.
This isn’t the first attempt of this kind. Philo cites several precedents: the Scannoramic project, John Hikerbiker’s experiment, Daniel Lawrence Lu’s technique of inverting a stationary camera, and Martin Liebscher’s film photographs. The goal was to improve on those results by accounting for the actual speed of motion, to keep the final image from coming out distorted.
Technical details: how the line-scan camera works
The first prototype was literally a couch. Philo put their phone on an office chair, pushed it slowly while recording video, and used a script to extract the leftmost column (a slit) from each frame and combine them into a single image. The result vaguely resembled a couch, but distorted, because the pushing speed wasn’t constant. That was the first sign that the project’s core problem wasn’t optical but about measuring speed accurately.
The second attempt was on Boston’s MBTA Orange Line: an old phone taped to the seat captured accelerometer data while another recorded video at 60 frames per second against the window. Integrating acceleration to get speed turned out to be too noisy: at one point the data indicated the train was moving backward at the end of the trip, which obviously didn’t happen.
To get more lines per second than a phone could manage, Philo ended up buying a Basler ruL2048-19gm, an industrial line-scan camera designed to inspect objects on conveyor belts at high speed. Its 1×2048 pixel sensor can be read up to nearly 19,000 times per second, as Philo documents. That capture rate is what makes it possible to build sharp images even when the train is moving fast: the faster the vehicle, the more lines per second are needed to avoid losing detail.
Buying one of these cameras new isn’t cheap: Basler’s entry-level model runs around $700. Philo got theirs on eBay for about a tenth of that price, also sidestepping the problem with 1990s scanning backs, which still cost thousands of dollars and require rebuilding a period-accurate computing environment to operate.
flowchart TD
A["1x2048px line sensor"] --> B["Line buffer"]
B --> C["Speed estimation"]
C --> D["Duplicate or discard columns"]
D --> E["Final panoramic image"]
How to get started or try it yourself
You don’t need a $700 industrial camera to experiment with the concept: the same slit-scan technique Philo used in the first couch prototype can be reproduced with Python, a laptop, and any camera that records video. The idea is the same: take a single column from each frame of a video and stitch them side by side.
First, install the dependencies. The package is the same across all three operating systems (opencv-python and numpy), only how you activate the virtual environment changes:
# Windows (PowerShell)
python -m venv venv
venv\Scripts\Activate.ps1
pip install opencv-python numpy
# macOS / Linux (bash)
python3 -m venv venv
source venv/bin/activate
pip install opencv-python numpy
The minimal script opens a video, extracts the center column from each frame, and stacks them into a new image:
import cv2
import numpy as np
capture = cv2.VideoCapture("train_ride.mp4")
columns = []
while True:
ok, frame = capture.read()
if not ok:
break
height, width = frame.shape[:2]
center_column = frame[:, width // 2]
columns.append(center_column)
slitscan_image = np.stack(columns, axis=1)
cv2.imwrite("basic_slitscan.png", slitscan_image)
That script produces a distorted image if the vehicle’s speed isn’t constant, exactly the problem Philo ran into with the couch. A more realistic version compensates for speed by duplicating or skipping columns based on how fast the vehicle is moving at each instant, using optical flow between consecutive frames to estimate it:
import cv2
import numpy as np
capture = cv2.VideoCapture("train_ride.mp4")
ok, previous_frame = capture.read()
previous_gray = cv2.cvtColor(previous_frame, cv2.COLOR_BGR2GRAY)
columns = []
while True:
ok, frame = capture.read()
if not ok:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
flow = cv2.calcOpticalFlowFarneback(
previous_gray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0
)
horizontal_speed = np.mean(flow[:, :, 0])
repetitions = max(1, round(abs(horizontal_speed)))
width = frame.shape[1]
center_column = frame[:, width // 2]
for _ in range(repetitions):
columns.append(center_column)
previous_gray = gray
compensated_image = np.stack(columns, axis=1)
cv2.imwrite("compensated_slitscan.png", compensated_image)
To confirm the compensation works, measure in pixels the width of an object that repeats along the route, like a lamppost or a rail crossing: if that width stays reasonably constant throughout the image, the estimated speed is correct; if it varies a lot, you need to adjust the calcOpticalFlowFarneback parameters.
| Approach | When to use it | Advantage | Limitation |
|---|---|---|---|
| Phone + basic script | To test the concept without spending anything | Zero investment, ready in minutes | Distorts if speed isn’t constant |
| Phone + optical flow | For presentable results from a bus or car | Automatically compensates for speed changes | Still limited by the phone’s frame rate |
| Basler ruL2048-19gm camera | For sharp images at high speed, like on a train | Up to 19,000 lines per second | Requires dedicated hardware and mechanical mounting |
💡 Tip: if you try this yourself, record against a clean window on a stretch of the route without curves or sudden braking: speed changes are, by far, the main source of distortion in any line-scan image.
Impact and analysis
What’s interesting about Philo’s project isn’t just the visual result, but the repurposing of industrial hardware outside its original intent. The Basler ruL2048-19gm exists for quality control on production lines, not artistic photography, and its availability on the secondhand market, pulled from factories upgrading their equipment, makes it accessible at a price far below a vintage digital scanning back.
It’s also a reminder that much of the work in image-capture projects isn’t in the sensor but in post-processing: syncing the line-reading speed with the vehicle’s actual speed was, by Philo’s own account, the part that took the longest to solve, far more than sourcing or mounting the camera.
Philo wasn’t the only person presenting this kind of project at EMFcamp 2026: Tim Jacobs, known as mitxela, gave a parallel talk about line-scan cameras, though with a different approach, generating psychedelic animations by sweeping through every possible position of a strip within a video instead of still photographs of real landscapes.
📌 Note: Philo says they got worried upon seeing mitxela’s talk on the EMFcamp schedule, fearing both had done exactly the same thing. The two projects turned out to be complementary, not duplicates.
What’s next
Philo maintains a gallery with more results from the project, including the full image of a container port and the San Francisco to Oakland ferry shot. The original article, about 4,600 words long, also details the mechanical construction of the camera mount and the full post-processing pipeline, useful information for anyone wanting to replicate the project with their own hardware.
The EMFcamp 2026 talk was recorded on video and is linked from the same article, for those who’d rather watch the process explained step by step instead of reading it.
📖 Summary on Telegram: View summary
Try it yourself: clone the optical flow script above, record a short video from a bus window, and compare the result against the basic uncompensated script.
Frequently Asked Questions
What is a line-scan camera?
It’s a sensor that, instead of capturing a full frame, captures a single line of pixels many times per second. It’s normally used in industrial inspection, where the object, for example something on a conveyor belt, moves in front of the fixed sensor.
Why are the images in this project so wide?
Because each line captured by the sensor corresponds to a different instant of the journey. The more lines per second captured and the longer the trip lasts, the longer the final image ends up, reaching tens of thousands of pixels as in the San Francisco to Oakland ferry example.
What’s the main technical difficulty with this type of photography?
Accurately measuring the vehicle’s speed at every instant. If speed varies and isn’t compensated for, the final image comes out stretched or compressed in the areas where the vehicle accelerated or braked.
Can you try this technique without buying an industrial camera?
Yes. The project’s own author started out recording video with a phone and extracting one column from each frame with a homemade script, the same technique that can be reproduced with Python and OpenCV.
Where was this project presented?
At EMFcamp 2026, a hacker conference held every two years in the UK, where Philo gave a talk explaining the full build process and the failures of the early prototypes.
How much does a camera like the one Philo used cost?
Basler’s entry-level model runs around $700 new; Philo got theirs used on eBay for about a tenth of that price.
References
- Using the railway network as a flatbed scanner: Philo’s original article with the full project details, image gallery, and the EMFcamp 2026 talk video.
- Basler AG: manufacturer of the ruL2048-19gm industrial line-scan camera used in the project.
- EMFcamp: the UK’s biennial hacker conference where the talk about this project was presented.
- Image scanner (Wikipedia): general background on image-scanning technologies, including 1990s digital scanning backs.
📱 Enjoying this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day. @programacion
Imagen destacada: Foto de Disha Sharma en Unsplash
0 Comments