Introduction to Contours

Contours are curves that join all the continuous points along a boundary that have the same color or intensity. They are widely used in shape analysis, object detection, and recognition tasks in computer vision.

OpenCV provides the findContours() method to extract contours and drawContours() to display them.

Basic Contour Detection

Steps:

  1. Convert image to grayscale
  2. Apply threshold or Canny edge detection
  3. Use findContours()
  4. Draw the contours with drawContours()

cv::Mat img = cv::imread("shapes.png");
cv::Mat gray, edges;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
cv::Canny(gray, edges, 100, 200);

std::vector<std::vector<cv::Point>> contours;
cv::findContours(edges, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
cv::drawContours(img, contours, -1, cv::Scalar(0, 255, 0), 2);

findContours Parameters

cv::findContours() signature:


void findContours(InputOutputArray image, 
                  OutputArrayOfArrays contours,
                  OutputArray hierarchy,
                  int mode,
                  int method);

Notes:

drawContours and Visual Output

Use drawContours() to visualize contours. You can specify:


cv::drawContours(image, contours, -1, cv::Scalar(255, 0, 0), 2);

Contour Hierarchy

Hierarchy describes parent-child relationships between contours. It is returned as a vector with the format:

[Next, Previous, First_Child, Parent]


std::vector<cv::Vec4i> hierarchy;
cv::findContours(edges, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

Contour Properties and Shape Analysis

You can calculate properties using:


double peri = cv::arcLength(contours[i], true);
std::vector<cv::Point> approx;
cv::approxPolyDP(contours[i], approx, 0.02 * peri, true);
cv::Rect rect = cv::boundingRect(approx);

Advanced Techniques: Filtering and Matching

Contour Filtering: Filter by size, shape, or hierarchy:


for (size_t i = 0; i < contours.size(); i++) {
  double area = cv::contourArea(contours[i]);
  if (area > 1000) {
    cv::drawContours(image, contours, (int)i, cv::Scalar(0, 255, 0), 2);
  }
}

Shape Matching:


double match = cv::matchShapes(contour1, contour2, cv::CONTOURS_MATCH_I1, 0);

Conclusion

Contours provide a flexible foundation for many image processing tasks. Mastering their extraction and manipulation with OpenCV in C++ opens up advanced image analysis possibilities such as object recognition, measurement, tracking, and shape matching.