contour detection
open vs closed contour
computer vision
image processing
algorithms

Define if a contour is closed or not

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A contour is closed if it forms a loop and open if its endpoints remain separate. In code, the tricky part is that contour representations vary: some libraries already return boundary loops, while polylines extracted from edge pixels may need an explicit geometric check with a tolerance.

Core Sections

Know what your contour representation means

Before writing a closure test, check how the contour was produced. For example, OpenCV findContours usually returns border loops extracted from binary regions, so many contours there are already closed in a topological sense. A raw list of edge points from another algorithm may instead represent an open polyline.

That distinction matters because “first point equals last point” is only meaningful if your data format stores endpoints explicitly.

Simple endpoint check with tolerance

If your contour is a sequence of points, a practical first test is the distance between the first and last point. In real image data, exact equality is often too strict because of quantization or simplification.

python
1import math
2
3
4def is_closed(contour, tolerance=1.5):
5    if len(contour) < 3:
6        return False
7
8    x1, y1 = contour[0]
9    x2, y2 = contour[-1]
10    distance = math.hypot(x2 - x1, y2 - y1)
11    return distance <= tolerance
12
13
14contour = [(0, 0), (5, 0), (5, 5), (0, 5), (0, 0)]
15print(is_closed(contour))

A tolerance-based check is often enough for polygons, hand-drawn paths, and simplified edge traces.

Area is a useful secondary signal

A truly closed contour usually encloses area. An open contour, by definition, does not. So if your geometry pipeline can compute polygon area, that becomes a useful secondary validation.

python
1import cv2
2import numpy as np
3
4pts = np.array([[[0, 0]], [[5, 0]], [[5, 5]], [[0, 5]]], dtype=np.int32)
5area = cv2.contourArea(pts)
6print(area)

If the area is essentially zero, the contour is either open, degenerate, or self-overlapping in a way that needs more careful interpretation.

Area alone is not sufficient, but it helps reject obvious non-loops.

OpenCV-specific considerations

When using OpenCV, be careful about the source of the contour. If the contour comes from findContours on a filled binary object, it is often already a border loop. In that case, what you may really care about is whether the shape is valid, not whether the contour is “closed.”

If instead you start from Canny edges or line traces, the endpoint-based test is more relevant because those structures can remain open naturally.

Polygon approximation can make the check cleaner

Raw contours can be noisy. Approximating the contour before checking closure can reduce tiny zigzags that make the start and end points look farther apart than they conceptually are.

python
approx = cv2.approxPolyDP(pts, epsilon=2.0, closed=True)

This does not magically close an open contour, but it can simplify closure reasoning when the contour is noisy and nearly looped.

Pick a definition that matches the application

Different tasks mean different closure criteria:

  • for vector graphics, endpoint coincidence may be enough
  • for region extraction, enclosed area may matter more
  • for topology-sensitive work, self-intersections may need special handling

So the real first step is defining what “closed” means in your pipeline, not just writing one universal if-statement.

Common Pitfalls

  • Assuming all contours returned by a vision library have the same semantics regardless of how they were extracted.
  • Comparing first and last points for exact equality when noisy image data really needs a tolerance-based check.
  • Using enclosed area as the only closure test even though degenerate or self-intersecting shapes can make that misleading.
  • Forgetting that some APIs already treat detected object boundaries as closed loops by construction.
  • Defining “closed” too loosely for an application that actually needs topological validity, not just nearby endpoints.

Summary

  • A contour is closed when it forms a loop, but the exact test depends on how the contour is represented.
  • For point sequences, endpoint distance with tolerance is a practical first check.
  • Enclosed area is a useful secondary signal, not a universal answer by itself.
  • OpenCV contour semantics depend on how the contour was generated.
  • Define closure in a way that matches your application, then implement the corresponding geometric test.

Course illustration
Course illustration

All Rights Reserved.