Comprehensive OpenCV (C++) Tutorial

1 Introduction & Version Landscape

Why OpenCV in Modern C++?

OpenCV (Open Source Computer Vision Library) is the de-facto standard for real-time computer-vision and image-processing tasks. A modern C++ (C++17/20) workflow gives you:

Current Releases

OpenCV 4.11.0 (18 Feb 2025) is the latest stable branch.​
OpenCV 5.x (alpha) is under active development—major API clean-ups, Apache-2 license, revamped dnn module, FP16 support, and universal intrinsics are planned.​

2 Installation & Build Pipeline

Using Package Managers (quick start)

# macOS + Homebrew
brew install opencv
 
# Ubuntu 22.04
sudo apt update && sudo apt install libopencv-dev python3-opencv

Custom CMake Build

Building from source lets you enable CUDA, OpenCL, or extra modules (e.g. opencv_contrib):

git clone --depth 1 https://github.com/opencv/opencv.git
git clone --depth 1 https://github.com/opencv/opencv_contrib.git

cmake -S opencv -B build \
      -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
      -DCMAKE_BUILD_TYPE=Release \
      -DWITH_CUDA=ON -DWITH_OPENCL=ON \
      -DBUILD_opencv_python3=OFF \
      -DCMAKE_INSTALL_PREFIX=/usr/local

cmake --build build -j$(nproc) 
sudo cmake --install build

Linking in Your Project

# CMakeLists.txt (C++17 example)
cmake_minimum_required(VERSION 3.16)
project(OpencvDemo LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)

find_package(OpenCV 4.5 REQUIRED)
add_executable(demo main.cpp)
target_link_libraries(demo PRIVATE opencv::opencv)

3 Core Data Structures

3.1 cv::Mat — the N-dimensional Matrix

  • Mat() Empty constructor (no allocation).
  • Mat(rows, cols, type[, Scalar value]) — allocate & optionally fill.
  • .at<T>(row,col) — element access with bounds check.
  • .reshape(), .clone(), .release() for shape manipulation & memory control.
// Create a 3×3 single-channel 8-bit matrix filled with 255
cv::Mat ones = cv::Mat::ones(3, 3, CV_8UC1) * 255;

3.2 Supporting Types

cv::Point<T> (2-D/3-D points),
cv::Size (width, height),
cv::Scalar (variadic pixel constants, e.g. B,G,R,A). These are shallow POD-like wrappers, trivially copyable.

4 Image I/O & Display

4.1 imread / imwrite

cv::Mat img = cv::imread("lena.png", cv::IMREAD_COLOR);
if(img.empty()) throw std::runtime_error("File not found");
cv::imwrite("copy.jpg", img);

4.2 GUI Helpers (imshow, waitKey)

cv::imshow("Preview", img);
cv::waitKey(0);   // block until key press

4.3 Video Streams

cv::VideoCapture cap(0);           // webcam
cv::VideoWriter  writer("out.mp4",
                        cv::VideoWriter::fourcc('a','v','c','1'),
                        30, cv::Size(640,480));

cv::Mat frame;
while(cap.read(frame)){
    writer.write(frame);
    cv::imshow("Live", frame);
    if(cv::waitKey(1)==27) break;  // Esc
}

5 Fundamental Image-Processing Operations

5.1 Color Conversions — cvtColor

cv::Mat gray;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

5.2 Resizing & Interpolation — resize

cv::Mat small;
cv::resize(img, small, cv::Size(), 0.5, 0.5, cv::INTER_AREA);

5.3 Filtering

  • GaussianBlur — low-pass, remove high-freq noise.
  • medianBlur — salt-and-pepper denoising.
  • bilateralFilter — edge-preserving smoothing.
cv::Mat blur;
cv::GaussianBlur(img, blur, cv::Size(5,5), 1.2);

5.4 Threshold & Edges

cv::Mat edges;
cv::Canny(gray, edges, 50, 150);

