Library / SDK
iago-suarez/ELSED avatar
iago-suarez/ELSED

ELSED: a fast line segment detector for drones and phones

ELSED: Enhanced Line SEgment Drawing

303 stars60 forksJupyter NotebookApache-2.0

At a glance

What is it?
ELSED is a C++ line segment detector with Python bindings, published in Pattern Recognition in 2022 and still receiving commits in 2026. It is aimed at resource-limited hardware, and it is not a general-purpose feature matcher.
Who is it for?
Adopt ELSED if you need line segments on a drone, a phone or another device where the detector has to stay cheap, and if you are willing to build from source because there is no PyPI release. Do not adopt it if you need a maintained binary wheel, a documented API reference, or a detector whose parameters you can tune from a paper you have not read.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 77 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem ELSED targets: line segments on hardware that cannot afford them

Line segment detection is the step that turns an image into a set of straight edges. It feeds vanishing point estimation, visual odometry, and the wireframe-style representations used in robotics and augmented reality. The README states that ELSED is "the fastest line segment detector in the literature" and that it is "ideal for resource-limited devices like drones of smartphones". That framing is the whole pitch. The project is not trying to be the most accurate detector on a benchmark; it is trying to be the one that still runs when the compute budget is a few milliseconds on an embedded ARM core.

The intended user is therefore an engineer working on a robot, a drone, or a mobile application who has already decided that line segments are the right representation and now needs a detector that fits. It is a lower-level building block, not an application. There is no viewer, no annotation tool, no training pipeline. The repository is C++ source plus a pybind11 wrapper, and the primary language listed for the repository is Jupyter Notebook because the interactive demo lives in Python_ELSED.ipynb.

One consequence of that positioning is worth stating plainly: if your bottleneck is not the detector, ELSED will not help you. A desktop pipeline that spends its time in matching or in a neural network will see no benefit from swapping the detector for a faster one. The speed argument only pays off at the edge of the budget.

How ELSED works: a C++ core, pybind11 bindings, and an OpenCV dependency

The repository layout is small and readable. The top level holds CMakeLists.txt, setup.py, MANIFEST.in, pybind11 as a submodule, src/ for the C++ implementation, images/, the notebook, and the README. There is no separate Python package directory, which tells you the Python module is produced by compiling the C++ rather than by shipping pure Python.

setup.py confirms the mechanism. It defines a CMakeExtension and a CMakeBuild command that shells out to cmake, checks the CMake version (requiring at least 3.1.0 on Windows), and passes -DCMAKE_LIBRARY_OUTPUT_DIRECTORY plus -DPYTHON_EXECUTABLE into the CMake configure step. In other words, pip install does not download a wheel; it invokes CMake, builds the extension in Release or Debug depending on the build mode, and places the resulting library where setuptools expects it. On non-Windows platforms the build uses -j2.

That design is the reason the install instructions begin with a system package rather than with pip. OpenCV is a hard dependency, and the README notes it was tested with version 4.1.1, with a collapsible section explaining how to compile OpenCV from source on Ubuntu 18.04. The Python entry point is deliberately narrow: pyelsed.detect takes a grayscale image and returns two arrays, segments and scores. There is no configuration object, no detector class to instantiate, and no documented parameter set in the README. Everything the paper exposes lives in the C++ side and is not surfaced through the Python call shown.

Installing ELSED from Python and running a first detection

The README gives the Python path as a system package plus a pip install from the repository URL. Note that the install is from GitHub, not from PyPI, so pip needs git available and will compile the extension on your machine.

bash
sudo apt-get install libopencv-dev
pip install setuptools
pip install git+https://github.com/iago-suarez/ELSED.git

The first line provides the OpenCV headers and libraries the C++ core links against. The second ensures setuptools is present, which matters on minimal Python environments. The third triggers the CMake build described in setup.py. Expect compilation output rather than a wheel download; if CMake is missing, the build command raises a RuntimeError naming the extension.

Once installed, the README's usage example is three lines. It reads an image in grayscale and calls detect:

python
import pyelsed
import cv2

img = cv2.imread('my_favourite_img.jpg', cv2.IMREAD_GRAYSCALE)
segments, scores = pyelsed.detect(img)

The important detail is that cv2.IMREAD_GRAYSCALE is not optional. The function takes a single-channel image, and the README's example loads it that way. What you get back is a pair of arrays: segments, which holds the detected line segments, and scores, which holds a value per segment. The README does not specify the exact shape or dtype of either array, so inspect them once in a REPL before writing code that indexes into them.

For C++ users the README describes a demo in the repository that detects both large and short segments in one image, built with CMake:

bash
mkdir build && cd build
cmake .. && make
./elsed_main

