Piero V.

RealSense D400 and infrared streams

A while ago, I started working on a dataset I captured a few years ago with a Microsoft Kinect One.

I immediately realized the data looked much cleaner than the newer datasets I created with my Intel RealSense D435.

I had already noticed that, above a certain distance, the depth data was full of craters. I already knew the error is proportional to the squared distance, but for me, it was much bigger than expected. Therefore, I calibrated the sensors and now I stay closer to my targets during the acquisitions.

But for the last dataset I captured, I tried another strategy: I decided to save also the raw IR footage to process it offline.

Stereo vision

RealSense cameras are RGBD sensors: they provide simultaneously a color (RGB) and depth (D) stream.

There are several types of techniques to measure depth. For example, the original Kinect for the Xbox 360 uses “structured light”, and the Kinect One included a time-of-flight camera.

The RealSense D400 series is based on stereo vision, which works by matching the same point in frames captured by two different cameras. There is a relation between the displacement of this point (disparity), the relative position of the two cameras, and the depth. … [Leggi il resto]

IMAP downloader

Two weeks ago, I needed to mass-download a few IMAP mailboxes before migrating them to another provider.

Gist contains many scripts to do so, and I tried one of them, but it did not work as I wanted. I wanted to download all the IMAP folders, not only Inbox.

Therefore, I wrote my version of that script 😄️.

I used imapclient instead of the built-in imaplib because it is more Pythonic and handles all the tedious conversions between bytes, strings, and other types.

The center of the script is the process function. It connects to an IMAP server, queries the list of folders, and downloads all the messages from each one but trash and spam (but notice that the comparison is case-sensitive!).

client.fetch downloads all the messages you provide to it, which caused an OOM in my case. Therefore, I split the list with the message IDs into chunks. I had to write the batches function because I was running on Python 3.11. From Python 3.12, you can use itertools.batched instead. … [Leggi il resto]

Zbar, GTK and Python 3

Last week, we had Hackweek at Tor. Instead of doing what we usually do, we worked on small Tor-related projects for 5 days. I chose to work with intrigeri and boyska from Tails to help them improving the pluggable transports on Tails.

There are several ways to get Tor bridges. One is requesting them to BridgeDB through email. The answer contains the bridge lines both as text and in a QR code. So, the first objective of our Hackweek team was to create a proof-of-concept to load these QR codes through a webcam.

Tails’s connection wizard is written in Python. A trivial approach is capturing frames from the webcam with OpenCV, then decoding them with pyzbar. This would have worked, but Tails is a live system, and an OpenCV installation requires a lot of space.

I soon discovered that OpenCV is the de facto way to deal with webcams in Python. I have tried some other alternatives, but they did not work. I have also tried to use a low-level approach based on the V4L2 API. But dealing with the conversion of color spaces and creating a generally reliable solution is burdensome. … [Leggi il resto]

OpenCV and time lapses

After buying my Pixel 4a, I decided to take a picture of a poplar near my home every day. I did this for one year, and I created a time lapse. But I will not publish it here because it would reveal where my home is 😜️.

Methodical is not enough

With time lapses, you usually keep your camera still, but this was not an option in my case. Therefore, I tried to be methodical in taking the various pictures.

I used a sewer cover as a point to shoot the photo and a telephone pole as a reference (its tip is close to the upper-left corner in every picture).

Still, the results were varied, but luckily OpenCV came to the rescue.

Homography matrices

We could say that my scenario is like capturing the same scene with different cameras. Therefore, we can compute the homography matrix to reproject one image to the previous one.

And OpenCV has a very handful function to do so: findHomography. It takes the coordinates of corresponding points as inputs, and it returns a 3-by-3 matrix as output.

If you are using Python, you must pass the points as two NumPy matrices. Both must have the same shapes: a row for each pair and two columns with the coordinates. The point at the ith row of the first array must correspond to the point at the ith row of the second array. … [Leggi il resto]


Recently, I started experimenting with stereo vision.

It is a technique to produce depth maps using images captured by close positions. Then, with these maps, it is possible to create 3D representations.

The core of this workflow is the matching algorithm, which takes pairs of post-processed images and creates a “disparity” map. The disparity is the distance between a point in the two images. Depth and disparity are inverses, so it is easy to switch from one to the other.

OpenCV contains some stereo matching algorithms, but they produced a lot of noise. So I looked for another library, and I found libelas.

It is a GPLv3 C++/MATLAB library with many parameters to tune, but I could not find a Python version. My options were to switch to C++ or to port it by myself. I chose the latter, hoping that also others can benefit from it 🙂️.

Long story short, I published my first package on PyPI: PyElas.

How to use it

You can install it using pip. Then you just have to do this: … [Leggi il resto]