cv::Mat binary;
cv::threshold(gray, binary, 128, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

5.5 Morphology

auto kernel = cv::getStructuringElement(cv::MORPH_RECT, {3,3});
cv::Mat dilated;
cv::dilate(binary, dilated, kernel);

6 Geometric Transformations

6.1 Affine & Perspective Warp

cv::Point2f srcTri[3]{{0,0},{img.cols-1,0},{0,img.rows-1}};
cv::Point2f dstTri[3]{{0,0},{img.cols*0.8f,0},{img.cols*0.2f,img.rows*0.9f}};

auto M = cv::getAffineTransform(srcTri,dstTri);
cv::Mat warped;
cv::warpAffine(img, warped, M, img.size());

6.2 Rotation & Scaling

auto R = cv::getRotationMatrix2D({img.cols/2.f,img.rows/2.f}, 45, 1.0);
cv::warpAffine(img, warped, R, img.size());

7 Drawing & Annotation API

cv::Mat canvas = cv::Mat::zeros(400,600,CV_8UC3);
cv::rectangle(canvas, {50,50},{200,150}, {255,0,0}, 2);
cv::circle(canvas, {300,200}, 80, {0,255,0}, cv::FILLED);
cv::putText(canvas, "OpenCV!", {60,300},
            cv::FONT_HERSHEY_SIMPLEX, 1.2, {255,255,255}, 2);

8 Feature Detection, Description & Matching

8.1 ORB Detector

auto orb = cv::ORB::create(1000);
std::vector<cv::KeyPoint> kps1, kps2;
cv::Mat desc1, desc2;
orb->detectAndCompute(img1, cv::noArray(), kps1, desc1);
orb->detectAndCompute(img2, cv::noArray(), kps2, desc2);

cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector<cv::DMatch> matches;
matcher.match(desc1, desc2, matches);

8.2 SIFT/SURF (non-free licensing note)

Starting from OpenCV 4.4, SIFT’s patent expired—now fully in the main tree; simply use cv::SIFT::create().

9 Camera Calibration & 3-D Reconstruction

9.1 Chessboard Calibration

std::vector<cv::Point3f> objPts;
for(int i=0;i<9;i++)
  for(int j=0;j<6;j++)
    objPts.emplace_back(i*25.f, j*25.f, 0);   // 25 mm grid

std::vector<std::vector<cv::Point3f>> obj(1,objPts);
std::vector<std::vector<cv::Point2f>> img(1,imageCorners);

cv::Mat K, distCoeffs;
cv::calibrateCamera(obj, img, gray.size(), K, distCoeffs, cv::noArray(), cv::noArray());

9.2 Stereo Matching → Disparity Map

cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, 128, 5);
cv::Mat disparity16S;
sgbm->compute(leftGray, rightGray, disparity16S);
cv::Mat disp;
disparity16S.convertTo(disp, CV_32F, 1/16.0f);

10 Deep Neural Network (dnn) Module

10.1 Loading Pre-trained Models

auto net = cv::dnn::readNetFromONNX("yolov8n.onnx");
net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA_FP16);

10.2 Inference

cv::Mat blob = cv::dnn::blobFromImage(img, 1/255.0, {640,640},
                                      {0,0,0}, true, false);
net.setInput(blob);
auto outs = net.forward();   // returns cv::Mat

10.3 Post-processing Tips

  • Convert from NCHW to NHWC when needed via permute.
  • Use net.enableWinograd() for faster 3×3 conv (CPU).
  • Batch inference: stack blobs with cv::vconcat.

11 Performance & Deployment

11.1 Transparent API (T-API)

cv::UMat uimg;
img.copyTo(uimg);                 // lazy GPU upload
cv::GaussianBlur(uimg, uimg, {7,7}, 1.5);   // runs on GPU if available

11.2 G-API (Graph API)

Declarative data-flow graphs with lazy compilation; outperform imperative pipelines on heterogeneous targets.

11.3 Multi-threading

OpenCV uses OpenMP/TBB by default. You can wrap cv::parallel_for_ for custom loops.

12 Idiomatic C++ Tips & Best Practices

  • Favor cv::Mat move-semantics (no deep copy on assignment).
  • Use constexpr & enum class for flag sets.
  • Leverage std::filesystem for portable paths.
  • Combine OpenCV with fmt & spdlog for logging.
  • Benchmark with Google Benchmark; profile with opencv_perf.

13 Further Reading & Resources

  • Official docs & tutorials – docs.opencv.org
  • Advanced C++ book: Effective Modern C++ by Scott Meyers
  • CV/ML recipes – Learning OpenCV 4 (O’Reilly, 2020)
  • Runtimes: OpenVINO, TensorRT for high-speed inference
  • Community – #opencv Slack & Forum