The README states the demo prints a banner and then two counts, 305 large segments and 391 short segments for the provided image. Those numbers are for the image shipped with the repository, not a benchmark, and they are the only output figures the README gives.

Where ELSED is the wrong tool, and what the README does not cover

The most concrete limitation is distribution. There is no PyPI release documented in the README, and no release artifacts are listed for the repository. Every installation compiles C++ against a system OpenCV. On a CI runner that is a slow step; on a machine without a compiler or without libopencv-dev it fails outright. If your team's policy is to install only prebuilt wheels from an internal index, ELSED does not fit that policy without you building and hosting the wheel yourself.

The second limitation is documentation depth. The README covers dependencies, two install paths, one Python example, one C++ demo, and a BibTeX entry. It does not document the detector's parameters, the meaning of the scores array, the expected dtype of the input, or any error behaviour. There is no API reference in the repository. For a research artifact that is normal, and the paper is the intended reference, but a team that needs to tune the detector for a specific scene will be reading the publication and the src/ directory rather than a manual.

The third is scope. ELSED returns line segments. It does not match them across frames, estimate homographies, or track them. If your task is to find correspondences between two images, a detector alone is half the pipeline, and the README says nothing about the other half.

On maintenance, the repository is not archived and the last push was on 2026-07-26. That is recent enough that the code is not abandoned, but there are no retrieved releases, so there is no versioned changelog to read before upgrading. Upgrading means pulling a new commit and rebuilding.

How ELSED differs from OpenCV's line segment detector

The obvious alternative is the LSD implementation that ships inside OpenCV itself, which many pipelines already have because ELSED requires OpenCV anyway. The difference in approach is architectural. OpenCV's detector is a library call inside a dependency you have already installed: no separate compilation step, no submodule, no git URL in your requirements file, and it works with whatever OpenCV version your platform provides.

ELSED asks for the opposite trade. You take on a build step and a pinned-ish OpenCV (the README says tested with 4.1.1) in exchange for a detector whose stated design goal is speed on constrained hardware. If your deployment target is a server, the build step is a minor inconvenience and the speed difference may not matter. If your deployment target is a drone or a phone, the build step is a one-time cost and the runtime difference is the reason you are here.

There is a second, less obvious difference. Because ELSED is a small research repository, you can read all of src/ and adjust the algorithm. A detector inside a large general-purpose library is far harder to modify for a specific application. Teams that need to change the detection strategy, not just call it, get more from ELSED's layout than from OpenCV's.

Licence and the cost of keeping ELSED current

The repository is licensed under Apache-2.0, and the LICENSE file sits at the top level. Apache-2.0 is a permissive licence that includes an explicit patent grant, which is often the reason teams pick it over MIT for anything shipped in a product. It is not a copyleft licence, so linking the C++ core into a proprietary application is not, on its face, a redistribution trigger. This is a description of the licence text, not legal advice; if ELSED ends up inside a shipped product, have your own counsel read the NOTICE requirements and the patent termination clause.

Upgrade cost is dominated by the build, not by API churn. There has been no retrieved release, so there is no semver contract to rely on and no changelog to scan. Updating means changing the commit you install from and rebuilding against your OpenCV. Two things can break: the pybind11 submodule, which is vendored in the repository, and the OpenCV ABI, if your system OpenCV moves far from the version the project was tested against. Pin the commit hash in your requirements rather than tracking main, and build the wheel once in CI and cache it, because compiling on every developer machine is wasted time.

Editorial conclusion

Adopt ELSED if you need line segments on a drone, a phone or another device where the detector has to stay cheap, and if you are willing to build from source because there is no PyPI release. Do not adopt it if you need a maintained binary wheel, a documented API reference, or a detector whose parameters you can tune from a paper you have not read. Before committing, verify that libopencv-dev and CMake are present on your build machine, that the pip install from the GitHub URL completes, and that pyelsed.detect returns both segments and scores on one of your own grayscale images.

Frequently asked questions

How do I install ELSED for Python?

Install the OpenCV development package, make sure setuptools is present, then pip install directly from the GitHub URL. The build runs CMake on your machine, so a compiler and CMake must be available.

Does ELSED require OpenCV?

Yes. The README lists OpenCV as a dependency and says the code was tested with version 4.1.1, and the Python install instructions begin with libopencv-dev.

What do the segments and scores returned by pyelsed.detect contain?

The README shows detect returning two values, segments and scores, for a grayscale image, but it does not document their shape or dtype. Inspect the arrays once before relying on their layout.

Official sources

  1. iago-suarez/ELSED on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/iago-suarez-elsed.svg)](https://hysenlabs.com/projects/iago-suarez-elsed)