# Camera Calibration
Source: https://opencv-opencv.mintlify.app/api/calib3d/calibration
Functions for calibrating monocular cameras, detecting calibration patterns, and estimating camera intrinsic parameters
## Overview
Camera calibration estimates intrinsic parameters (focal length, principal point, distortion coefficients) from multiple views of a calibration pattern. OpenCV supports chessboard and circular grid patterns.
## Core Functions
### calibrateCamera
Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern.
```cpp theme={null}
double cv::calibrateCamera(
InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)
)
```
Vector of vectors of calibration pattern points in the calibration pattern coordinate space (e.g. `std::vector>`). The outer vector contains as many elements as pattern views. For planar patterns, Z-coordinate is 0.
Vector of vectors of the projections of calibration pattern points (e.g. `std::vector>`). Must match the size of objectPoints.
Size of the image used only to initialize the camera intrinsic matrix.
Input/output 3x3 floating-point camera intrinsic matrix. If `CALIB_USE_INTRINSIC_GUESS` is specified, some or all of fx, fy, cx, cy must be initialized before calling.
Input/output vector of distortion coefficients `(k1, k2, p1, p2[, k3[, k4, k5, k6[, s1, s2, s3, s4[, τx, τy]]]])`.
Output vector of rotation vectors (Rodrigues) estimated for each pattern view. Each rotation vector brings the calibration pattern from object coordinate space to camera coordinate space.
Output vector of translation vectors estimated for each pattern view.
Different flags for calibration behavior (see Calibration Flags below).
Termination criteria for the iterative optimization algorithm.
**Returns:** The overall RMS re-projection error.
The algorithm is based on Zhang2000. It performs:
1. Compute initial intrinsic parameters (for planar patterns) or read from input
2. Estimate initial camera pose using solvePnP
3. Run global Levenberg-Marquardt optimization to minimize reprojection error
### Extended Version
```cpp theme={null}
double cv::calibrateCamera(
InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray stdDeviationsIntrinsics,
OutputArray stdDeviationsExtrinsics,
OutputArray perViewErrors,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)
)
```
Extended version provides additional outputs:
Output vector of standard deviations estimated for intrinsic parameters. Order: `(fx, fy, cx, cy, k1, k2, p1, p2, k3, k4, k5, k6, s1, s2, s3, s4, τx, τy)`
Output vector of standard deviations estimated for extrinsic parameters. Order: `(R0, T0, ..., R_{M-1}, T_{M-1})` where M is the number of pattern views.
Output vector of the RMS re-projection error estimated for each pattern view.
## Calibration Flags
Flags control which parameters are estimated or fixed during calibration:
| Flag | Value | Description |
| --------------------------- | --------- | --------------------------------------------------------------------- |
| `CALIB_USE_INTRINSIC_GUESS` | 0x00001 | cameraMatrix contains valid initial values that are optimized further |
| `CALIB_FIX_PRINCIPAL_POINT` | 0x00004 | Principal point is not changed during optimization |
| `CALIB_FIX_ASPECT_RATIO` | 0x00002 | Only fy is estimated, ratio fx/fy stays same as input |
| `CALIB_ZERO_TANGENT_DIST` | 0x00008 | Tangential distortion coefficients (p1, p2) are set to zero |
| `CALIB_FIX_FOCAL_LENGTH` | 0x00010 | Focal length is not changed (requires `CALIB_USE_INTRINSIC_GUESS`) |
| `CALIB_FIX_K1` | 0x00020 | k1 distortion coefficient is not changed |
| `CALIB_FIX_K2` | 0x00040 | k2 distortion coefficient is not changed |
| `CALIB_FIX_K3` | 0x00080 | k3 distortion coefficient is not changed |
| `CALIB_FIX_K4` | 0x00800 | k4 distortion coefficient is not changed |
| `CALIB_FIX_K5` | 0x01000 | k5 distortion coefficient is not changed |
| `CALIB_FIX_K6` | 0x02000 | k6 distortion coefficient is not changed |
| `CALIB_RATIONAL_MODEL` | 0x04000 | Enable k4, k5, k6 coefficients (8+ coefficients) |
| `CALIB_THIN_PRISM_MODEL` | 0x08000 | Enable s1, s2, s3, s4 coefficients (12+ coefficients) |
| `CALIB_FIX_S1_S2_S3_S4` | 0x10000 | Thin prism distortion coefficients are not changed |
| `CALIB_TILTED_MODEL` | 0x40000 | Enable tauX and tauY coefficients (14 coefficients) |
| `CALIB_FIX_TAUX_TAUY` | 0x80000 | Tilted sensor model coefficients are not changed |
| `CALIB_USE_QR` | 0x100000 | Use QR instead of SVD decomposition (faster but less precise) |
| `CALIB_FIX_TANGENT_DIST` | 0x200000 | Fix tangential distortion coefficients |
| `CALIB_USE_LU` | 1 \<\< 17 | Use LU instead of SVD decomposition (much faster but less precise) |
## Pattern Detection
### findChessboardCorners
Finds the positions of internal corners of the chessboard.
```cpp theme={null}
bool cv::findChessboardCorners(
InputArray image,
Size patternSize,
OutputArray corners,
int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
)
```
Source chessboard view. Must be an 8-bit grayscale or color image.
Number of inner corners per chessboard row and column: `Size(points_per_row, points_per_column)` = `Size(columns, rows)`. For an 8x8 chessboard, use `Size(7, 7)`.
Output array of detected corners.
Operation flags:
* `CALIB_CB_ADAPTIVE_THRESH` (1): Use adaptive thresholding
* `CALIB_CB_NORMALIZE_IMAGE` (2): Normalize image gamma with equalizeHist
* `CALIB_CB_FILTER_QUADS` (4): Use additional criteria to filter false quads
* `CALIB_CB_FAST_CHECK` (8): Run fast check for chessboard corners
* `CALIB_CB_PLAIN` (256): Take image as-is without processing
**Returns:** Non-zero if all corners are found and placed in order (row by row, left to right), otherwise 0.
The function requires white space (like a square-thick border) around the board to make detection more robust. Without borders, the outer black squares cannot be segmented properly.
**Example:**
```cpp theme={null}
Size patternsize(8, 6); // interior number of corners
Mat gray = ...; // source image
vector corners;
bool patternfound = findChessboardCorners(gray, patternsize, corners,
CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
if(patternfound)
cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(img, patternsize, Mat(corners), patternfound);
```
### findChessboardCornersSB
Finds chessboard corners using a sector-based approach (more accurate and robust).
```cpp theme={null}
bool cv::findChessboardCornersSB(
InputArray image,
Size patternSize,
OutputArray corners,
int flags = 0
)
```
Operation flags:
* `CALIB_CB_NORMALIZE_IMAGE` (2): Normalize image gamma
* `CALIB_CB_EXHAUSTIVE` (16): Run exhaustive search to improve detection rate
* `CALIB_CB_ACCURACY` (32): Upsample input image for better sub-pixel accuracy
* `CALIB_CB_LARGER` (64): Allow detected pattern to be larger than patternSize
* `CALIB_CB_MARKER` (128): Pattern must have a marker (for consistent coordinate system)
This method uses a localized Radon transformation and is:
* More robust to noise
* Faster on larger images
* Returns more accurate sub-pixel positions than cornerSubPix
Based on the paper "Accurate Detection and Localization of Checkerboard Corners for Calibration" (Duda 2018).
### drawChessboardCorners
Renders the detected chessboard corners.
```cpp theme={null}
void cv::drawChessboardCorners(
InputOutputArray image,
Size patternSize,
InputArray corners,
bool patternWasFound
)
```
Destination image. Must be an 8-bit color image.
Number of inner corners per chessboard row and column.
Array of detected corners from findChessboardCorners.
Parameter indicating whether the complete board was found. Pass the return value of findChessboardCorners.
Draws individual corners as red circles (if board not found) or as colored corners connected with lines (if board found).
## Helper Functions
### initCameraMatrix2D
Finds an initial camera intrinsic matrix from 3D-2D point correspondences.
```cpp theme={null}
Mat cv::initCameraMatrix2D(
InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
double aspectRatio = 1.0
)
```
If zero or negative, both fx and fy are estimated independently. Otherwise, fx = fy \* aspectRatio.
**Returns:** Initial camera intrinsic matrix for calibration process.
Currently only supports planar calibration patterns (Z-coordinate = 0).
### calibrationMatrixValues
Computes useful camera characteristics from the camera intrinsic matrix.
```cpp theme={null}
void cv::calibrationMatrixValues(
InputArray cameraMatrix,
Size imageSize,
double apertureWidth,
double apertureHeight,
CV_OUT double& fovx,
CV_OUT double& fovy,
CV_OUT double& focalLength,
CV_OUT Point2d& principalPoint,
CV_OUT double& aspectRatio
)
```
Physical width of the sensor in mm.
Physical height of the sensor in mm.
Output field of view in degrees along horizontal sensor axis.
Output field of view in degrees along vertical sensor axis.
Focal length of the lens in mm.
Principal point in mm.
fy/fx ratio.
## Advanced Calibration
### calibrateCameraRO
Calibrates camera using the releasing object method for improved precision.
```cpp theme={null}
double cv::calibrateCameraRO(
InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints,
Size imageSize,
int iFixedPoint,
InputOutputArray cameraMatrix,
InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray newObjPoints,
int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)
)
```
Index of the 3D object point in objectPoints\[0] to be fixed. Range \[1, objectPoints\[0].size()-2] enables object-releasing method. Values outside this range use standard calibration.
Updated output vector of calibration pattern points with potentially scaled coordinates.
This method can dramatically improve precision for inaccurate, unmeasured, roughly planar targets. Requires identical calibration board fully visible in all views.
Calibration time may be much longer with this method. Use CALIB\_USE\_QR or CALIB\_USE\_LU for faster calibration.
## See Also
* [Pose Estimation](/api/calib3d/pose-estimation) - solvePnP, solvePnPRansac for estimating camera pose
* [Stereo Calibration](/api/calib3d/stereo) - stereoCalibrate for calibrating stereo camera systems
* OpenCV samples: `calibration.cpp`, `3calibration.cpp`
# Pose Estimation
Source: https://opencv-opencv.mintlify.app/api/calib3d/pose-estimation
Functions for estimating camera pose from 3D-2D point correspondences using PnP (Perspective-n-Point) algorithms
## Overview
Pose estimation determines the transformation (rotation and translation) from the object coordinate system to the camera coordinate system. This is essential for:
* Augmented reality applications
* Robot navigation and manipulation
* 3D scene reconstruction
* Object tracking and localization
## Core Functions
### solvePnP
Finds an object pose from 3D-2D point correspondences.
```cpp theme={null}
bool cv::solvePnP(
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
bool useExtrinsicGuess = false,
int flags = SOLVEPNP_ITERATIVE
)
```
Array of object points in the object coordinate space, Nx3 1-channel or 1xN/Nx1 3-channel, where N is the number of points. `vector` can also be passed.
Array of corresponding image points in pixel coordinates, Nx2 1-channel or 1xN/Nx1 2-channel. `vector` can also be passed.
Input camera intrinsic matrix (3x3).
Input vector of distortion coefficients. If the vector is NULL/empty, zero distortion coefficients are assumed.
Output rotation vector (see Rodrigues) that, together with tvec, brings points from the model coordinate system to the camera coordinate system.
Output translation vector.
If true, the function uses the provided rvec and tvec values as initial approximations and further optimizes them (used with SOLVEPNP\_ITERATIVE).
Method for solving the PnP problem (see SolvePnP Methods below).
**Returns:** True if a solution is found, false otherwise.
**Coordinate Systems:**
* Input objectPoints: 3D points in **world coordinate frame**
* Output rvec/tvec: Transformation from world to **camera coordinate frame**
* The transformation `Xc = R * Xw + t` brings world points to camera coordinates
### SolvePnP Methods
| Method | Value | Description | Requirements |
| ---------------------- | ----- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `SOLVEPNP_ITERATIVE` | 0 | Levenberg-Marquardt optimization. DLT for non-planar (≥6 pts), homography for planar (≥4 pts) | ≥4 points |
| `SOLVEPNP_EPNP` | 1 | Efficient PnP based on Lepetit et al. 2009 | ≥4 points |
| `SOLVEPNP_P3P` | 2 | P3P algorithm based on Ding et al. 2023 | Exactly 4 points (3 for estimation, 1 for validation) |
| `SOLVEPNP_DLS` | 3 | **Broken - fallback to EPnP** | Not recommended |
| `SOLVEPNP_UPNP` | 4 | **Broken - fallback to EPnP** | Not recommended |
| `SOLVEPNP_AP3P` | 5 | Efficient algebraic solution by Ke & Roumeliotis 2017 | Exactly 4 points |
| `SOLVEPNP_IPPE` | 6 | Infinitesimal Plane-Based Pose Estimation | ≥4 coplanar points |
| `SOLVEPNP_IPPE_SQUARE` | 7 | IPPE for square markers (returns 2 solutions) | Exactly 4 coplanar points in specific order |
| `SOLVEPNP_SQPNP` | 8 | SQPnP: Fast and globally optimal solution | ≥3 points |
For SOLVEPNP\_IPPE\_SQUARE, object points must be defined in this exact order:
* point 0: `[-squareLength/2, squareLength/2, 0]`
* point 1: `[ squareLength/2, squareLength/2, 0]`
* point 2: `[ squareLength/2, -squareLength/2, 0]`
* point 3: `[-squareLength/2, -squareLength/2, 0]`
**Example:**
```cpp theme={null}
// Define object points (e.g., 3D corners of a marker)
vector objectPoints = {
{-0.05f, 0.05f, 0.0f},
{ 0.05f, 0.05f, 0.0f},
{ 0.05f, -0.05f, 0.0f},
{-0.05f, -0.05f, 0.0f}
};
// Corresponding 2D image points (detected in image)
vector imagePoints = {
{234.5f, 156.3f},
{456.2f, 167.8f},
{443.1f, 389.4f},
{221.7f, 378.9f}
};
Mat cameraMatrix = ...; // 3x3 camera intrinsic matrix
Mat distCoeffs = ...; // Distortion coefficients
Mat rvec, tvec;
bool success = solvePnP(objectPoints, imagePoints,
cameraMatrix, distCoeffs,
rvec, tvec, false, SOLVEPNP_IPPE_SQUARE);
```
### solvePnPRansac
Finds object pose from 3D-2D point correspondences using RANSAC to handle outliers.
```cpp theme={null}
bool cv::solvePnPRansac(
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
bool useExtrinsicGuess = false,
int iterationsCount = 100,
float reprojectionError = 8.0,
double confidence = 0.99,
OutputArray inliers = noArray(),
int flags = SOLVEPNP_ITERATIVE
)
```
Number of RANSAC iterations.
Inlier threshold value in pixels. The maximum allowed distance between observed and computed point projections to consider it an inlier.
The probability that the algorithm produces a useful result (typically 0.99).
Output vector that contains indices of inliers in objectPoints and imagePoints.
**Returns:** True if a solution is found.
This function estimates an object pose and is resistant to outliers using RANSAC. The algorithm:
1. Randomly selects minimal subsets of points
2. Estimates pose for each subset
3. Counts inliers (points within reprojectionError threshold)
4. Refines final pose using all inliers
**Minimal Sample Sets:**
* Default method uses SOLVEPNP\_EPNP for minimal sample estimation
* If you choose SOLVEPNP\_P3P or SOLVEPNP\_AP3P, these methods are used
* If exactly 4 input points, SOLVEPNP\_P3P is automatically used
* Final pose is refined using all inliers with the method specified in flags (unless P3P/AP3P, then EPNP is used)
### USAC-based solvePnPRansac
Advanced robust estimation using USAC (Universal RANSAC) framework.
```cpp theme={null}
bool cv::solvePnPRansac(
InputArray objectPoints,
InputArray imagePoints,
InputOutputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
OutputArray inliers,
const UsacParams& params = UsacParams()
)
```
USAC provides several advanced RANSAC variants with configurable parameters for better performance and accuracy.
### solvePnPGeneric
Returns all possible solutions for pose estimation (multiple solutions from P3P methods).
```cpp theme={null}
int cv::solvePnPGeneric(
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
bool useExtrinsicGuess = false,
SolvePnPMethod flags = SOLVEPNP_ITERATIVE,
InputArray rvec = noArray(),
InputArray tvec = noArray(),
OutputArray reprojectionError = noArray()
)
```
Vector of output rotation vectors. P3P methods return 0-4 solutions, SOLVEPNP\_IPPE returns 2 solutions, others return 1 solution.
Vector of output translation vectors corresponding to rvecs.
Optional output array of reprojection error (RMSE) for each solution.
**Returns:** Number of solutions found.
P3P solutions are sorted by reprojection errors (lowest to highest).
### solveP3P
Finds an object pose from 3 3D-2D point correspondences.
```cpp theme={null}
int cv::solveP3P(
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
int flags
)
```
Array of object points, 3x3 1-channel or 1x3/3x1 3-channel. Exactly 3 points required.
Array of corresponding image points, 3x2 1-channel or 1x3/3x1 2-channel. Exactly 3 points required.
Method for solving P3P:
* `SOLVEPNP_P3P`: Based on Ding et al. 2023
* `SOLVEPNP_AP3P`: Based on Ke & Roumeliotis 2017
**Returns:** Number of solutions (0-4). Solutions are sorted by reprojection errors.
## Pose Refinement
### solvePnPRefineLM
Refines a pose using Levenberg-Marquardt optimization.
```cpp theme={null}
void cv::solvePnPRefineLM(
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
InputOutputArray rvec,
InputOutputArray tvec,
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 20, FLT_EPSILON)
)
```
Input/Output rotation vector. Input values used as initial solution.
Input/Output translation vector. Input values used as initial solution.
Termination criteria for the iterative optimization algorithm.
Minimizes projection error using Levenberg-Marquardt iterative minimization. Requires at least 3 object points and an initial pose estimate.
### solvePnPRefineVVS
Refines a pose using Virtual Visual Servoing (VVS).
```cpp theme={null}
void cv::solvePnPRefineVVS(
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
InputOutputArray rvec,
InputOutputArray tvec,
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 20, FLT_EPSILON),
double VVSlambda = 1
)
```
Gain for the virtual visual servoing control law, equivalent to the α gain in the Damped Gauss-Newton formulation.
Minimizes projection error using Virtual Visual Servoing scheme (Chaumette 2006, Marchand 2016).
## Homography-Based Methods
### findHomography
Finds a perspective transformation between two planes.
```cpp theme={null}
Mat cv::findHomography(
InputArray srcPoints,
InputArray dstPoints,
int method = 0,
double ransacReprojThreshold = 3,
OutputArray mask = noArray(),
const int maxIters = 2000,
const double confidence = 0.995
)
```
Coordinates of points in the original plane, CV\_32FC2 or `vector`.
Coordinates of points in the target plane, CV\_32FC2 or `vector`.
Method for computing homography:
* 0: Regular method using all points (least squares)
* `RANSAC` (8): RANSAC-based robust method
* `LMEDS` (4): Least-Median robust method
* `RHO` (16): PROSAC-based robust method
Maximum allowed reprojection error to treat a point pair as an inlier (pixels). Used in RANSAC and RHO methods.
Optional output mask set by robust methods. Input mask values are ignored.
Maximum number of RANSAC iterations.
Confidence level, between 0 and 1.
**Returns:** The 3x3 homography matrix H such that:
```
s_i [x'_i, y'_i, 1]^T ≈ H [x_i, y_i, 1]^T
```
The function finds the perspective transformation between source and destination planes. Useful for:
* Finding initial intrinsic and extrinsic matrices
* Planar object tracking
* Image rectification
If H cannot be estimated, an empty matrix is returned.
### USAC-based findHomography
```cpp theme={null}
Mat cv::findHomography(
InputArray srcPoints,
InputArray dstPoints,
OutputArray mask,
const UsacParams& params
)
```
Uses USAC framework for robust homography estimation with configurable parameters.
## Decomposition Methods
### decomposeProjectionMatrix
Decomposes a projection matrix into rotation matrix and camera intrinsic matrix.
```cpp theme={null}
void cv::decomposeProjectionMatrix(
InputArray projMatrix,
OutputArray cameraMatrix,
OutputArray rotMatrix,
OutputArray transVect,
OutputArray rotMatrixX = noArray(),
OutputArray rotMatrixY = noArray(),
OutputArray rotMatrixZ = noArray(),
OutputArray eulerAngles = noArray()
)
```
3x4 input projection matrix P.
Output 3x3 camera intrinsic matrix.
Output 3x3 external rotation matrix R.
Output 4x1 translation vector T.
Optional 3x3 rotation matrix around x-axis.
Optional 3x3 rotation matrix around y-axis.
Optional 3x3 rotation matrix around z-axis.
Optional three-element vector containing three Euler angles of rotation in degrees.
Decomposes a projection matrix into calibration and rotation matrix and the position of a camera. Based on RQDecomp3x3.
### RQDecomp3x3
Computes an RQ decomposition of 3x3 matrices.
```cpp theme={null}
Vec3d cv::RQDecomp3x3(
InputArray src,
OutputArray mtxR,
OutputArray mtxQ,
OutputArray Qx = noArray(),
OutputArray Qy = noArray(),
OutputArray Qz = noArray()
)
```
3x3 input matrix.
Output 3x3 upper-triangular matrix.
Output 3x3 orthogonal matrix.
**Returns:** Three Euler angles in degrees.
Used in decomposeProjectionMatrix to decompose the left 3x3 submatrix of a projection matrix.
## Helper Functions
### projectPoints
Projects 3D points to an image plane.
```cpp theme={null}
void cv::projectPoints(
InputArray objectPoints,
InputArray rvec,
InputArray tvec,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray imagePoints,
OutputArray jacobian = noArray(),
double aspectRatio = 0
)
```
Array of object points in world coordinate frame, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel.
Rotation vector (Rodrigues) that performs change of basis from world to camera coordinate system.
Translation vector.
Output array of image points in **pixel coordinates**, 1xN/Nx1 2-channel, or `vector`.
Optional output 2Nx(10+numDistCoeffs) Jacobian matrix of derivatives of image points with respect to rotation, translation, focal lengths, principal point, and distortion coefficients.
Optional fixed aspect ratio parameter. If not 0, the function assumes aspect ratio (fx/fy) is fixed.
Computes 2D projections of 3D points given intrinsic and extrinsic camera parameters. Used during optimization in calibrateCamera, solvePnP, and stereoCalibrate.
### drawFrameAxes
Draws axes of the world/object coordinate system from pose estimation.
```cpp theme={null}
void cv::drawFrameAxes(
InputOutputArray image,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray rvec,
InputArray tvec,
float length,
int thickness = 3
)
```
Length of the painted axes in the same unit as tvec (usually meters).
Line thickness of the painted axes.
Draws the world/object coordinate system axes w\.r.t. the camera frame:
* OX is drawn in red
* OY is drawn in green
* OZ is drawn in blue
## See Also
* [Camera Calibration](/api/calib3d/calibration) - calibrateCamera for obtaining camera intrinsics
* [Stereo Vision](/api/calib3d/stereo) - Stereo calibration and rectification
* OpenCV samples: `plane_ar.py` (planar augmented reality)
# Stereo Vision
Source: https://opencv-opencv.mintlify.app/api/calib3d/stereo
Functions for stereo camera calibration, rectification, and depth computation from stereo image pairs
## Overview
Stereo vision uses two cameras to compute depth information by triangulation. OpenCV provides functions for:
* Calibrating stereo camera systems
* Computing rectification transformations
* Stereo correspondence algorithms (StereoBM, StereoSGBM)
* 3D reconstruction from disparity maps
## Stereo Calibration
### stereoCalibrate
Calibrates a stereo camera setup by finding intrinsic parameters for each camera and extrinsic parameters between them.
```cpp theme={null}
double cv::stereoCalibrate(
InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2,
InputOutputArray cameraMatrix1,
InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2,
InputOutputArray distCoeffs2,
Size imageSize,
OutputArray R,
OutputArray T,
OutputArray E,
OutputArray F,
int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, 1e-6)
)
```
Vector of vectors of calibration pattern points. Both cameras need to see the same object points. Structure same as calibrateCamera.
Vector of vectors of projections of calibration pattern points observed by the first camera.
Vector of vectors of projections of calibration pattern points observed by the second camera.
Input/output camera intrinsic matrix for the first camera.
Input/output vector of distortion coefficients for the first camera.
Input/output camera intrinsic matrix for the second camera.
Input/output vector of distortion coefficients for the second camera.
Size of the image used only to initialize camera intrinsic matrices.
Output rotation matrix between the first and second camera coordinate systems. This matrix brings points from the first camera's coordinate system to the second camera's coordinate system.
Output translation vector between the coordinate systems of the cameras. Equivalent to the position of the first camera with respect to the second camera.
Output essential matrix.
Output fundamental matrix.
Different flags for stereo calibration (see Stereo Calibration Flags below).
Termination criteria for the iterative optimization algorithm.
**Returns:** The overall RMS re-projection error.
The function estimates the transformation between two cameras:
```
R2 = R * R1
T2 = R * T1 + T
```
Optionally computes the essential matrix E:
```
E = [T]_x * R
```
where `[T]_x` is the skew-symmetric matrix of T.
And the fundamental matrix F:
```
F = cameraMatrix2^(-T) * E * cameraMatrix1^(-1)
```
Due to high dimensionality and noise, the function can diverge. If intrinsic parameters can be estimated with high accuracy for each camera individually (using calibrateCamera), it's recommended to pass CALIB\_FIX\_INTRINSIC flag with the computed intrinsic parameters.
### Extended Version
```cpp theme={null}
double cv::stereoCalibrate(
InputArrayOfArrays objectPoints,
InputArrayOfArrays imagePoints1,
InputArrayOfArrays imagePoints2,
InputOutputArray cameraMatrix1,
InputOutputArray distCoeffs1,
InputOutputArray cameraMatrix2,
InputOutputArray distCoeffs2,
Size imageSize,
InputOutputArray R,
InputOutputArray T,
OutputArray E,
OutputArray F,
OutputArrayOfArrays rvecs,
OutputArrayOfArrays tvecs,
OutputArray perViewErrors,
int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, 1e-6)
)
```
Output vector of rotation vectors (Rodrigues) estimated for each pattern view in the coordinate system of the first camera.
Output vector of translation vectors estimated for each pattern view.
Output vector of the RMS re-projection error estimated for each pattern view.
### Stereo Calibration Flags
Flags control the calibration behavior (in addition to single camera flags):
| Flag | Value | Description |
| --------------------------------- | --------- | --------------------------------------------------------------------------- |
| `CALIB_FIX_INTRINSIC` | 0x00100 | Fix cameraMatrix1/2 and distCoeffs1/2 so that only R, T, E, F are estimated |
| `CALIB_USE_INTRINSIC_GUESS` | 0x00001 | Optimize some or all intrinsic parameters according to specified flags |
| `CALIB_USE_EXTRINSIC_GUESS` | 1 \<\< 22 | R and T contain valid initial values that are optimized further |
| `CALIB_FIX_PRINCIPAL_POINT` | 0x00004 | Fix principal points during optimization |
| `CALIB_FIX_FOCAL_LENGTH` | 0x00010 | Fix fx and fy for both cameras |
| `CALIB_FIX_ASPECT_RATIO` | 0x00002 | Optimize fy, fix ratio fx/fy |
| `CALIB_SAME_FOCAL_LENGTH` | 0x00200 | Enforce fx^(0) = fx^(1) and fy^(0) = fy^(1) |
| `CALIB_ZERO_TANGENT_DIST` | 0x00008 | Set tangential distortion coefficients to zero for each camera |
| `CALIB_FIX_K1` ... `CALIB_FIX_K6` | Various | Do not change corresponding radial distortion coefficient |
| `CALIB_RATIONAL_MODEL` | 0x04000 | Enable k4, k5, k6 coefficients (8 coefficients total) |
| `CALIB_THIN_PRISM_MODEL` | 0x08000 | Enable s1, s2, s3, s4 coefficients (12 coefficients total) |
| `CALIB_FIX_S1_S2_S3_S4` | 0x10000 | Thin prism distortion coefficients are not changed |
| `CALIB_TILTED_MODEL` | 0x40000 | Enable tauX and tauY coefficients (14 coefficients) |
| `CALIB_FIX_TAUX_TAUY` | 0x80000 | Tilted sensor model coefficients are not changed |
It's usually reasonable to restrict some parameters, e.g., pass CALIB\_SAME\_FOCAL\_LENGTH and CALIB\_ZERO\_TANGENT\_DIST flags.
## Stereo Rectification
### stereoRectify
Computes rectification transforms for each head of a calibrated stereo camera.
```cpp theme={null}
void cv::stereoRectify(
InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
Size imageSize,
InputArray R,
InputArray T,
OutputArray R1,
OutputArray R2,
OutputArray P1,
OutputArray P2,
OutputArray Q,
int flags = CALIB_ZERO_DISPARITY,
double alpha = -1,
Size newImageSize = Size(),
CV_OUT Rect* validPixROI1 = 0,
CV_OUT Rect* validPixROI2 = 0
)
```
First camera intrinsic matrix.
First camera distortion parameters.
Second camera intrinsic matrix.
Second camera distortion parameters.
Size of the image used for stereo calibration.
Rotation matrix from the coordinate system of the first camera to the second camera (from stereoCalibrate).
Translation vector from the coordinate system of the first camera to the second camera (from stereoCalibrate).
Output 3x3 rectification transform (rotation matrix) for the first camera. Performs change of basis from unrectified to rectified first camera's coordinate system.
Output 3x3 rectification transform (rotation matrix) for the second camera.
Output 3x4 projection matrix in the new (rectified) coordinate systems for the first camera. Projects points given in the rectified first camera coordinate system into the rectified first camera's image.
Output 3x4 projection matrix in the new (rectified) coordinate systems for the second camera.
Output 4x4 disparity-to-depth mapping matrix (see reprojectImageTo3D).
Operation flags:
* `CALIB_ZERO_DISPARITY` (0x00400): Makes principal points of each camera have the same pixel coordinates in rectified views
Free scaling parameter between 0 and 1:
* `alpha=0`: Rectified images are zoomed and shifted so only valid pixels are visible (no black areas)
* `alpha=1`: Rectified images are decimated and shifted so all pixels from original images are retained
* `-1`: Default scaling
New image resolution after rectification. When (0,0), it's set to the original imageSize. Setting to larger value helps preserve details.
Optional output rectangle inside the rectified first image where all pixels are valid.
Optional output rectangle inside the rectified second image where all pixels are valid.
The function computes rotation matrices for each camera that make both camera image planes the same plane. This makes all epipolar lines parallel, simplifying dense stereo correspondence.
**Horizontal Stereo:**
For cameras shifted mainly along x-axis, the projection matrices are:
```
P1 = [f 0 cx1 0 ]
[0 f cy 0 ]
[0 0 1 0 ]
P2 = [f 0 cx2 Tx*f]
[0 f cy 0 ]
[0 0 1 0 ]
Q = [1 0 0 -cx1 ]
[0 1 0 -cy ]
[0 0 0 f ]
[0 0 -1/Tx (cx1-cx2)/Tx]
```
where Tx is horizontal shift between cameras and cx1=cx2 if CALIB\_ZERO\_DISPARITY is set.
**Vertical Stereo:**
For cameras shifted mainly along y-axis:
```
P1 = [f 0 cx 0 ]
[0 f cy1 0 ]
[0 0 1 0 ]
P2 = [f 0 cx 0 ]
[0 f cy2 Ty*f]
[0 0 1 0 ]
Q = [1 0 0 -cx ]
[0 1 0 -cy1 ]
[0 0 0 f ]
[0 0 -1/Ty (cy1-cy2)/Ty]
```
The first three columns of P1 and P2 are the new "rectified" camera matrices. Pass these with R1 and R2 to initUndistortRectifyMap to initialize rectification maps.
### stereoRectifyUncalibrated
Computes a rectification transform for an uncalibrated stereo camera.
```cpp theme={null}
bool cv::stereoRectifyUncalibrated(
InputArray points1,
InputArray points2,
InputArray F,
Size imgSize,
OutputArray H1,
OutputArray H2,
double threshold = 5
)
```
Array of feature points in the first image.
Corresponding points in the second image.
Input fundamental matrix. Can be computed from the same point pairs using findFundamentalMat.
Size of the image.
Output rectification homography matrix for the first image.
Output rectification homography matrix for the second image.
Optional threshold to filter outliers. If >0, point pairs not complying with epipolar geometry are rejected. Otherwise all points are considered inliers.
Computes rectification transformations without knowing intrinsic parameters. Implements the algorithm from Hartley99.
Algorithm heavily depends on epipolar geometry. If camera lenses have significant distortion, correct it before computing fundamental matrix and calling this function.
## Utility Functions
### getOptimalNewCameraMatrix
Returns the new camera intrinsic matrix based on the free scaling parameter.
```cpp theme={null}
Mat cv::getOptimalNewCameraMatrix(
InputArray cameraMatrix,
InputArray distCoeffs,
Size imageSize,
double alpha,
Size newImgSize = Size(),
CV_OUT Rect* validPixROI = 0,
bool centerPrincipalPoint = false
)
```
Input camera intrinsic matrix.
Input vector of distortion coefficients. If NULL/empty, zero distortion is assumed.
Original image size.
Free scaling parameter between 0 (only valid pixels) and 1 (retain all source pixels). See stereoRectify for details.
Image size after rectification. By default, set to imageSize.
Optional output rectangle outlining all-good-pixels region in undistorted image.
Optional flag indicating whether the principal point should be at image center or chosen to best fit source image (determined by alpha).
**Returns:** New camera intrinsic matrix.
By varying alpha parameter, you can retrieve only sensible pixels (alpha=0), keep all original pixels (alpha=1), or get something in between. When alpha>0, undistorted result likely has black pixels corresponding to "virtual" pixels outside captured distorted image.
### rectify3Collinear
Computes rectification transforms for 3-head camera where all heads are on the same line.
```cpp theme={null}
float cv::rectify3Collinear(
InputArray cameraMatrix1,
InputArray distCoeffs1,
InputArray cameraMatrix2,
InputArray distCoeffs2,
InputArray cameraMatrix3,
InputArray distCoeffs3,
InputArrayOfArrays imgpt1,
InputArrayOfArrays imgpt3,
Size imageSize,
InputArray R12,
InputArray T12,
InputArray R13,
InputArray T13,
OutputArray R1,
OutputArray R2,
OutputArray R3,
OutputArray P1,
OutputArray P2,
OutputArray P3,
OutputArray Q,
double alpha,
Size newImgSize,
CV_OUT Rect* roi1,
CV_OUT Rect* roi2,
int flags
)
```
Computes rectification transformations for tri-focal stereo camera systems with collinear arrangement.
## Stereo Matching Classes
### StereoBM
Class for computing stereo correspondence using the block matching algorithm.
```cpp theme={null}
class CV_EXPORTS_W StereoBM : public StereoMatcher
{
public:
static Ptr create(int numDisparities = 0, int blockSize = 21);
// Parameters
CV_WRAP virtual int getPreFilterType() const = 0;
CV_WRAP virtual void setPreFilterType(int preFilterType) = 0;
CV_WRAP virtual int getPreFilterSize() const = 0;
CV_WRAP virtual void setPreFilterSize(int preFilterSize) = 0;
CV_WRAP virtual int getPreFilterCap() const = 0;
CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
CV_WRAP virtual int getTextureThreshold() const = 0;
CV_WRAP virtual void setTextureThreshold(int textureThreshold) = 0;
CV_WRAP virtual int getUniquenessRatio() const = 0;
CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
CV_WRAP virtual int getSmallerBlockSize() const = 0;
CV_WRAP virtual void setSmallerBlockSize(int blockSize) = 0;
CV_WRAP virtual Rect getROI1() const = 0;
CV_WRAP virtual void setROI1(Rect roi1) = 0;
CV_WRAP virtual Rect getROI2() const = 0;
CV_WRAP virtual void setROI2(Rect roi2) = 0;
};
```
**Key Parameters:**
Maximum disparity minus minimum disparity. Must be divisible by 16. Typical value: 16, 32, 48, 64, etc.
Matched block size. Must be odd number ≥1. Typical values: 5-21. Larger blocks produce smoother but less detailed disparity maps.
Type of the prefilter:
* `PREFILTER_NORMALIZED_RESPONSE`: Normalized response
* `PREFILTER_XSOBEL`: Sobel prefilter
Prefilter window size (5-255, must be odd).
Truncation value for prefiltered image pixels (1-63).
Minimum texture for disparity computation. Areas with low texture are filtered out.
Margin in percentage by which best computed cost function value should "win" second best value. Typically 5-15.
**Example:**
```cpp theme={null}
Ptr stereo = StereoBM::create(64, 15);
stereo->setPreFilterCap(31);
stereo->setUniquenessRatio(10);
Mat disparity;
stereo->compute(leftImage, rightImage, disparity);
```
### StereoSGBM
Class for computing stereo correspondence using Semi-Global Block Matching algorithm.
```cpp theme={null}
class CV_EXPORTS_W StereoSGBM : public StereoMatcher
{
public:
enum {
MODE_SGBM = 0,
MODE_HH = 1,
MODE_SGBM_3WAY = 2,
MODE_HH4 = 3
};
static Ptr create(
int minDisparity = 0,
int numDisparities = 16,
int blockSize = 3,
int P1 = 0,
int P2 = 0,
int disp12MaxDiff = 0,
int preFilterCap = 0,
int uniquenessRatio = 0,
int speckleWindowSize = 0,
int speckleRange = 0,
int mode = MODE_SGBM
);
CV_WRAP virtual int getPreFilterCap() const = 0;
CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0;
CV_WRAP virtual int getUniquenessRatio() const = 0;
CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0;
CV_WRAP virtual int getP1() const = 0;
CV_WRAP virtual void setP1(int P1) = 0;
CV_WRAP virtual int getP2() const = 0;
CV_WRAP virtual void setP2(int P2) = 0;
CV_WRAP virtual int getMode() const = 0;
CV_WRAP virtual void setMode(int mode) = 0;
};
```
**Key Parameters:**
Minimum possible disparity value. Typically 0, but can be adjusted.
Maximum disparity minus minimum disparity. Must be divisible by 16. Values: 16, 32, 48, 64, 96, 128, etc.
Matched block size. Must be odd number ≥1. Values: 3, 5, 7, etc. SGBM works well with smaller blocks than BM.
First parameter controlling disparity smoothness. Penalty for disparity change by ±1. If 0, default is `8 * channels * blockSize^2`.
Second parameter controlling disparity smoothness. Penalty for disparity change by more than 1. If 0, default is `32 * channels * blockSize^2`. P2 > P1.
Maximum allowed difference in left-right disparity check. Set to negative value to disable check.
Truncation value for prefiltered image pixels. Default: 63.
Margin by which best cost function value should "win" second best. Typically 5-15.
Maximum size of smooth disparity regions to consider noise speckles and invalidate. Set to 0 to disable. Typical: 50-200.
Maximum disparity variation within connected component. Typical: 1-2.
Algorithm mode:
* `MODE_SGBM`: Standard Semi-Global Block Matching
* `MODE_HH`: Hirschmuller algorithm
* `MODE_SGBM_3WAY`: Modified SGBM
* `MODE_HH4`: Full-scale two-pass algorithm
SGBM produces smoother and more accurate disparity maps than BM but is computationally more expensive.
**Example:**
```cpp theme={null}
Ptr stereo = StereoSGBM::create(
0, // minDisparity
96, // numDisparities
5, // blockSize
600, // P1
2400, // P2
1, // disp12MaxDiff
63, // preFilterCap
10, // uniquenessRatio
100, // speckleWindowSize
32, // speckleRange
StereoSGBM::MODE_SGBM_3WAY
);
Mat disparity;
stereo->compute(leftImage, rightImage, disparity);
// Convert to float disparity
disparity.convertTo(disparity, CV_32F, 1.0/16.0);
```
SGBM is more suitable for real-time applications and produces better results than BM, especially in textured regions. Consider using MODE\_SGBM\_3WAY or MODE\_HH4 for best quality.
## See Also
* [Camera Calibration](/api/calib3d/calibration) - calibrateCamera for obtaining camera intrinsics
* [Pose Estimation](/api/calib3d/pose-estimation) - solvePnP for 3D-2D correspondences
* OpenCV samples: `stereo_calib.cpp`, `stereo_match.cpp`
# Mat Class
Source: https://opencv-opencv.mintlify.app/api/core/mat
N-dimensional dense array class for storing images, matrices, and multi-dimensional data
## Overview
The `Mat` class is the primary data structure in OpenCV for representing n-dimensional dense arrays. It can store real or complex-valued vectors, matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, and histograms.
## Constructors
### Default Constructor
```cpp theme={null}
Mat()
```
Creates an empty matrix with no allocated data.
### Size and Type Constructor
```cpp theme={null}
Mat(int rows, int cols, int type)
Mat(Size size, int type)
```
Number of rows in a 2D array
Number of columns in a 2D array
2D array size: Size(cols, rows)
Array type. Use CV\_8UC1, ..., CV\_64FC4 to create 1-4 channel matrices, or CV\_8UC(n), ..., CV\_64FC(n) to create multi-channel matrices (up to CV\_CN\_MAX channels)
**Example:**
```cpp theme={null}
// Create a 100x100 8-bit unsigned single-channel matrix
Mat img(100, 100, CV_8UC1);
// Create a 640x480 8-bit 3-channel color image
Mat colorImage(Size(640, 480), CV_8UC3);
```
### Constructor with Initialization
```cpp theme={null}
Mat(int rows, int cols, int type, const Scalar& s)
Mat(Size size, int type, const Scalar& s)
```
Optional value to initialize each matrix element with
**Example:**
```cpp theme={null}
// Create a 7x7 complex matrix filled with 1+3j
Mat M(7, 7, CV_32FC2, Scalar(1, 3));
// Create a 100x100 matrix filled with zeros
Mat zeros(100, 100, CV_64F, Scalar(0));
```
### Multi-dimensional Constructor
```cpp theme={null}
Mat(int ndims, const int* sizes, int type)
Mat(const std::vector& sizes, int type)
Mat(int ndims, const int* sizes, int type, const Scalar& s)
```
Array dimensionality
Array of integers specifying an n-dimensional array shape
**Example:**
```cpp theme={null}
// Create a 100x100x100 8-bit 3D array
int sz[] = {100, 100, 100};
Mat bigCube(3, sz, CV_8U, Scalar::all(0));
```
### User Data Constructor
```cpp theme={null}
Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
```
Pointer to user data. No data is copied; the matrix header points to the specified data
Number of bytes each matrix row occupies. If AUTO\_STEP, no padding is assumed
The external data is not automatically deallocated, so you should manage it manually.
### Copy Constructor
```cpp theme={null}
Mat(const Mat& m)
```
Creates a matrix header for the same data. This is an O(1) operation that does not copy data but increments the reference counter.
### ROI Constructors
```cpp theme={null}
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all())
Mat(const Mat& m, const Rect& roi)
Mat(const Mat& m, const Range* ranges)
```
Range of rows to take from the source matrix
Range of columns to take from the source matrix
Region of interest rectangle
**Example:**
```cpp theme={null}
Mat img(320, 240, CV_8UC3);
// Select a ROI
Mat roi(img, Rect(10, 10, 100, 100));
// Fill the ROI with green color
roi = Scalar(0, 255, 0);
```
## Key Methods
### create
```cpp theme={null}
void create(int rows, int cols, int type)
void create(Size size, int type)
void create(int ndims, const int* sizes, int type)
```
Allocates new array data if needed. If the array already has the specified size and type, the method does nothing.
### clone
```cpp theme={null}
Mat clone() const
```
Creates a full copy of the array and underlying data.
**Example:**
```cpp theme={null}
Mat A = Mat::eye(3, 3, CV_32F);
Mat B = A.clone(); // B is an independent copy
```
### copyTo
```cpp theme={null}
void copyTo(OutputArray m) const
void copyTo(OutputArray m, InputArray mask) const
```
Destination matrix. Reallocated if needed
Operation mask (8-bit single channel). Non-zero elements indicate which matrix elements to copy
### convertTo
```cpp theme={null}
void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const
```
Output matrix
Desired output matrix type or depth
Optional scale factor
Optional delta added to scaled values
Converts array to another data type with optional scaling: `m(x,y) = saturate_cast(alpha*(*this)(x,y) + beta)`
### row / col
```cpp theme={null}
Mat row(int y) const
Mat col(int x) const
```
Creates a matrix header for the specified matrix row or column. This is an O(1) operation.
0-based row index
0-based column index
**Example:**
```cpp theme={null}
// Add the 5-th row, multiplied by 3 to the 3rd row
M.row(3) = M.row(3) + M.row(5) * 3;
```
### rowRange / colRange
```cpp theme={null}
Mat rowRange(int startrow, int endrow) const
Mat rowRange(const Range& r) const
Mat colRange(int startcol, int endcol) const
Mat colRange(const Range& r) const
```
Creates a matrix header for the specified row or column span.
### diag
```cpp theme={null}
Mat diag(int d=0) const
static Mat diag(const Mat& d)
```
Index of the diagonal. d=0 is the main diagonal, d\<0 is below, d>0 is above
Extracts a diagonal from a matrix or creates a diagonal matrix.
### reshape
```cpp theme={null}
Mat reshape(int cn, int rows=0) const
Mat reshape(int cn, int newndims, const int* newsz) const
```
New number of channels. If 0, the number of channels remains unchanged
New number of rows. If 0, the number of rows remains unchanged
Changes the shape and/or number of channels without copying data.
### at
```cpp theme={null}
template _Tp& at(int i0, int i1)
template const _Tp& at(int i0, int i1) const
template _Tp& at(Point pt)
template _Tp& at(int i0, int i1, int i2)
```
Returns a reference to the specified array element.
**Example:**
```cpp theme={null}
Mat M(100, 100, CV_64F);
M.at(i, j) += 1.0;
Mat colorImage(480, 640, CV_8UC3);
Vec3b& pixel = colorImage.at(y, x);
pixel[0] = 255; // Blue channel
```
No bounds checking is performed in Release builds. Use with caution.
### ptr
```cpp theme={null}
template _Tp* ptr(int i0=0)
template const _Tp* ptr(int i0=0) const
```
Returns a pointer to the specified matrix row.
**Example:**
```cpp theme={null}
// Efficient row-wise processing
for(int i = 0; i < M.rows; i++)
{
const double* Mi = M.ptr(i);
for(int j = 0; j < M.cols; j++)
sum += std::max(Mi[j], 0.);
}
```
## Static Initialization Methods
### zeros
```cpp theme={null}
static Mat zeros(int rows, int cols, int type)
static Mat zeros(Size size, int type)
static Mat zeros(int ndims, const int* sz, int type)
```
Returns a zero array of the specified size and type.
**Example:**
```cpp theme={null}
Mat Z = Mat::zeros(3, 3, CV_32F);
```
### ones
```cpp theme={null}
static Mat ones(int rows, int cols, int type)
static Mat ones(Size size, int type)
static Mat ones(int ndims, const int* sz, int type)
```
Returns an array of all 1's of the specified size and type.
### eye
```cpp theme={null}
static Mat eye(int rows, int cols, int type)
static Mat eye(Size size, int type)
```
Returns an identity matrix of the specified size and type.
**Example:**
```cpp theme={null}
// Add identity matrix to M
M += Mat::eye(M.rows, M.cols, CV_64F);
```
## Properties
### Data Layout
Number of rows (for 2D arrays)
Number of columns (for 2D arrays)
Number of matrix dimensions (≥ 2)
Pointer to the data
Array of strides (step\[0] contains the full row length in bytes)
### Type Information
Returns the matrix element type (CV\_8UC1, CV\_32FC3, etc.)
Returns the depth of the matrix elements (CV\_8U, CV\_32F, etc.)
Returns the number of channels
Returns element size in bytes
Returns size of each element channel in bytes
### Size Information
Returns the matrix size (for 2D matrices)
Returns the total number of array elements
Returns true if the array has no elements
Returns true if the matrix is continuous (no gaps at the end of rows)
Returns true if the matrix is a submatrix of another matrix
## Operators
### Assignment
```cpp theme={null}
Mat& operator=(const Mat& m)
Mat& operator=(const MatExpr& expr)
```
Matrix assignment is an O(1) operation that copies the header and increments the reference counter.
### Element Access
```cpp theme={null}
template _Tp& operator()(int row, int col)
template _Tp& operator()(Point pt)
template _Tp& operator()(const int* idx)
```
Provides element access similar to at() method.
### Arithmetic Operators
Matrix arithmetic operators (+, -, \*, /) are supported through matrix expressions:
```cpp theme={null}
Mat A, B, C;
C = A + B; // Addition
C = A - B; // Subtraction
C = A * B; // Matrix multiplication
C = A / 2.0; // Scalar division
```
## Memory Management
Mat uses reference counting for automatic memory management. When no one references the data, it's automatically deallocated.
**Example:**
```cpp theme={null}
Mat A(100, 100, CV_32F);
Mat B = A; // B references the same data (O(1) operation)
Mat C = A.clone(); // C is an independent copy
// Manually release data before destructor
A.release();
```
## Data Layout
For a 2D array, element (i,j) address is computed as:
```
addr(M[i,j]) = M.data + M.step[0]*i + M.step[1]*j
```
Matrices are stored row-by-row, with `step[0]` being the row length in bytes.
The data is stored continuously if `isContinuous()` returns true, meaning there are no gaps between rows. This allows for more efficient processing.
# Array Operations
Source: https://opencv-opencv.mintlify.app/api/core/operations
Per-element operations, matrix arithmetic, and array manipulation functions
## Arithmetic Operations
### add
```cpp theme={null}
void add(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1)
```
Calculates the per-element sum of two arrays or an array and a scalar.
First input array or scalar
Second input array or scalar
Output array with the same size and number of channels as input arrays
Optional 8-bit single channel mask that specifies elements to be changed
Optional depth of the output array. Default is -1 (same as input)
**Formula:**
```
dst(I) = saturate(src1(I) + src2(I)) if mask(I) ≠ 0
```
**Example:**
```cpp theme={null}
Mat A(100, 100, CV_8UC1, Scalar(50));
Mat B(100, 100, CV_8UC1, Scalar(100));
Mat C;
add(A, B, C); // C = A + B
// Equivalent matrix expression
C = A + B;
```
Saturation is not applied when the output array has depth CV\_32S. You may get incorrect sign in case of overflow.
### subtract
```cpp theme={null}
void subtract(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1)
```
Calculates the per-element difference between two arrays or array and a scalar.
First input array or scalar
Second input array or scalar
Output array
Optional operation mask
Optional depth of the output array
**Formula:**
```
dst(I) = saturate(src1(I) - src2(I)) if mask(I) ≠ 0
```
**Example:**
```cpp theme={null}
Mat result;
subtract(imageA, imageB, result);
// Equivalent: result = imageA - imageB;
```
### multiply
```cpp theme={null}
void multiply(InputArray src1, InputArray src2, OutputArray dst,
double scale = 1, int dtype = -1)
```
Calculates the per-element scaled product of two arrays.
First input array
Second input array of the same size and type as src1
Output array
Optional scale factor
Optional depth of the output array
**Formula:**
```
dst(I) = saturate(scale · src1(I) · src2(I))
```
**Example:**
```cpp theme={null}
Mat A, B, C;
multiply(A, B, C, 2.5); // Element-wise multiplication with scaling
```
For matrix multiplication (not element-wise), use gemm() function.
### divide
```cpp theme={null}
void divide(InputArray src1, InputArray src2, OutputArray dst,
double scale = 1, int dtype = -1)
void divide(double scale, InputArray src2, OutputArray dst, int dtype = -1)
```
Performs per-element division of two arrays or a scalar by an array.
First input array (numerator)
Second input array (denominator)
Scalar factor
Output array
**Formula:**
```
dst(I) = saturate(src1(I) * scale / src2(I))
dst(I) = saturate(scale / src2(I)) // Second overload
```
**Example:**
```cpp theme={null}
Mat A, B, C;
divide(A, B, C); // Element-wise division
divide(255.0, B, C); // Scalar divided by array
```
For integer types, when src2(I) is zero, dst(I) will also be zero. For floating-point data, expect IEEE-754 behavior (NaN, Inf values).
### scaleAdd
```cpp theme={null}
void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst)
```
Calculates the sum of a scaled array and another array (SAXPY/DAXPY operation).
First input array
Scale factor for the first array
Second input array (same size and type as src1)
Output array
**Formula:**
```
dst(I) = scale · src1(I) + src2(I)
```
**Example:**
```cpp theme={null}
Mat A, B, C;
scaleAdd(A, 2.0, B, C); // C = 2*A + B
```
### addWeighted
```cpp theme={null}
void addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1)
```
Calculates the weighted sum of two arrays.
First input array
Weight of the first array elements
Second input array
Weight of the second array elements
Scalar added to each sum
Output array
**Formula:**
```
dst(I) = saturate(src1(I) · alpha + src2(I) · beta + gamma)
```
**Example:**
```cpp theme={null}
// Image blending
Mat img1, img2, blended;
addWeighted(img1, 0.7, img2, 0.3, 0.0, blended);
```
## Bitwise Operations
### bitwise\_and
```cpp theme={null}
void bitwise_and(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray())
```
Calculates per-element bit-wise conjunction of two arrays or array and a scalar.
First input array or scalar
Second input array or scalar
Output array
Optional operation mask
**Formula:**
```
dst(I) = src1(I) & src2(I) if mask(I) ≠ 0
```
### bitwise\_or
```cpp theme={null}
void bitwise_or(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray())
```
Calculates per-element bit-wise disjunction of two arrays or array and a scalar.
**Formula:**
```
dst(I) = src1(I) | src2(I) if mask(I) ≠ 0
```
### bitwise\_xor
```cpp theme={null}
void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray())
```
Calculates per-element bit-wise exclusive OR of two arrays or array and a scalar.
**Formula:**
```
dst(I) = src1(I) ^ src2(I) if mask(I) ≠ 0
```
### bitwise\_not
```cpp theme={null}
void bitwise_not(InputArray src, OutputArray dst, InputArray mask = noArray())
```
Inverts every bit of an array.
Input array
Output array
**Formula:**
```
dst(I) = ~src(I) if mask(I) ≠ 0
```
**Example:**
```cpp theme={null}
Mat mask, inverted_mask;
bitwise_not(mask, inverted_mask);
```
## Comparison Operations
### compare
```cpp theme={null}
void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop)
```
Performs per-element comparison of two arrays or array and scalar.
First input array or scalar
Second input array or scalar
Output array of type CV\_8U (0 or 255 values)
Comparison operation: CMP\_EQ, CMP\_GT, CMP\_GE, CMP\_LT, CMP\_LE, CMP\_NE
**Example:**
```cpp theme={null}
Mat A, B, mask;
compare(A, B, mask, CMP_GT); // mask = (A > B)
```
### min
```cpp theme={null}
void min(InputArray src1, InputArray src2, OutputArray dst)
```
Calculates per-element minimum of two arrays or array and scalar.
**Example:**
```cpp theme={null}
Mat A, B, C;
min(A, B, C); // C = min(A, B) element-wise
```
### max
```cpp theme={null}
void max(InputArray src1, InputArray src2, OutputArray dst)
```
Calculates per-element maximum of two arrays or array and scalar.
**Example:**
```cpp theme={null}
Mat A, B, C;
max(A, B, C); // C = max(A, B) element-wise
```
### inRange
```cpp theme={null}
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
```
Checks if array elements lie between two bounds.
Input array
Inclusive lower boundary array or scalar
Inclusive upper boundary array or scalar
Output array of type CV\_8U (0 or 255)
**Formula:**
```
dst(I) = 255 if lowerb(I) ≤ src(I) ≤ upperb(I), else 0
```
**Example:**
```cpp theme={null}
// Color segmentation
Mat hsv, mask;
cvtColor(image, hsv, COLOR_BGR2HSV);
inRange(hsv, Scalar(100, 50, 50), Scalar(130, 255, 255), mask);
```
## Mathematical Operations
### sqrt
```cpp theme={null}
void sqrt(InputArray src, OutputArray dst)
```
Calculates square root of array elements.
**Formula:**
```
dst(I) = √src(I)
```
### pow
```cpp theme={null}
void pow(InputArray src, double power, OutputArray dst)
```
Raises every array element to a power.
Input array
Exponent of power
Output array
**Formula:**
```
dst(I) = src(I)^power
```
**Example:**
```cpp theme={null}
Mat A, B;
pow(A, 2.0, B); // Square each element
```
### exp
```cpp theme={null}
void exp(InputArray src, OutputArray dst)
```
Calculates the exponent of every array element.
**Formula:**
```
dst(I) = e^src(I)
```
### log
```cpp theme={null}
void log(InputArray src, OutputArray dst)
```
Calculates the natural logarithm of every array element.
**Formula:**
```
dst(I) = log(|src(I)|)
```
**Example:**
```cpp theme={null}
Mat A, logA;
log(A, logA);
```
### absdiff
```cpp theme={null}
void absdiff(InputArray src1, InputArray src2, OutputArray dst)
```
Calculates per-element absolute difference between two arrays or array and scalar.
**Formula:**
```
dst(I) = |src1(I) - src2(I)|
```
**Example:**
```cpp theme={null}
// Frame difference for motion detection
Mat frame1, frame2, diff;
absdiff(frame1, frame2, diff);
```
### magnitude
```cpp theme={null}
void magnitude(InputArray x, InputArray y, OutputArray magnitude)
```
Calculates magnitude of 2D vectors.
Floating-point array of x-coordinates
Floating-point array of y-coordinates (same size as x)
Output array of magnitudes
**Formula:**
```
magnitude(I) = √(x(I)² + y(I)²)
```
### phase
```cpp theme={null}
void phase(InputArray x, InputArray y, OutputArray angle, bool angleInDegrees = false)
```
Calculates the rotation angle of 2D vectors.
Array of x-coordinates (floating-point)
Array of y-coordinates (same size and type as x)
Output array of angles
When true, angles are in degrees (0-360), otherwise radians (0-2π)
**Formula:**
```
angle(I) = atan2(y(I), x(I))
```
### cartToPolar
```cpp theme={null}
void cartToPolar(InputArray x, InputArray y, OutputArray magnitude,
OutputArray angle, bool angleInDegrees = false)
```
Calculates the magnitude and angle of 2D vectors.
**Example:**
```cpp theme={null}
Mat dx, dy, magnitude, angle;
// ... compute gradients dx, dy ...
cartToPolar(dx, dy, magnitude, angle, true);
```
### polarToCart
```cpp theme={null}
void polarToCart(InputArray magnitude, InputArray angle, OutputArray x,
OutputArray y, bool angleInDegrees = false)
```
Converts polar coordinates to Cartesian.
Array of vector magnitudes
Array of vector angles
Output array of x-coordinates
Output array of y-coordinates
## Matrix Operations
### gemm
```cpp theme={null}
void gemm(InputArray src1, InputArray src2, double alpha,
InputArray src3, double beta, OutputArray dst, int flags = 0)
```
Performs generalized matrix multiplication (GEMM).
First input matrix
Second input matrix
Weight for src1 \* src2
Third input matrix (added to product)
Weight for src3
Output matrix
Operation flags: GEMM\_1\_T (transpose src1), GEMM\_2\_T (transpose src2), GEMM\_3\_T (transpose src3)
**Formula:**
```
dst = alpha · src1 · src2 + beta · src3
```
**Example:**
```cpp theme={null}
Mat A, B, C, D;
gemm(A, B, 1.0, C, 1.0, D); // D = A*B + C
gemm(A, B, 2.0, C, 0.5, D, GEMM_1_T); // D = 2*A^T*B + 0.5*C
```
### transpose
```cpp theme={null}
void transpose(InputArray src, OutputArray dst)
```
Transposes a matrix.
**Formula:**
```
dst(i,j) = src(j,i)
```
**Example:**
```cpp theme={null}
Mat A, AT;
transpose(A, AT);
```
### transform
```cpp theme={null}
void transform(InputArray src, OutputArray dst, InputArray m)
```
Performs matrix transformation of every array element.
Input array (must be continuous)
Output array
Transformation matrix (2x2, 2x3, 3x3, or 3x4 for 2D, 3x3 or 3x4 for 3D)
**Example:**
```cpp theme={null}
// Rotate all 2D points by 45 degrees
std::vector points, rotated;
Mat R = getRotationMatrix2D(Point2f(0,0), 45, 1.0);
transform(points, rotated, R);
```
### mulTransposed
```cpp theme={null}
void mulTransposed(InputArray src, OutputArray dst, bool aTa,
InputArray delta = noArray(), double scale = 1, int dtype = -1)
```
Calculates the product of a matrix and its transposition.
Input matrix
Output square matrix
If true, computes src^T \* src; if false, computes src \* src^T
Optional delta matrix subtracted from src before multiplication
Optional scale factor for the matrix product
**Formula:**
```
dst = scale · (src - delta)^T · (src - delta) // if aTa=true
dst = scale · (src - delta) · (src - delta)^T // if aTa=false
```
## Array Manipulation
### flip
```cpp theme={null}
void flip(InputArray src, OutputArray dst, int flipCode)
```
Flips a 2D array around vertical, horizontal, or both axes.
Input array
Output array
Flip type: 0 (vertical flip), positive (horizontal flip), negative (both axes)
**Example:**
```cpp theme={null}
Mat img, flipped;
flip(img, flipped, 1); // Horizontal flip
flip(img, flipped, 0); // Vertical flip
flip(img, flipped, -1); // Both axes
```
### rotate
```cpp theme={null}
void rotate(InputArray src, OutputArray dst, int rotateCode)
```
Rotates a 2D array in multiples of 90 degrees.
Rotation type: ROTATE\_90\_CLOCKWISE, ROTATE\_180, ROTATE\_90\_COUNTERCLOCKWISE
**Example:**
```cpp theme={null}
Mat img, rotated;
rotate(img, rotated, ROTATE_90_CLOCKWISE);
```
### repeat
```cpp theme={null}
void repeat(InputArray src, int ny, int nx, OutputArray dst)
Mat repeat(const Mat& src, int ny, int nx)
```
Fills the output array with repeated copies of the input array.
Number of times to repeat along the vertical axis
Number of times to repeat along the horizontal axis
**Example:**
```cpp theme={null}
Mat pattern(2, 2, CV_8U, Scalar(255));
Mat tiled = repeat(pattern, 5, 5); // Create 10x10 tiled pattern
```
### hconcat
```cpp theme={null}
void hconcat(InputArray src1, InputArray src2, OutputArray dst)
void hconcat(InputArrayOfArrays src, OutputArray dst)
```
Concatenates arrays horizontally (along columns).
**Example:**
```cpp theme={null}
Mat A, B, C;
hconcat(A, B, C); // Concatenate side by side
```
### vconcat
```cpp theme={null}
void vconcat(InputArray src1, InputArray src2, OutputArray dst)
void vconcat(InputArrayOfArrays src, OutputArray dst)
```
Concatenates arrays vertically (along rows).
**Example:**
```cpp theme={null}
Mat A, B, C;
vconcat(A, B, C); // Stack vertically
```
## Channel Operations
### split
```cpp theme={null}
void split(InputArray src, OutputArrayOfArrays mv)
```
Divides a multi-channel array into several single-channel arrays.
Input multi-channel array
Output vector of arrays
**Example:**
```cpp theme={null}
Mat bgr, channels[3];
split(bgr, channels);
// channels[0] = blue, channels[1] = green, channels[2] = red
```
### merge
```cpp theme={null}
void merge(InputArrayOfArrays mv, OutputArray dst)
```
Merges several arrays to make a multi-channel array.
**Example:**
```cpp theme={null}
std::vector channels;
Mat bgr;
merge(channels, bgr);
```
### mixChannels
```cpp theme={null}
void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
const int* fromTo, size_t npairs)
void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
const std::vector& fromTo)
```
Copies specified channels from input arrays to specified channels of output arrays.
Array of index pairs: fromTo\[k*2] is source channel, fromTo\[k*2+1] is destination channel
**Example:**
```cpp theme={null}
Mat bgr, bgra;
// Copy BGR to BGRA and set alpha to 255
int from_to[] = {0,0, 1,1, 2,2, -1,3};
mixChannels(&bgr, 1, &bgra, 1, from_to, 4);
```
Channel indexing starts from 0. Use -1 to set a channel to zero.
# Utility Functions
Source: https://opencv-opencv.mintlify.app/api/core/utilities
Statistical functions, reduction operations, and utility helpers for array processing
## Statistical Functions
### sum
```cpp theme={null}
Scalar sum(InputArray src)
```
Calculates the sum of array elements.
Input array (1 to 4 channels)
Sum of all array elements for each channel
**Example:**
```cpp theme={null}
Mat img(100, 100, CV_8UC3);
Scalar total = sum(img); // Returns sum for each channel
double blueSum = total[0];
double greenSum = total[1];
double redSum = total[2];
```
### mean
```cpp theme={null}
Scalar mean(InputArray src, InputArray mask = noArray())
```
Calculates the mean value of array elements.
Input array (1 to 4 channels)
Optional operation mask (8-bit single channel)
Mean value for each channel
**Example:**
```cpp theme={null}
Mat img;
Scalar avgColor = mean(img); // Average color
Mat mask;
Scalar avgInRegion = mean(img, mask); // Average within masked region
```
### meanStdDev
```cpp theme={null}
void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev,
InputArray mask = noArray())
```
Calculates mean and standard deviation of array elements.
Input array (1 to 4 channels)
Output parameter: calculated mean value
Output parameter: calculated standard deviation
Optional operation mask
**Example:**
```cpp theme={null}
Mat img;
Mat mean, stddev;
meanStdDev(img, mean, stddev);
std::cout << "Mean: " << mean << std::endl;
std::cout << "Std Dev: " << stddev << std::endl;
```
### minMaxLoc
```cpp theme={null}
void minMaxLoc(InputArray src, double* minVal, double* maxVal = 0,
Point* minLoc = 0, Point* maxLoc = 0, InputArray mask = noArray())
```
Finds the global minimum and maximum in an array.
Input single-channel array
Pointer to returned minimum value (can be NULL)
Pointer to returned maximum value (can be NULL)
Pointer to returned minimum location (can be NULL)
Pointer to returned maximum location (can be NULL)
Optional mask to select a sub-array
**Example:**
```cpp theme={null}
Mat img;
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(img, &minVal, &maxVal, &minLoc, &maxLoc);
std::cout << "Min: " << minVal << " at " << minLoc << std::endl;
std::cout << "Max: " << maxVal << " at " << maxLoc << std::endl;
```
### norm
```cpp theme={null}
double norm(InputArray src1, int normType = NORM_L2, InputArray mask = noArray())
double norm(InputArray src1, InputArray src2, int normType = NORM_L2,
InputArray mask = noArray())
```
Calculates an absolute array norm, absolute difference norm, or relative difference norm.
First input array
Second input array (for difference norms)
Type of norm: NORM\_INF, NORM\_L1, NORM\_L2, NORM\_L2SQR, NORM\_HAMMING, NORM\_HAMMING2
Optional operation mask
Calculated norm value
**Norm Types:**
* `NORM_INF`: max(|x\_i|)
* `NORM_L1`: Σ|x\_i|
* `NORM_L2`: √(Σx\_i²)
* `NORM_L2SQR`: Σx\_i²
**Example:**
```cpp theme={null}
Mat vec1, vec2;
double l2norm = norm(vec1, NORM_L2);
double diff = norm(vec1, vec2, NORM_L2); // Euclidean distance
```
### normalize
```cpp theme={null}
void normalize(InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0,
int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray())
```
Normalizes the norm or value range of an array.
Input array
Output array (same size as src)
Norm value to normalize to or lower range boundary in range normalization
Upper range boundary in range normalization (not used for norm normalization)
Normalization type: NORM\_INF, NORM\_L1, NORM\_L2, or NORM\_MINMAX
Optional depth of output array
Optional operation mask
**Example:**
```cpp theme={null}
Mat src, dst;
// Normalize to range [0, 255]
normalize(src, dst, 0, 255, NORM_MINMAX, CV_8U);
// Normalize to unit norm
normalize(src, dst, 1.0, 0, NORM_L2);
```
### countNonZero
```cpp theme={null}
int countNonZero(InputArray src)
```
Counts non-zero array elements.
Single-channel array
Number of non-zero elements
**Example:**
```cpp theme={null}
Mat binary;
threshold(img, binary, 128, 255, THRESH_BINARY);
int whitePixels = countNonZero(binary);
```
### hasNonZero
```cpp theme={null}
bool hasNonZero(InputArray src)
```
Checks if there are any non-zero elements in array.
True if at least one non-zero element exists
**Example:**
```cpp theme={null}
Mat mask;
if (hasNonZero(mask)) {
// Process masked region
}
```
### findNonZero
```cpp theme={null}
void findNonZero(InputArray src, OutputArray idx)
```
Returns the list of locations of non-zero pixels.
Single-channel array (8-bit or floating-point)
Output array of Point locations (N×1 or 1×N)
**Example:**
```cpp theme={null}
Mat binary;
threshold(img, binary, 128, 255, THRESH_BINARY);
std::vector locations;
findNonZero(binary, locations);
for(const Point& pt : locations) {
// Process each non-zero pixel location
}
```
## Reduction Operations
### reduce
```cpp theme={null}
void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype = -1)
```
Reduces a matrix to a vector by applying an operation along a specified dimension.
Input array
Output vector
Dimension to reduce: 0 (reduce to single row), 1 (reduce to single column)
Reduction operation: REDUCE\_SUM, REDUCE\_AVG, REDUCE\_MAX, REDUCE\_MIN, REDUCE\_SUM2
Optional depth of output array
**Operations:**
* `REDUCE_SUM`: Sum of all rows/columns
* `REDUCE_AVG`: Mean of all rows/columns
* `REDUCE_MAX`: Maximum of all rows/columns
* `REDUCE_MIN`: Minimum of all rows/columns
* `REDUCE_SUM2`: Sum of squared values
**Example:**
```cpp theme={null}
Mat matrix(100, 100, CV_32F);
Mat columnSums, rowMeans;
reduce(matrix, columnSums, 0, REDUCE_SUM); // Sum each column
reduce(matrix, rowMeans, 1, REDUCE_AVG); // Mean of each row
```
### reduceArgMin
```cpp theme={null}
void reduceArgMin(InputArray src, OutputArray dst, int axis, bool lastIndex = false)
```
Finds indices of minimum elements along specified axis.
Input array
Output array of indices
Dimension to reduce along
Whether to return last index in case of multiple minimum values
**Example:**
```cpp theme={null}
Mat data, minIndices;
reduceArgMin(data, minIndices, 1); // Index of min in each row
```
### reduceArgMax
```cpp theme={null}
void reduceArgMax(InputArray src, OutputArray dst, int axis, bool lastIndex = false)
```
Finds indices of maximum elements along specified axis.
**Example:**
```cpp theme={null}
Mat data, maxIndices;
reduceArgMax(data, maxIndices, 0); // Index of max in each column
```
## Sorting
### sort
```cpp theme={null}
void sort(InputArray src, OutputArray dst, int flags)
```
Sorts each matrix row or column in ascending or descending order.
Input single-channel array
Output array (same size and type as src)
Operation flags: SORT\_EVERY\_ROW, SORT\_EVERY\_COLUMN, SORT\_ASCENDING, SORT\_DESCENDING
**Example:**
```cpp theme={null}
Mat data, sorted;
sort(data, sorted, SORT_EVERY_ROW | SORT_ASCENDING);
```
### sortIdx
```cpp theme={null}
void sortIdx(InputArray src, OutputArray dst, int flags)
```
Sorts each matrix row or column and returns sorted indices instead of values.
Output integer array of sorted indices
**Example:**
```cpp theme={null}
Mat values, indices;
sortIdx(values, indices, SORT_EVERY_ROW | SORT_DESCENDING);
```
## Linear Algebra
### determinant
```cpp theme={null}
double determinant(InputArray mtx)
```
Returns the determinant of a square matrix.
Input matrix (must be square)
Determinant value
**Example:**
```cpp theme={null}
Mat A(3, 3, CV_64F);
double det = determinant(A);
```
### trace
```cpp theme={null}
Scalar trace(InputArray mtx)
```
Returns the trace (sum of diagonal elements) of a matrix.
Input matrix
Trace of the matrix
**Formula:**
```
trace(A) = Σ A[i,i]
```
**Example:**
```cpp theme={null}
Mat A;
Scalar tr = trace(A);
```
### invert
```cpp theme={null}
double invert(InputArray src, OutputArray dst, int flags = DECOMP_LU)
```
Finds the inverse or pseudo-inverse of a matrix.
Input floating-point matrix
Output matrix of the same size and type as src
Inversion method: DECOMP\_LU, DECOMP\_SVD, DECOMP\_CHOLESKY
Reciprocal condition number (for SVD) or 0 if singular
**Decomposition Methods:**
* `DECOMP_LU`: LU decomposition (fastest for well-conditioned matrices)
* `DECOMP_SVD`: Singular value decomposition (works for singular matrices)
* `DECOMP_CHOLESKY`: Cholesky decomposition (for symmetric positive-definite matrices)
**Example:**
```cpp theme={null}
Mat A, invA;
double rcond = invert(A, invA, DECOMP_SVD);
if (rcond > 1e-6) {
// Matrix is well-conditioned
}
```
### solve
```cpp theme={null}
bool solve(InputArray src1, InputArray src2, OutputArray dst, int flags = DECOMP_LU)
```
Solves one or more linear systems or least-squares problems.
Coefficient matrix (A in Ax=b)
Right-hand side matrix (b in Ax=b)
Output solution (x in Ax=b)
Solution method: DECOMP\_LU, DECOMP\_SVD, DECOMP\_CHOLESKY, DECOMP\_QR, DECOMP\_NORMAL
True if solution exists
**Example:**
```cpp theme={null}
Mat A, b, x;
// Solve Ax = b
if (solve(A, b, x, DECOMP_LU)) {
std::cout << "Solution: " << x << std::endl;
}
```
### eigen
```cpp theme={null}
bool eigen(InputArray src, OutputArray eigenvalues, OutputArray eigenvectors = noArray())
```
Calculates eigenvalues and eigenvectors of a symmetric matrix.
Input symmetric square matrix
Output vector of eigenvalues (in descending order)
Output matrix of eigenvectors (one per row)
True if successful
**Example:**
```cpp theme={null}
Mat covar, eigenvalues, eigenvectors;
calcCovarMatrix(samples, covar, mean, COVAR_NORMAL | COVAR_ROWS);
eigen(covar, eigenvalues, eigenvectors);
// First eigenvector (principal component)
Mat pc1 = eigenvectors.row(0);
```
This function is optimized for symmetric matrices. For general matrices, use eigenNonSymmetric().
### calcCovarMatrix
```cpp theme={null}
void calcCovarMatrix(InputArray samples, OutputArray covar, InputOutputArray mean,
int flags, int ctype = CV_64F)
```
Calculates covariance matrix of a set of vectors.
Input samples (each row or column is a sample)
Output covariance matrix
Input or output mean vector
Operation flags: COVAR\_SCRAMBLED, COVAR\_NORMAL, COVAR\_USE\_AVG, COVAR\_SCALE, COVAR\_ROWS, COVAR\_COLS
Type of output matrices (CV\_32F or CV\_64F)
**Example:**
```cpp theme={null}
Mat samples(1000, 5, CV_32F); // 1000 samples, 5 dimensions
Mat covar, mean;
calcCovarMatrix(samples, covar, mean,
COVAR_NORMAL | COVAR_ROWS | COVAR_SCALE, CV_32F);
```
## Timing and Profiling
### getTickCount
```cpp theme={null}
int64 getTickCount()
```
Returns the number of ticks since a certain event (e.g., machine startup).
Current tick count
**Example:**
```cpp theme={null}
int64 t1 = getTickCount();
// ... perform operation ...
int64 t2 = getTickCount();
double time = (t2 - t1) / getTickFrequency();
std::cout << "Time: " << time << " seconds" << std::endl;
```
### getTickFrequency
```cpp theme={null}
double getTickFrequency()
```
Returns the number of ticks per second.
Tick frequency in Hz
### TickMeter
```cpp theme={null}
class TickMeter {
public:
void start();
void stop();
void reset();
double getTimeSec() const;
double getTimeMilli() const;
double getTimeMicro() const;
int64 getCounter() const;
double getFPS() const;
};
```
A class to measure passing time and calculate performance metrics.
**Example:**
```cpp theme={null}
cv::TickMeter tm;
tm.start();
// ... perform operation ...
tm.stop();
std::cout << "Time: " << tm.getTimeMilli() << " ms" << std::endl;
std::cout << "FPS: " << tm.getFPS() << std::endl;
```
## System Information
### getNumberOfCPUs
```cpp theme={null}
int getNumberOfCPUs()
```
Returns the number of logical CPUs available for the process.
### setNumThreads
```cpp theme={null}
void setNumThreads(int nthreads)
```
Sets the number of threads used by OpenCV for parallel regions.
Number of threads. Use 0 or negative values to reset to default
### getNumThreads
```cpp theme={null}
int getNumThreads()
```
Returns the number of threads used by OpenCV for parallel regions.
### getBuildInformation
```cpp theme={null}
String getBuildInformation()
```
Returns full configuration time cmake output including version, compiler, enabled modules, etc.
**Example:**
```cpp theme={null}
std::cout << getBuildInformation() << std::endl;
```
### getVersionString
```cpp theme={null}
String getVersionString()
```
Returns library version string (e.g., "4.8.0").
### getCPUFeaturesLine
```cpp theme={null}
std::string getCPUFeaturesLine()
```
Returns a string containing CPU features enabled during compilation.
**Example output:**
```
SSE SSE2 SSE3 *SSE4.1 *SSE4.2 *AVX *AVX2
```
* No marker: baseline features
* `*`: features enabled in dispatcher
* `?`: features enabled but not available in hardware
## Utility Functions
### setUseOptimized
```cpp theme={null}
void setUseOptimized(bool onoff)
```
Enables or disables optimized code (SSE, AVX, etc.).
True to enable optimizations, false to disable
### useOptimized
```cpp theme={null}
bool useOptimized()
```
Returns the status of optimized code usage.
### checkRange
```cpp theme={null}
bool checkRange(InputArray a, bool quiet = true, Point* pos = 0,
double minVal = -DBL_MAX, double maxVal = DBL_MAX)
```
Checks every element of an input array for invalid values.
Input array
If true, doesn't throw exceptions on invalid values
Optional output parameter for position of first invalid value
Minimum valid value (inclusive)
Maximum valid value (inclusive)
True if all elements are within range and not NaN/Inf
**Example:**
```cpp theme={null}
Mat result;
// ... computation ...
if (!checkRange(result)) {
std::cerr << "Invalid values detected (NaN or Inf)" << std::endl;
}
```
### patchNaNs
```cpp theme={null}
void patchNaNs(InputOutputArray a, double val = 0)
```
Replaces all NaN values in an array with specified value.
Input/output floating-point array
Value to replace NaNs with
**Example:**
```cpp theme={null}
Mat data;
// ... computation that might produce NaNs ...
patchNaNs(data, 0.0); // Replace NaNs with zeros
```
### LUT
```cpp theme={null}
void LUT(InputArray src, InputArray lut, OutputArray dst)
```
Performs a look-up table transform of an array.
Input array (8-bit elements)
Look-up table (256 elements)
Output array (same size as src)
**Example:**
```cpp theme={null}
// Create a gamma correction LUT
Mat lut(1, 256, CV_8U);
for(int i = 0; i < 256; i++)
lut.at(i) = saturate_cast(pow(i / 255.0, 0.5) * 255.0);
Mat img, corrected;
LUT(img, lut, corrected); // Apply gamma correction
```
### convertScaleAbs
```cpp theme={null}
void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0)
```
Scales, calculates absolute values, and converts to 8-bit unsigned type.
Input array
Output array (CV\_8U type)
Scale factor
Delta added to scaled values
**Formula:**
```
dst(I) = saturate_cast(|src(I) · alpha + beta|)
```
**Example:**
```cpp theme={null}
Mat gradient_x, abs_gradient;
Sobel(img, gradient_x, CV_16S, 1, 0);
convertScaleAbs(gradient_x, abs_gradient);
```
### PSNR
```cpp theme={null}
double PSNR(InputArray src1, InputArray src2, double R = 255.0)
```
Computes Peak Signal-to-Noise Ratio (PSNR) between two images.
First input array
Second input array (same size and type as src1)
Maximum pixel value (255.0 for 8-bit images)
PSNR value in decibels (dB)
**Example:**
```cpp theme={null}
Mat original, compressed;
double psnr = PSNR(original, compressed);
std::cout << "PSNR: " << psnr << " dB" << std::endl;
```
Higher PSNR values indicate better quality. Typical values range from 20 to 50 dB, with 30-50 dB being good quality.
# DNN Inference Utilities
Source: https://opencv-opencv.mintlify.app/api/dnn/inference
Helper functions and utilities for neural network inference
## Overview
OpenCV DNN provides utility functions for preparing inputs, processing outputs, and managing inference workflows.
## Blob Creation
### blobFromImage
Convert single image to 4D blob:
```cpp theme={null}
Mat blobFromImage(
InputArray image,
double scalefactor = 1.0,
const Size& size = Size(),
const Scalar& mean = Scalar(),
bool swapRB = false,
bool crop = false,
int ddepth = CV_32F
);
```
**Parameters**:
* `image`: Input image (any size, any channels)
* `scalefactor`: Multiplier for pixel values
* `size`: Target spatial dimensions
* `mean`: Values to subtract from channels
* `swapRB`: Swap red and blue channels (BGR to RGB)
* `crop`: Crop image after resize
* `ddepth`: Output depth (typically CV\_32F)
**Example**:
```cpp theme={null}
Mat img = imread("image.jpg");
// Basic usage
Mat blob = blobFromImage(img, 1.0/255, Size(224, 224));
// With mean subtraction
Mat blob = blobFromImage(
img,
1.0,
Size(224, 224),
Scalar(104, 117, 123), // ImageNet mean
true, // BGR to RGB
false // No crop
);
// Output shape: [1, 3, 224, 224]
```
### blobFromImages
Convert multiple images to single blob (batching):
```cpp theme={null}
Mat blobFromImages(
InputArrayOfArrays images,
double scalefactor = 1.0,
Size size = Size(),
const Scalar& mean = Scalar(),
bool swapRB = false,
bool crop = false,
int ddepth = CV_32F
);
```
**Example**:
```cpp theme={null}
std::vector images;
images.push_back(imread("img1.jpg"));
images.push_back(imread("img2.jpg"));
images.push_back(imread("img3.jpg"));
Mat blob = blobFromImages(
images,
1.0/255,
Size(224, 224),
Scalar(),
true
);
// Output shape: [3, 3, 224, 224]
// batch_size=3, channels=3, height=224, width=224
```
### imagesFromBlob
Convert blob back to images:
```cpp theme={null}
void imagesFromBlob(
const Mat& blob,
OutputArrayOfArrays images
);
```
**Example**:
```cpp theme={null}
std::vector images;
imagesFromBlob(blob, images);
for(const Mat& img : images) {
imshow("Image", img);
waitKey(0);
}
```
## Blob Utilities
### getPlane
Extract single plane from blob:
```cpp theme={null}
Mat getPlane(const Mat& m, int n, int cn);
```
**Parameters**:
* `m`: 4D blob \[N, C, H, W]
* `n`: Batch index
* `cn`: Channel index
**Example**:
```cpp theme={null}
// Extract first channel of first image
Mat plane = getPlane(blob, 0, 0);
```
### getMatFromNet
Get layer activations:
```cpp theme={null}
Mat net.getParam(const String& layer, int paramId);
```
## NMS (Non-Maximum Suppression)
### NMSBoxes
Filter overlapping bounding boxes:
```cpp theme={null}
void NMSBoxes(
const std::vector& bboxes,
const std::vector& scores,
const float score_threshold,
const float nms_threshold,
std::vector& indices,
const float eta = 1.f,
const int top_k = 0
);
```
**Parameters**:
* `bboxes`: Bounding boxes
* `scores`: Confidence scores
* `score_threshold`: Minimum score to keep
* `nms_threshold`: IoU threshold (typically 0.4-0.5)
* `indices`: Output indices of kept boxes
* `eta`: Adaptive NMS parameter
* `top_k`: Keep top K boxes (0 = all)
**Example**:
```cpp theme={null}
std::vector boxes = {/* detected boxes */};
std::vector confidences = {/* scores */};
std::vector indices;
NMSBoxes(
boxes,
confidences,
0.5, // score_threshold
0.4, // nms_threshold
indices
);
// Draw kept boxes
for(int idx : indices) {
rectangle(img, boxes[idx], Scalar(0, 255, 0), 2);
}
```
### NMSBoxesBatched
NMS for batched detections:
```cpp theme={null}
void NMSBoxesBatched(
const std::vector& bboxes,
const std::vector& scores,
const std::vector& class_ids,
const std::vector& batch_ids,
const float score_threshold,
const float nms_threshold,
std::vector& indices,
const float eta = 1.f,
const int top_k = 0
);
```
## Softmax
### softmax
Apply softmax activation:
```cpp theme={null}
Mat softmax(const Mat& src);
void softmax(
InputArray src,
OutputArray dst,
int axis = 1
);
```
**Example**:
```cpp theme={null}
Mat logits = net.forward();
Mat probs;
softmax(logits, probs, 1);
// Get top class
Point classIdPoint;
minMaxLoc(probs.reshape(1, 1), 0, 0, 0, &classIdPoint);
int classId = classIdPoint.x;
```
## Backend Queries
### getAvailableBackends
Query available backends:
```cpp theme={null}
std::vector> getAvailableBackends();
```
**Example**:
```cpp theme={null}
auto backends = getAvailableBackends();
for(auto& pair : backends) {
std::cout << "Backend: " << pair.first
<< ", Target: " << pair.second << std::endl;
}
```
### getAvailableTargets
Query targets for backend:
```cpp theme={null}
std::vector getAvailableTargets(Backend be);
```
**Example**:
```cpp theme={null}
auto targets = getAvailableTargets(DNN_BACKEND_CUDA);
for(Target t : targets) {
std::cout << "Target: " << t << std::endl;
}
```
## Model Diagnostics
### enableModelDiagnostics
Enable verbose model loading:
```cpp theme={null}
void enableModelDiagnostics(bool isDiagnosticsMode);
```
**Example**:
```cpp theme={null}
enableModelDiagnostics(true);
Net net = readNet("model.onnx"); // Prints detailed info
```
## Complete Examples
### Image Classification
```cpp theme={null}
#include
#include
#include
using namespace cv;
using namespace cv::dnn;
int main() {
// Load model
Net net = readNet("model.onnx");
net.setPreferableBackend(DNN_BACKEND_CUDA);
net.setPreferableTarget(DNN_TARGET_CUDA);
// Load image
Mat img = imread("image.jpg");
// Create blob
Mat blob = blobFromImage(
img,
1.0/255.0,
Size(224, 224),
Scalar(0.485, 0.456, 0.406) * 255, // ImageNet mean
true, // swapRB
false // crop
);
// Inference
net.setInput(blob);
Mat output = net.forward();
// Softmax
Mat probs;
softmax(output, probs, 1);
// Get top-5 predictions
Mat flat = probs.reshape(1, 1);
Mat sorted;
sortIdx(flat, sorted, SORT_EVERY_ROW | SORT_DESCENDING);
std::cout << "Top 5 predictions:\n";
for(int i = 0; i < 5; i++) {
int classId = sorted.at(i);
float prob = flat.at(classId);
std::cout << i+1 << ". Class " << classId
<< ": " << prob*100 << "%\n";
}
return 0;
}
```
### Object Detection (YOLO)
```cpp theme={null}
#include
#include
#include
using namespace cv;
using namespace cv::dnn;
int main() {
// Load YOLO
Net net = readNetFromDarknet("yolov4.cfg", "yolov4.weights");
// Load image
Mat img = imread("image.jpg");
// Create blob
Mat blob = blobFromImage(img, 1/255.0, Size(416, 416),
Scalar(), true, false);
// Inference
net.setInput(blob);
std::vector outputs;
net.forward(outputs, net.getUnconnectedOutLayersNames());
// Process detections
std::vector boxes;
std::vector confidences;
std::vector classIds;
for(const Mat& output : outputs) {
for(int i = 0; i < output.rows; i++) {
const float* data = output.ptr(i);
float confidence = data[4];
if(confidence > 0.5) {
Mat scores = output.row(i).colRange(5, output.cols);
Point classIdPoint;
double maxScore;
minMaxLoc(scores, 0, &maxScore, 0, &classIdPoint);
if(maxScore > 0.5) {
int centerX = data[0] * img.cols;
int centerY = data[1] * img.rows;
int width = data[2] * img.cols;
int height = data[3] * img.rows;
boxes.push_back(Rect(
centerX - width/2,
centerY - height/2,
width, height
));
confidences.push_back(confidence);
classIds.push_back(classIdPoint.x);
}
}
}
}
// NMS
std::vector indices;
NMSBoxes(boxes, confidences, 0.5, 0.4, indices);
// Draw detections
for(int idx : indices) {
Rect box = boxes[idx];
rectangle(img, box, Scalar(0, 255, 0), 2);
String label = format("Class %d: %.2f",
classIds[idx],
confidences[idx]);
putText(img, label, Point(box.x, box.y-5),
FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0,255,0), 2);
}
imshow("Detections", img);
waitKey(0);
return 0;
}
```
## Best Practices
Match preprocessing used during training
Use blobFromImages for multiple images
Remove overlapping detections
Query available backends for optimization
## See Also
* [Net Class](/api/dnn/network) - Network operations
* [DNN Module](/modules/dnn) - Module overview
* [DNN Layers](/api/dnn/layers) - Layer types
# DNN Layer Types
Source: https://opencv-opencv.mintlify.app/api/dnn/layers
Built-in layer types and custom layer implementation
## Overview
OpenCV DNN module supports numerous layer types from different frameworks. This document covers common layers and how to implement custom ones.
## Base Layer Class
### Layer Interface
```cpp theme={null}
class Layer : public Algorithm {
public:
// Layer parameters
std::vector blobs;
String name;
String type;
// Initialize layer
virtual void finalize(
InputArrayOfArrays inputs,
OutputArrayOfArrays outputs
);
// Forward pass
virtual void forward(
InputArrayOfArrays inputs,
OutputArrayOfArrays outputs,
OutputArrayOfArrays internals
);
// Query methods
virtual int inputNameToIndex(String inputName);
virtual int outputNameToIndex(const String& outputName);
};
```
## Convolution Layers
### Convolution
**Type**: `Convolution`
**Parameters**:
* `num_output`: Number of output channels
* `kernel_size`: Kernel dimensions
* `stride`: Stride
* `pad`: Padding
* `dilation`: Dilation
* `group`: Number of groups
**Example network**:
```
Convolution:
num_output: 64
kernel_size: 3
stride: 1
pad: 1
```
### Deconvolution
**Type**: `Deconvolution` / `ConvolutionTranspose`
Transposed convolution for upsampling.
### Depthwise Convolution
Implemented as regular convolution with `group = num_input`.
## Pooling Layers
### MaxPooling
**Type**: `Pooling` with `pool: MAX`
**Parameters**:
* `kernel_size`: Pool window size
* `stride`: Stride
* `pad`: Padding
**Example**:
```
Pooling:
pool: MAX
kernel_size: 2
stride: 2
```
### AveragePooling
**Type**: `Pooling` with `pool: AVE`
### GlobalPooling
**Type**: `Pooling` with `global_pooling: true`
Reduces spatial dimensions to 1x1.
## Activation Layers
### ReLU
**Type**: `ReLU`
```cpp theme={null}
class ActivationLayer : public Layer {
public:
virtual void forwardSlice(
const float* src, float* dst,
int len, size_t planeSize, int cn
) const = 0;
};
```
### LeakyReLU
**Type**: `ReLU` with `negative_slope`
**Parameters**:
* `negative_slope`: Slope for negative values (e.g., 0.1)
### PReLU
**Type**: `PReLU`
Parametric ReLU with learned slopes.
### ELU
**Type**: `ELU`
**Parameters**:
* `alpha`: Scale factor
### Sigmoid
**Type**: `Sigmoid`
### TanH
**Type**: `TanH`
### Swish / SiLU
**Type**: `Swish`
### Mish
**Type**: `Mish`
## Normalization Layers
### BatchNormalization
**Type**: `BatchNorm`
**Parameters**:
* `eps`: Epsilon for numerical stability
* Learned parameters: gamma, beta, mean, variance
```cpp theme={null}
// Batch norm stores 4 parameters:
// blobs[0] - mean
// blobs[1] - variance
// blobs[2] - scale (gamma)
// blobs[3] - shift (beta)
```
### LayerNormalization
**Type**: `LayerNorm`
Normalizes across channel dimension.
### InstanceNormalization
**Type**: `InstanceNorm`
Normalizes each sample independently.
### GroupNormalization
**Type**: `GroupNorm`
**Parameters**:
* `num_groups`: Number of groups
## Fully Connected Layers
### InnerProduct / Dense
**Type**: `InnerProduct`
**Parameters**:
* `num_output`: Output dimension
```cpp theme={null}
// Parameters stored in blobs:
// blobs[0] - weights [num_output x num_input]
// blobs[1] - biases [num_output] (optional)
```
## Reshape Layers
### Reshape
**Type**: `Reshape`
**Parameters**:
* `dim`: New dimensions (can use -1 for auto)
### Flatten
**Type**: `Flatten`
Reshapes to 2D (batch\_size, features).
### Permute
**Type**: `Permute`
Transposes dimensions.
**Parameters**:
* `order`: New axis order (e.g., \[0, 2, 3, 1])
### Slice
**Type**: `Slice`
Slices along an axis.
**Parameters**:
* `axis`: Axis to slice
* `slice_point`: Split points
### Concat
**Type**: `Concat`
Concatenates along an axis.
**Parameters**:
* `axis`: Concatenation axis
## Attention Layers
### Attention (Generic)
**Type**: `Attention`
Multi-head self-attention mechanism.
### ScaledDotProductAttention
Implemented for transformer models.
## Dropout
**Type**: `Dropout`
**Parameters**:
* `dropout_ratio`: Probability of dropping (0-1)
Dropout is typically disabled during inference (automatically handled).
## Element-wise Operations
### Eltwise
**Type**: `Eltwise`
**Operations**:
* `SUM`: Element-wise addition
* `PROD`: Element-wise multiplication
* `MAX`: Element-wise maximum
**Parameters**:
* `operation`: Operation type
* `coeff`: Optional coefficients for SUM
### Scale
**Type**: `Scale`
Scales and shifts: `output = scale * input + bias`
### Shift
**Type**: `Shift`
Adds a bias term.
## Upsampling Layers
### Resize
**Type**: `Resize` / `Upsample`
**Parameters**:
* `zoom_factor`: Scale factor
* `interpolation`: NEAREST, BILINEAR
### UpsamplingNearest
**Type**: `ResizeNearest`
Nearest neighbor upsampling.
### UpsamplingBilinear
**Type**: `ResizeBilinear`
Bilinear upsampling.
## Utility Layers
### Split
**Type**: `Split`
Duplicates input to multiple outputs.
### Crop
**Type**: `Crop`
Crops spatial dimensions.
### Padding
**Type**: `Padding`
Adds padding to input.
### Exp
**Type**: `Exp`
Element-wise exponential.
### Log
**Type**: `Log`
Element-wise logarithm.
### Power
**Type**: `Power`
Raises to power: `output = (shift + scale * input) ^ power`
### Abs
**Type**: `AbsVal`
Absolute value.
### BNLL
**Type**: `BNLL`
Binomial normal log likelihood.
## Custom Layers
### Implementing Custom Layer
```cpp theme={null}
class MyCustomLayer : public Layer {
public:
MyCustomLayer(const LayerParams& params)
: Layer(params) {
// Initialize from params
myParam = params.get("my_param", 0);
}
virtual bool getMemoryShapes(
const std::vector& inputs,
const int requiredOutputs,
std::vector& outputs,
std::vector& internals
) const override {
// Define output shapes
outputs.resize(1);
outputs[0] = inputs[0]; // Same as input
return false;
}
virtual void forward(
InputArrayOfArrays inputs_arr,
OutputArrayOfArrays outputs_arr,
OutputArrayOfArrays internals_arr
) override {
std::vector inputs, outputs;
inputs_arr.getMatVector(inputs);
outputs_arr.getMatVector(outputs);
const Mat& input = inputs[0];
Mat& output = outputs[0];
// Implement forward pass
output = input * 2; // Example: multiply by 2
}
private:
int myParam;
};
```
### Registering Custom Layer
```cpp theme={null}
CV_DNN_REGISTER_LAYER_CLASS(MyCustom, MyCustomLayer);
```
### Using Custom Layer
The layer will be automatically used when loading models containing that layer type.
## Layer Parameters
### LayerParams Class
```cpp theme={null}
class LayerParams : public Dict {
public:
std::vector blobs; // Learned parameters
String name; // Layer name
String type; // Layer type
// Get parameter
template
T get(const String& key, const T& defaultValue) const;
};
```
### Accessing Parameters
```cpp theme={null}
// In custom layer constructor
int numOutput = params.get("num_output");
float scale = params.get("scale", 1.0f); // With default
// Access learned weights
if(!params.blobs.empty()) {
Mat weights = params.blobs[0];
Mat biases = params.blobs[1];
}
```
## Backend Support
### CPU Implementation
Default implementation for all layers.
### OpenCL Implementation
Many layers have optimized OpenCL kernels.
### CUDA Implementation
```cpp theme={null}
class Layer {
public:
virtual Ptr initCUDA(
void* context,
const std::vector>& inputs,
const std::vector>& outputs
);
};
```
### Adding Backend Support
```cpp theme={null}
virtual bool supportBackend(int backendId) override {
return backendId == DNN_BACKEND_OPENCV ||
backendId == DNN_BACKEND_CUDA;
}
virtual Ptr initCUDA(...) override {
// Implement CUDA version
return Ptr();
}
```
## Best Practices
Validate parameter blob dimensions in constructor
Define output shapes for memory allocation
Provide CUDA/OpenCL implementations when possible
Compare outputs with reference implementation
## See Also
* [Net Class](/api/dnn/network) - Network loading and inference
* [DNN Module](/modules/dnn) - DNN module overview
* [DNN Inference](/api/dnn/inference) - Inference utilities
# Net Class
Source: https://opencv-opencv.mintlify.app/api/dnn/network
The main class for loading and running deep neural network models
## Overview
The `Net` class is the core of OpenCV's DNN module. It represents a neural network loaded from various frameworks and provides methods for inference.
## Loading Models
### readNet (Auto-detect)
```cpp theme={null}
Net readNet(const String& model,
const String& config = "",
const String& framework = "");
```
Automatically detects model format:
```cpp theme={null}
// ONNX
Net net = readNet("model.onnx");
// TensorFlow
Net net = readNet("model.pb", "config.pbtxt");
// Caffe
Net net = readNet("model.caffemodel", "deploy.prototxt");
```
### Framework-Specific Loaders
#### ONNX
```cpp theme={null}
Net readNetFromONNX(const String& onnxFile);
// From buffer
Net readNetFromONNX(const std::vector& buffer);
```
#### TensorFlow
```cpp theme={null}
Net readNetFromTensorflow(
const String& model,
const String& config = String()
);
// From buffers
Net readNetFromTensorflow(
const std::vector& bufferModel,
const std::vector& bufferConfig = std::vector()
);
```
#### Caffe
```cpp theme={null}
Net readNetFromCaffe(
const String& prototxt,
const String& caffeModel = String()
);
// From buffers
Net readNetFromCaffe(
const std::vector& bufferProto,
const std::vector& bufferModel = std::vector()
);
```
#### Darknet (YOLO)
```cpp theme={null}
Net readNetFromDarknet(
const String& cfgFile,
const String& darknetModel = String()
);
// From buffers
Net readNetFromDarknet(
const std::vector& bufferCfg,
const std::vector& bufferModel = std::vector()
);
```
## Backend and Target
### setPreferableBackend
```cpp theme={null}
void Net::setPreferableBackend(int backendId);
```
**Available backends**:
* `DNN_BACKEND_DEFAULT`: Default OpenCV implementation
* `DNN_BACKEND_OPENCV`: Pure OpenCV implementation
* `DNN_BACKEND_CUDA`: NVIDIA CUDA
* `DNN_BACKEND_INFERENCE_ENGINE`: Intel OpenVINO
* `DNN_BACKEND_VKCOM`: Vulkan
```cpp theme={null}
net.setPreferableBackend(DNN_BACKEND_CUDA);
```
### setPreferableTarget
```cpp theme={null}
void Net::setPreferableTarget(int targetId);
```
**Available targets**:
* `DNN_TARGET_CPU`: CPU
* `DNN_TARGET_OPENCL`: OpenCL (GPU)
* `DNN_TARGET_OPENCL_FP16`: OpenCL with FP16
* `DNN_TARGET_CUDA`: CUDA
* `DNN_TARGET_CUDA_FP16`: CUDA with FP16
* `DNN_TARGET_MYRIAD`: Intel Myriad
* `DNN_TARGET_FPGA`: FPGA
```cpp theme={null}
net.setPreferableTarget(DNN_TARGET_CUDA);
```
### Backend/Target Compatibility
```cpp theme={null}
// CPU
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
// OpenCL GPU
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_OPENCL);
// CUDA GPU
net.setPreferableBackend(DNN_BACKEND_CUDA);
net.setPreferableTarget(DNN_TARGET_CUDA);
// Intel OpenVINO
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(DNN_TARGET_CPU);
```
## Setting Inputs
### setInput
```cpp theme={null}
void Net::setInput(
InputArray blob,
const String& name = "",
double scalefactor = 1.0,
const Scalar& mean = Scalar()
);
```
**Parameters**:
* `blob`: 4D blob (NCHW format)
* `name`: Input layer name (optional if single input)
* `scalefactor`: Multiplicative scaling factor
* `mean`: Mean values to subtract
```cpp theme={null}
Mat blob = blobFromImage(img, 1.0/255, Size(224, 224));
net.setInput(blob);
// With preprocessing
net.setInput(blob, "data", 1.0/255, Scalar(104, 117, 123));
```
## Forward Pass
### forward (Single Output)
```cpp theme={null}
Mat Net::forward(const String& outputName = String());
```
```cpp theme={null}
// Get output from last layer
Mat output = net.forward();
// Get specific output layer
Mat output = net.forward("conv5");
```
### forward (Multiple Outputs)
```cpp theme={null}
void Net::forward(
OutputArrayOfArrays outputBlobs,
const String& outputName = String()
);
void Net::forward(
OutputArrayOfArrays outputBlobs,
const std::vector& outBlobNames
);
```
```cpp theme={null}
// Multiple outputs
std::vector outputs;
net.forward(outputs, {"output1", "output2", "output3"});
// All unconnected outputs
std::vector outNames = net.getUnconnectedOutLayersNames();
std::vector outputs;
net.forward(outputs, outNames);
```
### forwardAsync (Asynchronous)
```cpp theme={null}
AsyncArray Net::forwardAsync(const String& outputName = String());
```
```cpp theme={null}
net.setInput(blob);
AsyncArray async = net.forwardAsync();
// Do other work...
Mat output = async.get(); // Wait for result
```
## Network Information
### empty
```cpp theme={null}
bool Net::empty() const;
```
Check if network is loaded:
```cpp theme={null}
if(net.empty()) {
std::cerr << "Failed to load model\n";
return -1;
}
```
### getLayerNames
```cpp theme={null}
std::vector Net::getLayerNames() const;
```
Get all layer names:
```cpp theme={null}
std::vector layerNames = net.getLayerNames();
for(const String& name : layerNames) {
std::cout << name << std::endl;
}
```
### getLayerId
```cpp theme={null}
int Net::getLayerId(const String& layer) const;
```
Get layer ID by name:
```cpp theme={null}
int layerId = net.getLayerId("conv1");
```
### getLayer
```cpp theme={null}
Ptr Net::getLayer(int layerId) const;
Ptr Net::getLayer(const String& layerName) const;
```
Get layer object:
```cpp theme={null}
Ptr layer = net.getLayer("conv1");
String type = layer->type;
```
### getUnconnectedOutLayersNames
```cpp theme={null}
std::vector Net::getUnconnectedOutLayersNames() const;
```
Get output layer names:
```cpp theme={null}
std::vector outNames = net.getUnconnectedOutLayersNames();
for(const String& name : outNames) {
std::cout << "Output: " << name << std::endl;
}
```
## Network Modification
### setInputsNames
```cpp theme={null}
void Net::setInputsNames(const std::vector& inputBlobNames);
```
### setInputShape
```cpp theme={null}
void Net::setInputShape(const String& inputName, const MatShape& shape);
```
### getParam
```cpp theme={null}
Mat Net::getParam(int layer, int numParam = 0) const;
Mat Net::getParam(const String& layerName, int numParam = 0) const;
```
Get layer parameters (weights):
```cpp theme={null}
Mat weights = net.getParam("conv1", 0); // Weights
Mat biases = net.getParam("conv1", 1); // Biases
```
### setParam
```cpp theme={null}
void Net::setParam(int layer, int numParam, const Mat& blob);
void Net::setParam(const String& layerName, int numParam, const Mat& blob);
```
Set layer parameters:
```cpp theme={null}
Mat newWeights = /* ... */;
net.setParam("conv1", 0, newWeights);
```
## Performance Analysis
### getPerfProfile
```cpp theme={null}
int64 Net::getPerfProfile(std::vector& timings);
```
Get layer-wise timing:
```cpp theme={null}
std::vector timings;
int64 overall = net.getPerfProfile(timings);
std::vector layerNames = net.getLayerNames();
for(size_t i = 0; i < timings.size(); i++) {
std::cout << layerNames[i] << ": "
<< timings[i] << " ms\n";
}
std::cout << "Total: " << overall / 1000.0 << " ms\n";
```
### getFLOPS
```cpp theme={null}
int64 Net::getFLOPS(const MatShape& netInputShape) const;
int64 Net::getFLOPS(const std::vector& netInputShapes) const;
```
Compute FLOPs:
```cpp theme={null}
MatShape inputShape = {1, 3, 224, 224};
int64 flops = net.getFLOPS(inputShape);
std::cout << "Model FLOPs: " << flops / 1e9 << " G\n";
```
### getMemoryConsumption
```cpp theme={null}
void Net::getMemoryConsumption(
const MatShape& netInputShape,
size_t& weights,
size_t& blobs
) const;
```
Get memory usage:
```cpp theme={null}
size_t weights, blobs;
net.getMemoryConsumption({1, 3, 224, 224}, weights, blobs);
std::cout << "Weights: " << weights / 1e6 << " MB\n";
std::cout << "Blobs: " << blobs / 1e6 << " MB\n";
```
## Network Optimization
### enableFusion
```cpp theme={null}
void Net::enableFusion(bool fusion);
```
Enable/disable layer fusion:
```cpp theme={null}
net.enableFusion(true); // Default
```
### enableWinograd
```cpp theme={null}
void Net::enableWinograd(bool useWinograd);
```
Enable Winograd convolution optimization:
```cpp theme={null}
net.enableWinograd(true); // Default
```
## Debugging
### dump
```cpp theme={null}
String Net::dump();
```
Get network structure:
```cpp theme={null}
String structure = net.dump();
std::cout << structure;
```
### dumpToFile
```cpp theme={null}
void Net::dumpToFile(const String& path);
```
Save structure to file:
```cpp theme={null}
net.dumpToFile("network_structure.txt");
```
### dumpToPbtxt
```cpp theme={null}
void Net::dumpToPbtxt(const String& path);
```
Save as protobuf text (viewable in Netron):
```cpp theme={null}
net.dumpToPbtxt("network.pbtxt");
// View at https://netron.app
```
## Complete Example
```cpp theme={null}
#include
#include
#include
using namespace cv;
using namespace cv::dnn;
int main() {
// Load model
Net net = readNet("model.onnx");
if(net.empty()) {
std::cerr << "Failed to load model\n";
return -1;
}
// Configure backend/target
net.setPreferableBackend(DNN_BACKEND_CUDA);
net.setPreferableTarget(DNN_TARGET_CUDA);
// Load and preprocess image
Mat img = imread("image.jpg");
Mat blob = blobFromImage(img, 1.0/255, Size(224, 224),
Scalar(), true, false);
// Set input
net.setInput(blob);
// Forward pass
Mat output = net.forward();
// Get performance info
std::vector timings;
int64 t = net.getPerfProfile(timings);
std::cout << "Inference time: " << t / 1000.0 << " ms\n";
// Process output
Point classIdPoint;
minMaxLoc(output.reshape(1, 1), 0, 0, 0, &classIdPoint);
int classId = classIdPoint.x;
std::cout << "Predicted class: " << classId << std::endl;
return 0;
}
```
## See Also
* [DNN Module](/modules/dnn) - DNN module overview
* [DNN Layers](/api/dnn/layers) - Layer types
* [DNN Inference](/api/dnn/inference) - Inference utilities
# Color Space Conversions
Source: https://opencv-opencv.mintlify.app/api/imgproc/color-conversion
Functions for converting images between different color spaces
OpenCV provides extensive support for color space conversions, allowing you to convert images between various color representations.
## Main Function
### cvtColor
Converts an image from one color space to another.
```cpp theme={null}
void cvtColor(InputArray src, OutputArray dst, int code,
int dstCn = 0, AlgorithmHint hint = cv::ALGO_HINT_DEFAULT);
```
Input image: 8-bit unsigned, 16-bit unsigned (CV\_16UC...), or single-precision floating-point.
Output image of the same size and depth as src.
Color space conversion code. See ColorConversionCodes.
Number of channels in the destination image; if the parameter is 0, the number of the channels is derived automatically from src and code.
Implementation modification flags.
The function converts an input image from one color space to another. The function ignores the colorModel indicator in IplImage header, and determines the source color space from the number of channels.
```cpp theme={null}
Mat src = imread("image.jpg");
Mat gray, hsv;
// Convert BGR to grayscale
cvtColor(src, gray, COLOR_BGR2GRAY);
// Convert BGR to HSV
cvtColor(src, hsv, COLOR_BGR2HSV);
```
```python theme={null}
src = cv2.imread('image.jpg')
# Convert BGR to grayscale
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# Convert BGR to HSV
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
```
The source image (src) must be of an appropriate type for the desired color conversion. Different conversion codes support different input types.
***
### cvtColorTwoPlane
Converts an image from one color space to another where the source image is stored in two planes.
```cpp theme={null}
void cvtColorTwoPlane(InputArray src1, InputArray src2, OutputArray dst,
int code, AlgorithmHint hint = cv::ALGO_HINT_DEFAULT);
```
8-bit image (CV\_8U) of the Y plane.
Image containing interleaved U/V plane.
Output image.
Specifies the type of conversion. Supported codes: COLOR\_YUV2BGR\_NV12, COLOR\_YUV2RGB\_NV12, COLOR\_YUV2BGRA\_NV12, COLOR\_YUV2RGBA\_NV12, COLOR\_YUV2BGR\_NV21, COLOR\_YUV2RGB\_NV21, COLOR\_YUV2BGRA\_NV21, COLOR\_YUV2RGBA\_NV21.
This function only supports YUV420 to RGB conversion as of now.
***
## ColorConversionCodes Enum
The color conversion codes specify the type of conversion to perform. Here are the most commonly used ones:
### RGB/BGR Conversions
* `COLOR_BGR2BGRA` - Add alpha channel to BGR image \[8U/16U/32F]
* `COLOR_RGB2RGBA` - Add alpha channel to RGB image \[8U/16U/32F]
* `COLOR_BGRA2BGR` - Remove alpha channel from BGR image \[8U/16U/32F]
* `COLOR_RGBA2RGB` - Remove alpha channel from RGB image \[8U/16U/32F]
* `COLOR_BGR2RGB` - Convert between RGB and BGR \[8U/16U/32F]
* `COLOR_BGRA2RGBA` - Convert between RGBA and BGRA \[8U/16U/32F]
### Grayscale Conversions
* `COLOR_BGR2GRAY` - Convert BGR to grayscale \[8U/16U/32F]
* `COLOR_RGB2GRAY` - Convert RGB to grayscale \[8U/16U/32F]
* `COLOR_GRAY2BGR` - Convert grayscale to BGR \[8U/16U/32F]
* `COLOR_GRAY2BGRA` - Convert grayscale to BGRA \[8U/16U/32F]
* `COLOR_BGRA2GRAY` - Convert BGRA to grayscale \[8U/16U/32F]
* `COLOR_RGBA2GRAY` - Convert RGBA to grayscale \[8U/16U/32F]
### HSV Conversions
* `COLOR_BGR2HSV` - Convert BGR to HSV with H range 0..180 if 8 bit image \[8U/32F]
* `COLOR_RGB2HSV` - Convert RGB to HSV \[8U/32F]
* `COLOR_HSV2BGR` - Convert HSV to BGR \[8U/32F]
* `COLOR_HSV2RGB` - Convert HSV to RGB \[8U/32F]
* `COLOR_BGR2HSV_FULL` - Convert BGR to HSV with H range 0..255 if 8 bit image \[8U/32F]
* `COLOR_HSV2BGR_FULL` - Convert HSV to BGR with full H range \[8U/32F]
### HLS Conversions
* `COLOR_BGR2HLS` - Convert BGR to HLS (hue lightness saturation) \[8U/32F]
* `COLOR_RGB2HLS` - Convert RGB to HLS \[8U/32F]
* `COLOR_HLS2BGR` - Convert HLS to BGR \[8U/32F]
* `COLOR_HLS2RGB` - Convert HLS to RGB \[8U/32F]
* `COLOR_BGR2HLS_FULL` - Convert BGR to HLS with H range 0..255 \[8U/32F]
* `COLOR_HLS2BGR_FULL` - Convert HLS to BGR with full H range \[8U/32F]
### CIE Lab Conversions
* `COLOR_BGR2Lab` - Convert BGR to CIE Lab \[8U/32F]
* `COLOR_RGB2Lab` - Convert RGB to CIE Lab \[8U/32F]
* `COLOR_Lab2BGR` - Convert CIE Lab to BGR \[8U/32F]
* `COLOR_Lab2RGB` - Convert CIE Lab to RGB \[8U/32F]
### CIE Luv Conversions
* `COLOR_BGR2Luv` - Convert BGR to CIE Luv \[8U/32F]
* `COLOR_RGB2Luv` - Convert RGB to CIE Luv \[8U/32F]
* `COLOR_Luv2BGR` - Convert CIE Luv to BGR \[8U/32F]
* `COLOR_Luv2RGB` - Convert CIE Luv to RGB \[8U/32F]
### CIE XYZ Conversions
* `COLOR_BGR2XYZ` - Convert BGR to CIE XYZ \[8U/16U/32F]
* `COLOR_RGB2XYZ` - Convert RGB to CIE XYZ \[8U/16U/32F]
* `COLOR_XYZ2BGR` - Convert CIE XYZ to BGR \[8U/16U/32F]
* `COLOR_XYZ2RGB` - Convert CIE XYZ to RGB \[8U/16U/32F]
### YCrCb Conversions
* `COLOR_BGR2YCrCb` - Convert BGR to YCrCb (luma-chroma) \[8U/16U/32F]
* `COLOR_RGB2YCrCb` - Convert RGB to YCrCb \[8U/16U/32F]
* `COLOR_YCrCb2BGR` - Convert YCrCb to BGR \[8U/16U/32F]
* `COLOR_YCrCb2RGB` - Convert YCrCb to RGB \[8U/16U/32F]
### YUV Conversions
* `COLOR_BGR2YUV` - Convert between RGB/BGR and YUV \[8U/16U/32F]
* `COLOR_RGB2YUV` - Convert RGB to YUV \[8U/16U/32F]
* `COLOR_YUV2BGR` - Convert YUV to BGR \[8U/16U/32F]
* `COLOR_YUV2RGB` - Convert YUV to RGB \[8U/16U/32F]
### YUV 4:2:0 Conversions (NV12/NV21)
* `COLOR_YUV2RGB_NV12` - YUV NV12 to RGB \[8U]
* `COLOR_YUV2BGR_NV12` - YUV NV12 to BGR \[8U]
* `COLOR_YUV2RGB_NV21` - YUV NV21 to RGB \[8U]
* `COLOR_YUV2BGR_NV21` - YUV NV21 to BGR \[8U]
* `COLOR_YUV2RGBA_NV12` - YUV NV12 to RGBA \[8U]
* `COLOR_YUV2BGRA_NV12` - YUV NV12 to BGRA \[8U]
### YUV 4:2:0 Conversions (YV12/IYUV)
* `COLOR_YUV2RGB_YV12` - YUV YV12 to RGB \[8U]
* `COLOR_YUV2BGR_YV12` - YUV YV12 to BGR \[8U]
* `COLOR_YUV2RGB_IYUV` - YUV IYUV/I420 to RGB \[8U]
* `COLOR_YUV2BGR_IYUV` - YUV IYUV/I420 to BGR \[8U]
### Bayer Pattern Conversions
* `COLOR_BayerBG2BGR` - Bayer BG/RGGB pattern to BGR \[8U/16U]
* `COLOR_BayerGB2BGR` - Bayer GB/GRBG pattern to BGR \[8U/16U]
* `COLOR_BayerRG2BGR` - Bayer RG/BGGR pattern to BGR \[8U/16U]
* `COLOR_BayerGR2BGR` - Bayer GR/GBRG pattern to BGR \[8U/16U]
* `COLOR_BayerBG2GRAY` - Bayer BG/RGGB pattern to grayscale \[8U/16U]
* `COLOR_BayerGB2GRAY` - Bayer GB/GRBG pattern to grayscale \[8U/16U]
### Bayer VNG (Variable Number of Gradients)
* `COLOR_BayerBG2BGR_VNG` - Bayer BG to BGR using VNG \[8U]
* `COLOR_BayerGB2BGR_VNG` - Bayer GB to BGR using VNG \[8U]
* `COLOR_BayerRG2BGR_VNG` - Bayer RG to BGR using VNG \[8U]
* `COLOR_BayerGR2BGR_VNG` - Bayer GR to BGR using VNG \[8U]
### Bayer Edge-Aware
* `COLOR_BayerBG2BGR_EA` - Bayer BG to BGR using edge-aware \[8U/16U]
* `COLOR_BayerGB2BGR_EA` - Bayer GB to BGR using edge-aware \[8U/16U]
* `COLOR_BayerRG2BGR_EA` - Bayer RG to BGR using edge-aware \[8U/16U]
* `COLOR_BayerGR2BGR_EA` - Bayer GR to BGR using edge-aware \[8U/16U]
## Color Space Information
### RGB/BGR
The default color space in OpenCV is BGR (Blue-Green-Red), not RGB. When you read an image using imread(), it returns a BGR image. Many other libraries (like matplotlib) expect RGB format.
### Grayscale
Grayscale images have a single channel. The conversion from RGB/BGR to grayscale uses:
$$
\text{Gray} = 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B
$$
### HSV (Hue, Saturation, Value)
HSV separates image intensity (value) from color information (hue and saturation). The hue range is:
* 0..180 for 8-bit images (default)
* 0..255 for 8-bit images (FULL variant)
* 0..360 for 32-bit images
### HLS (Hue, Lightness, Saturation)
Similar to HSV but uses lightness instead of value. The hue range is the same as HSV.
### Lab/Luv
CIE Lab and Luv are perceptually uniform color spaces, useful for color-based segmentation and comparison.
### YCrCb/YUV
Luma-chroma color spaces commonly used in video encoding. Y represents luminance (brightness), while Cr/Cb (or U/V) represent chrominance (color information).
# Drawing Functions
Source: https://opencv-opencv.mintlify.app/api/imgproc/drawing
Functions for drawing geometric shapes and text on images
Drawing functions work with matrices/images of arbitrary depth. The boundaries of shapes can be rendered with antialiasing (implemented only for 8-bit images for now).
## Color Convention
For color images, the channel ordering is normally Blue, Green, Red (BGR). This is what imshow, imread, and imwrite expect. If you form a color using the Scalar constructor, it should look like:
```cpp theme={null}
Scalar(blue_component, green_component, red_component[, alpha_component])
```
## Line Drawing
### line
Draws a line segment connecting two points.
```cpp theme={null}
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
```
Image.
First point of the line segment.
Second point of the line segment.
Line color.
Line thickness.
Type of the line. See LineTypes.
Number of fractional bits in the point coordinates.
The function line draws the line segment between pt1 and pt2 points in the image. The line is clipped by the image boundaries.
```cpp theme={null}
Mat img = Mat::zeros(400, 400, CV_8UC3);
line(img, Point(50, 50), Point(350, 350), Scalar(0, 255, 0), 2);
```
```python theme={null}
img = np.zeros((400, 400, 3), dtype=np.uint8)
cv2.line(img, (50, 50), (350, 350), (0, 255, 0), 2)
```
***
### arrowedLine
Draws an arrow segment pointing from the first point to the second one.
```cpp theme={null}
void arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness=1, int line_type=8, int shift=0, double tipLength=0.1);
```
Image.
The point the arrow starts from.
The point the arrow points to.
Line color.
Line thickness.
Type of the line. See LineTypes.
Number of fractional bits in the point coordinates.
The length of the arrow tip in relation to the arrow length.
***
## Shape Drawing
### rectangle
Draws a simple, thick, or filled up-right rectangle.
```cpp theme={null}
void rectangle(InputOutputArray img, Point pt1, Point pt2,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
void rectangle(InputOutputArray img, Rect rec,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
```
Image.
Vertex of the rectangle.
Vertex of the rectangle opposite to pt1.
Alternative rectangle specification.
Rectangle color or brightness (grayscale image).
Thickness of lines that make up the rectangle. Negative values, like FILLED, mean that the function has to draw a filled rectangle.
Type of the line. See LineTypes.
Number of fractional bits in the point coordinates.
```cpp theme={null}
// Draw rectangle outline
rectangle(img, Point(100, 100), Point(300, 200), Scalar(255, 0, 0), 2);
// Draw filled rectangle
rectangle(img, Rect(50, 250, 200, 100), Scalar(0, 0, 255), FILLED);
```
```python theme={null}
# Draw rectangle outline
cv2.rectangle(img, (100, 100), (300, 200), (255, 0, 0), 2)
# Draw filled rectangle
cv2.rectangle(img, (50, 250, 200, 100), (0, 0, 255), cv2.FILLED)
```
***
### circle
Draws a circle.
```cpp theme={null}
void circle(InputOutputArray img, Point center, int radius,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
```
Image where the circle is drawn.
Center of the circle.
Radius of the circle.
Circle color.
Thickness of the circle outline, if positive. Negative values, like FILLED, mean that a filled circle is to be drawn.
Type of the circle boundary. See LineTypes.
Number of fractional bits in the coordinates of the center and in the radius value.
```cpp theme={null}
circle(img, Point(200, 200), 50, Scalar(0, 255, 255), 3);
circle(img, Point(300, 300), 75, Scalar(255, 255, 0), FILLED);
```
```python theme={null}
cv2.circle(img, (200, 200), 50, (0, 255, 255), 3)
cv2.circle(img, (300, 300), 75, (255, 255, 0), cv2.FILLED)
```
***
### ellipse
Draws a simple or thick elliptic arc or fills an ellipse sector.
```cpp theme={null}
void ellipse(InputOutputArray img, Point center, Size axes,
double angle, double startAngle, double endAngle,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
void ellipse(InputOutputArray img, const RotatedRect& box, const Scalar& color,
int thickness = 1, int lineType = LINE_8);
```
Image.
Center of the ellipse.
Half of the size of the ellipse main axes.
Ellipse rotation angle in degrees.
Starting angle of the elliptic arc in degrees.
Ending angle of the elliptic arc in degrees.
Alternative ellipse representation via RotatedRect. This means that the function draws an ellipse inscribed in the rotated rectangle.
Ellipse color.
Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn.
Type of the ellipse boundary. See LineTypes.
Number of fractional bits in the coordinates of the center and values of axes.
To draw the whole ellipse, not an arc, pass startAngle=0 and endAngle=360. If startAngle is greater than endAngle, they are swapped.
***
## Polygon Drawing
### polylines
Draws several polygonal curves.
```cpp theme={null}
void polylines(InputOutputArray img, InputArrayOfArrays pts,
bool isClosed, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
```
Image.
Array of polygonal curves.
Flag indicating whether the drawn polylines are closed or not. If they are closed, the function draws a line from the last vertex of each curve to its first vertex.
Polyline color.
Thickness of the polyline edges.
Type of the line segments. See LineTypes.
Number of fractional bits in the vertex coordinates.
***
### fillPoly
Fills the area bounded by one or more polygons.
```cpp theme={null}
void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point());
```
Image.
Array of polygons where each polygon is represented as an array of points.
Polygon color.
Type of the polygon boundaries. See LineTypes.
Number of fractional bits in the vertex coordinates.
Optional offset of all points of the contours.
The function fillPoly fills an area bounded by several polygonal contours. The function can fill complex areas, for example, areas with holes, contours with self-intersections, and so forth.
***
### fillConvexPoly
Fills a convex polygon.
```cpp theme={null}
void fillConvexPoly(InputOutputArray img, InputArray points,
const Scalar& color, int lineType = LINE_8,
int shift = 0);
```
Image.
Polygon vertices.
Polygon color.
Type of the polygon boundaries. See LineTypes.
Number of fractional bits in the vertex coordinates.
This function is much faster than fillPoly. It can fill not only convex polygons but any monotonic polygon without self-intersections.
***
## Text Rendering
### putText
Draws a text string.
```cpp theme={null}
void putText(InputOutputArray img, const String& text, Point org,
int fontFace, double fontScale, Scalar color,
int thickness = 1, int lineType = LINE_8,
bool bottomLeftOrigin = false);
```
Image.
Text string to be drawn.
Bottom-left corner of the text string in the image.
Font type. See HersheyFonts.
Font scale factor that is multiplied by the font-specific base size.
Text color.
Thickness of the lines used to draw a text.
Line type. See LineTypes.
When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner.
The function putText renders the specified text string in the image. Symbols that cannot be rendered using the specified font are replaced by question marks.
```cpp theme={null}
putText(img, "OpenCV", Point(50, 100),
FONT_HERSHEY_SIMPLEX, 1.5, Scalar(255, 255, 255), 2);
```
```python theme={null}
cv2.putText(img, 'OpenCV', (50, 100),
cv2.FONT_HERSHEY_SIMPLEX, 1.5, (255, 255, 255), 2)
```
***
### getTextSize
Calculates the width and height of a text string.
```cpp theme={null}
Size getTextSize(const String& text, int fontFace,
double fontScale, int thickness,
int* baseLine);
```
Input text string.
Font to use. See HersheyFonts.
Font scale factor that is multiplied by the font-specific base size.
Thickness of lines used to render the text.
y-coordinate of the baseline relative to the bottom-most text point.
The function calculates and returns the size of a box that contains the specified text.
***
## Enumerations
### LineTypes
Types of line:
* `FILLED` (-1) - Filled shape
* `LINE_4` (4) - 4-connected line
* `LINE_8` (8) - 8-connected line
* `LINE_AA` (16) - Antialiased line
### HersheyFonts
Hershey font types:
* `FONT_HERSHEY_SIMPLEX` (0) - Normal size sans-serif font
* `FONT_HERSHEY_PLAIN` (1) - Small size sans-serif font
* `FONT_HERSHEY_DUPLEX` (2) - Normal size sans-serif font (more complex than SIMPLEX)
* `FONT_HERSHEY_COMPLEX` (3) - Normal size serif font
* `FONT_HERSHEY_TRIPLEX` (4) - Normal size serif font (more complex than COMPLEX)
* `FONT_HERSHEY_COMPLEX_SMALL` (5) - Smaller version of COMPLEX
* `FONT_HERSHEY_SCRIPT_SIMPLEX` (6) - Hand-writing style font
* `FONT_HERSHEY_SCRIPT_COMPLEX` (7) - More complex variant of SCRIPT\_SIMPLEX
* `FONT_ITALIC` (16) - Flag for italic font
### MarkerTypes
Marker types used for the drawMarker function:
* `MARKER_CROSS` (0) - A crosshair marker shape
* `MARKER_TILTED_CROSS` (1) - A 45 degree tilted crosshair marker shape
* `MARKER_STAR` (2) - A star marker shape
* `MARKER_DIAMOND` (3) - A diamond marker shape
* `MARKER_SQUARE` (4) - A square marker shape
* `MARKER_TRIANGLE_UP` (5) - An upwards pointing triangle marker shape
* `MARKER_TRIANGLE_DOWN` (6) - A downwards pointing triangle marker shape
# Feature Detection
Source: https://opencv-opencv.mintlify.app/api/imgproc/feature-detection
Functions for detecting edges, corners, lines, and circles in images
This module provides functions for detecting various features in images, including edges, corners, lines, and circles.
## Edge Detection
### Canny
Finds edges in an image using the Canny algorithm.
```cpp theme={null}
void Canny(InputArray image, OutputArray edges,
double threshold1, double threshold2,
int apertureSize = 3, bool L2gradient = false);
void Canny(InputArray dx, InputArray dy,
OutputArray edges,
double threshold1, double threshold2,
bool L2gradient = false);
```
8-bit input image.
16-bit x derivative of input image (CV\_16SC1 or CV\_16SC3).
16-bit y derivative of input image (same type as dx).
Output edge map; single channels 8-bit image, which has the same size as image.
First threshold for the hysteresis procedure.
Second threshold for the hysteresis procedure.
Aperture size for the Sobel operator.
A flag, indicating whether a more accurate L2 norm should be used to calculate the image gradient magnitude (L2gradient=true), or whether the default L1 norm is enough (L2gradient=false).
The function finds edges in the input image and marks them in the output map edges using the Canny algorithm. The smallest value between threshold1 and threshold2 is used for edge linking. The largest value is used to find initial segments of strong edges.
```cpp theme={null}
Mat src = imread("image.jpg", IMREAD_GRAYSCALE);
Mat edges;
Canny(src, edges, 50, 150);
```
```python theme={null}
src = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
edges = cv2.Canny(src, 50, 150)
```
***
## Derivatives and Gradients
### Sobel
Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator.
```cpp theme={null}
void Sobel(InputArray src, OutputArray dst, int ddepth,
int dx, int dy, int ksize = 3,
double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT);
```
Input image.
Output image of the same size and the same number of channels as src.
Output image depth. In the case of 8-bit input images it will result in truncated derivatives.
Order of the derivative x.
Order of the derivative y.
Size of the extended Sobel kernel; it must be 1, 3, 5, or 7.
Optional scale factor for the computed derivative values; by default, no scaling is applied.
Optional delta value that is added to the results prior to storing them in dst.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The Sobel operators combine Gaussian smoothing and differentiation. Most often, the function is called with (xorder = 1, yorder = 0, ksize = 3) or (xorder = 0, yorder = 1, ksize = 3) to calculate the first x- or y- image derivative.
***
### Scharr
Calculates the first x- or y- image derivative using Scharr operator.
```cpp theme={null}
void Scharr(InputArray src, OutputArray dst, int ddepth,
int dx, int dy, double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT);
```
Input image.
Output image of the same size and the same number of channels as src.
Output image depth.
Order of the derivative x.
Order of the derivative y.
Optional scale factor for the computed derivative values.
Optional delta value that is added to the results prior to storing them in dst.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The Scharr operator may give more accurate results than the 3×3 Sobel. The Scharr aperture is:
$$
\begin{bmatrix}
-3 & 0 & 3 \\
-10 & 0 & 10 \\
-3 & 0 & 3
\end{bmatrix}
$$
for the x-derivative, or transposed for the y-derivative.
***
### Laplacian
Calculates the Laplacian of an image.
```cpp theme={null}
void Laplacian(InputArray src, OutputArray dst, int ddepth,
int ksize = 1, double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT);
```
Source image.
Destination image of the same size and the same number of channels as src.
Desired depth of the destination image.
Aperture size used to compute the second-derivative filters. The size must be positive and odd.
Optional scale factor for the computed Laplacian values.
Optional delta value that is added to the results prior to storing them in dst.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The function calculates the Laplacian of the source image by adding up the second x and y derivatives calculated using the Sobel operator:
$$
\Delta \text{src} = \frac{\partial^2 \text{src}}{\partial x^2} + \frac{\partial^2 \text{src}}{\partial y^2}
$$
***
## Corner Detection
### cornerHarris
Harris corner detector.
```cpp theme={null}
void cornerHarris(InputArray src, OutputArray dst, int blockSize,
int ksize, double k,
int borderType = BORDER_DEFAULT);
```
Input single-channel 8-bit or floating-point image.
Image to store the Harris detector responses. It has the type CV\_32FC1 and the same size as src.
Neighborhood size.
Aperture parameter for the Sobel operator.
Harris detector free parameter.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The function runs the Harris corner detector on the image. Corners in the image can be found as the local maxima of this response map.
***
### cornerMinEigenVal
Calculates the minimal eigenvalue of gradient matrices for corner detection.
```cpp theme={null}
void cornerMinEigenVal(InputArray src, OutputArray dst,
int blockSize, int ksize = 3,
int borderType = BORDER_DEFAULT);
```
Input single-channel 8-bit or floating-point image.
Image to store the minimal eigenvalues. It has the type CV\_32FC1 and the same size as src.
Neighborhood size.
Aperture parameter for the Sobel operator.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The function is similar to cornerEigenValsAndVecs but it calculates and stores only the minimal eigenvalue of the covariance matrix of derivatives.
***
### goodFeaturesToTrack
Determines strong corners on an image.
```cpp theme={null}
void goodFeaturesToTrack(InputArray image, OutputArray corners,
int maxCorners, double qualityLevel, double minDistance,
InputArray mask = noArray(), int blockSize = 3,
bool useHarrisDetector = false, double k = 0.04);
```
Input 8-bit or floating-point 32-bit, single-channel image.
Output vector of detected corners.
Maximum number of corners to return. If there are more corners than are found, the strongest of them is returned. maxCorners \<= 0 implies that no limit on the maximum is set.
Parameter characterizing the minimal accepted quality of image corners. The parameter value is multiplied by the best corner quality measure.
Minimum possible Euclidean distance between the returned corners.
Optional region of interest.
Size of an average block for computing a derivative covariation matrix over each pixel neighborhood.
Parameter indicating whether to use a Harris detector or cornerMinEigenVal.
Free parameter of the Harris detector.
The function finds the most prominent corners in the image or in the specified image region.
***
## Hough Transform
### HoughLines
Finds lines in a binary image using the standard Hough transform.
```cpp theme={null}
void HoughLines(InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI,
bool use_edgeval = false);
```
8-bit, single-channel binary source image. The image may be modified by the function.
Output vector of lines. Each line is represented by a 2 or 3 element vector (ρ, θ) or (ρ, θ, votes).
Distance resolution of the accumulator in pixels.
Angle resolution of the accumulator in radians.
Accumulator threshold parameter. Only those lines are returned that get enough votes (>threshold).
For the multi-scale Hough transform, it is a divisor for the distance resolution rho.
For the multi-scale Hough transform, it is a divisor for the distance resolution theta.
Minimum angle to check for lines. Must fall between 0 and max\_theta.
Upper bound for the angle. Must fall between min\_theta and CV\_PI.
The function implements the standard or standard multi-scale Hough transform algorithm for line detection.
***
### HoughLinesP
Finds line segments in a binary image using the probabilistic Hough transform.
```cpp theme={null}
void HoughLinesP(InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double minLineLength = 0, double maxLineGap = 0);
```
8-bit, single-channel binary source image. The image may be modified by the function.
Output vector of lines. Each line is represented by a 4-element vector (x₁, y₁, x₂, y₂), where (x₁,y₁) and (x₂, y₂) are the ending points of each detected line segment.
Distance resolution of the accumulator in pixels.
Angle resolution of the accumulator in radians.
Accumulator threshold parameter. Only those lines are returned that get enough votes (>threshold).
Minimum line length. Line segments shorter than that are rejected.
Maximum allowed gap between points on the same line to link them.
The function implements the probabilistic Hough transform algorithm for line detection.
***
### HoughCircles
Finds circles in a grayscale image using the Hough transform.
```cpp theme={null}
void HoughCircles(InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0);
```
8-bit, single-channel, grayscale input image.
Output vector of found circles. Each vector is encoded as 3 or 4 element floating-point vector (x, y, radius) or (x, y, radius, votes).
Detection method. The available methods are HOUGH\_GRADIENT and HOUGH\_GRADIENT\_ALT.
Inverse ratio of the accumulator resolution to the image resolution. For example, if dp=1, the accumulator has the same resolution as the input image.
Minimum distance between the centers of the detected circles.
First method-specific parameter. In case of HOUGH\_GRADIENT and HOUGH\_GRADIENT\_ALT, it is the higher threshold of the two passed to the Canny edge detector.
Second method-specific parameter. In case of HOUGH\_GRADIENT, it is the accumulator threshold for the circle centers at the detection stage.
Minimum circle radius.
Maximum circle radius. If \<= 0, uses the maximum image dimension.
The function finds circles in a grayscale image using a modification of the Hough transform.
```cpp theme={null}
Mat src = imread("image.jpg", IMREAD_GRAYSCALE);
Mat blurred;
GaussianBlur(src, blurred, Size(9, 9), 2, 2);
vector circles;
HoughCircles(blurred, circles, HOUGH_GRADIENT, 1, src.rows/8, 200, 100);
```
```python theme={null}
src = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
blurred = cv2.GaussianBlur(src, (9, 9), 2)
circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, src.shape[0]/8,
param1=200, param2=100)
```
Usually the function detects the centers of circles well. However, it may fail to find correct radii. You can assist to the function by specifying the radius range (minRadius and maxRadius) if you know it.
***
## Enumerations
### HoughModes
Variants of Hough transform:
* `HOUGH_STANDARD` - Classical or standard Hough transform
* `HOUGH_PROBABILISTIC` - Probabilistic Hough transform (more efficient)
* `HOUGH_MULTI_SCALE` - Multi-scale variant of the classical Hough transform
* `HOUGH_GRADIENT` - 21HT for circles
* `HOUGH_GRADIENT_ALT` - Variation of HOUGH\_GRADIENT to get better accuracy
# Image Filtering
Source: https://opencv-opencv.mintlify.app/api/imgproc/filtering
Functions for performing linear and non-linear filtering operations on 2D images
This module provides functions to perform various linear or non-linear filtering operations on 2D images. For each pixel location in the source image, its neighborhood is considered and used to compute the response.
## Border Extrapolation
Many filtering functions need to extrapolate values of non-existing pixels (e.g., when processing pixels near image borders). OpenCV provides several border extrapolation methods via the `BorderTypes` enum.
## Smoothing Filters
### blur
Blurs an image using the normalized box filter.
```cpp theme={null}
void blur(InputArray src, OutputArray dst, Size ksize,
Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT);
```
Input image; it can have any number of channels, which are processed independently, but the depth should be CV\_8U, CV\_16U, CV\_16S, CV\_32F or CV\_64F.
Output image of the same size and type as src.
Blurring kernel size.
Anchor point; default value Point(-1,-1) means that the anchor is at the kernel center.
Border mode used to extrapolate pixels outside of the image. BORDER\_WRAP is not supported.
The function smooths an image using the kernel:
$$
\texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ 1 & 1 & 1 & \cdots & 1 & 1 \end{bmatrix}
$$
***
### GaussianBlur
Blurs an image using a Gaussian filter.
```cpp theme={null}
void GaussianBlur(InputArray src, OutputArray dst, Size ksize,
double sigmaX, double sigmaY = 0,
int borderType = BORDER_DEFAULT,
AlgorithmHint hint = cv::ALGO_HINT_DEFAULT);
```
Input image; the image can have any number of channels, which are processed independently, but the depth should be CV\_8U, CV\_16U, CV\_16S, CV\_32F or CV\_64F.
Output image of the same size and type as src.
Gaussian kernel size. ksize.width and ksize.height can differ but they both must be positive and odd. Or, they can be zeros and then they are computed from sigma.
Gaussian kernel standard deviation in X direction.
Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be equal to sigmaX.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The function convolves the source image with the specified Gaussian kernel. In-place filtering is supported.
***
### medianBlur
Blurs an image using the median filter.
```cpp theme={null}
void medianBlur(InputArray src, OutputArray dst, int ksize);
```
Input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image depth should be CV\_8U, CV\_16U, or CV\_32F, for larger aperture sizes, it can only be CV\_8U.
Destination array of the same size and type as src.
Aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ...
The function smoothes an image using the median filter with the ksize × ksize aperture. Each channel of a multi-channel image is processed independently. In-place operation is supported.
The median filter uses BORDER\_REPLICATE internally to cope with border pixels.
***
### bilateralFilter
Applies the bilateral filter to an image.
```cpp theme={null}
void bilateralFilter(InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT);
```
Source 8-bit or floating-point, 1-channel or 3-channel image.
Destination image of the same size and type as src.
Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, it is computed from sigmaSpace.
Filter sigma in the color space. A larger value means that farther colors within the pixel neighborhood will be mixed together.
Filter sigma in the coordinate space. A larger value means that farther pixels will influence each other as long as their colors are close enough.
Border mode used to extrapolate pixels outside of the image.
The bilateral filter can reduce unwanted noise very well while keeping edges fairly sharp. However, it is very slow compared to most filters.
**Sigma values**: For simplicity, you can set the 2 sigma values to be the same. If they are small (\< 10), the filter will not have much effect, whereas if they are large (> 150), they will have a very strong effect.
**Filter size**: Large filters (d > 5) are very slow, so it is recommended to use d=5 for real-time applications, and perhaps d=9 for offline applications.
This filter does not work inplace.
***
### boxFilter
Blurs an image using the box filter.
```cpp theme={null}
void boxFilter(InputArray src, OutputArray dst, int ddepth,
Size ksize, Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT);
```
Input image.
Output image of the same size and type as src.
The output image depth (-1 to use src.depth()).
Blurring kernel size.
Anchor point; default value Point(-1,-1) means that the anchor is at the kernel center.
Flag, specifying whether the kernel is normalized by its area or not.
Border mode used to extrapolate pixels outside of the image. BORDER\_WRAP is not supported.
Unnormalized box filter is useful for computing various integral characteristics over each pixel neighborhood, such as covariance matrices of image derivatives.
***
## Custom Filters
### filter2D
Convolves an image with the kernel.
```cpp theme={null}
void filter2D(InputArray src, OutputArray dst, int ddepth,
InputArray kernel, Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT);
```
Input image.
Output image of the same size and the same number of channels as src.
Desired depth of the destination image. See combinations in the documentation.
Convolution kernel (or rather a correlation kernel), a single-channel floating point matrix.
Anchor of the kernel that indicates the relative position of a filtered point within the kernel; default value (-1,-1) means that the anchor is at the kernel center.
Optional value added to the filtered pixels before storing them in dst.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The function applies an arbitrary linear filter to an image. In-place operation is supported. The function uses the DFT-based algorithm in case of sufficiently large kernels (\~11 x 11 or larger) and the direct algorithm for small kernels.
The function actually computes correlation, not convolution. If you need a real convolution, flip the kernel using flip() and set the new anchor.
***
### sepFilter2D
Applies a separable linear filter to an image.
```cpp theme={null}
void sepFilter2D(InputArray src, OutputArray dst, int ddepth,
InputArray kernelX, InputArray kernelY,
Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT);
```
Source image.
Destination image of the same size and the same number of channels as src.
Destination image depth.
Coefficients for filtering each row.
Coefficients for filtering each column.
Anchor position within the kernel. The default value (-1,-1) means that the anchor is at the kernel center.
Value added to the filtered results before storing them.
Pixel extrapolation method. BORDER\_WRAP is not supported.
The function applies a separable linear filter to the image. First, every row of src is filtered with the 1D kernel kernelX. Then, every column of the result is filtered with the 1D kernel kernelY.
***
## Helper Functions
### getGaussianKernel
Returns Gaussian filter coefficients.
```cpp theme={null}
Mat getGaussianKernel(int ksize, double sigma, int ktype = CV_64F);
```
Aperture size. It should be odd and positive.
Gaussian standard deviation. If it is non-positive, it is computed from ksize as sigma = 0.3\*((ksize-1)\*0.5 - 1) + 0.8.
Type of filter coefficients. It can be CV\_32F or CV\_64F.
The function computes and returns the ksize × 1 matrix of Gaussian filter coefficients. Two of such generated kernels can be passed to sepFilter2D or used with GaussianBlur.
***
### getDerivKernels
Returns filter coefficients for computing spatial image derivatives.
```cpp theme={null}
void getDerivKernels(OutputArray kx, OutputArray ky,
int dx, int dy, int ksize,
bool normalize = false, int ktype = CV_32F);
```
Output matrix of row filter coefficients.
Output matrix of column filter coefficients.
Derivative order in respect of x.
Derivative order in respect of y.
Aperture size. It can be FILTER\_SCHARR, 1, 3, 5, or 7.
Flag indicating whether to normalize (scale down) the filter coefficients or not.
Type of filter coefficients. It can be CV\_32F or CV\_64F.
The function computes and returns the filter coefficients for spatial image derivatives. When ksize=FILTER\_SCHARR, the Scharr 3 × 3 kernels are generated. Otherwise, Sobel kernels are generated.
***
### getStructuringElement
Returns a structuring element of the specified size and shape for morphological operations.
```cpp theme={null}
Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
```
Element shape that could be one of MorphShapes: MORPH\_RECT, MORPH\_CROSS, MORPH\_ELLIPSE, MORPH\_DIAMOND.
Size of the structuring element.
Anchor position within the element. The default value (-1, -1) means that the anchor is at the center.
The function constructs and returns the structuring element that can be further passed to erode, dilate or morphologyEx.
***
## Enumerations
### MorphShapes
Shape of the structuring element:
* `MORPH_RECT` - A rectangular structuring element
* `MORPH_CROSS` - A cross-shaped structuring element
* `MORPH_ELLIPSE` - An elliptic structuring element
* `MORPH_DIAMOND` - A diamond structuring element defined by Manhattan distance
### SpecialFilter
* `FILTER_SCHARR` - Scharr filter (-1)
# Geometric Image Transformations
Source: https://opencv-opencv.mintlify.app/api/imgproc/geometric
Functions for performing geometric transformations of 2D images
The functions in this module perform various geometrical transformations of 2D images. They do not change the image content but deform the pixel grid and map this deformed grid to the destination image.
## Image Resizing
### resize
Resizes an image.
```cpp theme={null}
void resize(InputArray src, OutputArray dst,
Size dsize, double fx = 0, double fy = 0,
int interpolation = INTER_LINEAR);
```
Input image.
Output image; it has the size dsize (when it is non-zero) or the size computed from src.size(), fx, and fy; the type of dst is the same as of src.
Output image size; if it equals zero, it is computed as dsize = Size(round(fx*src.cols), round(fy*src.rows)). Either dsize or both fx and fy must be non-zero.
Scale factor along the horizontal axis; when it equals 0, it is computed as (double)dsize.width/src.cols.
Scale factor along the vertical axis; when it equals 0, it is computed as (double)dsize.height/src.rows.
Interpolation method. See InterpolationFlags.
The function resize resizes the image src down to or up to the specified size.
```cpp theme={null}
// Explicitly specify dsize
resize(src, dst, Size(640, 480), 0, 0, INTER_LINEAR);
// Specify fx and fy
resize(src, dst, Size(), 0.5, 0.5, INTER_AREA);
```
```python theme={null}
# Explicitly specify dsize
dst = cv2.resize(src, (640, 480), interpolation=cv2.INTER_LINEAR)
# Specify fx and fy
dst = cv2.resize(src, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)
```
To shrink an image, it will generally look best with INTER\_AREA interpolation, whereas to enlarge an image, it will generally look best with INTER\_CUBIC (slow) or INTER\_LINEAR (faster but still looks OK).
***
## Affine Transformations
### warpAffine
Applies an affine transformation to an image.
```cpp theme={null}
void warpAffine(InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
```
Input image.
Output image that has the size dsize and the same type as src.
2×3 transformation matrix.
Size of the output image.
Combination of interpolation methods (see InterpolationFlags) and the optional flag WARP\_INVERSE\_MAP that means that M is the inverse transformation.
Pixel extrapolation method; when borderMode=BORDER\_TRANSPARENT, it means that the pixels in the destination image corresponding to the "outliers" in the source image are not modified by the function.
Value used in case of a constant border; by default, it is 0.
The function warpAffine transforms the source image using the specified matrix:
$$
\texttt{dst}(x,y) = \texttt{src}(M_{11} x + M_{12} y + M_{13}, M_{21} x + M_{22} y + M_{23})
$$
when the flag WARP\_INVERSE\_MAP is set. Otherwise, the transformation is first inverted with invertAffineTransform.
The function cannot operate in-place.
***
### getRotationMatrix2D
Calculates an affine matrix of 2D rotation.
```cpp theme={null}
Mat getRotationMatrix2D(Point2f center, double angle, double scale);
```
Center of the rotation in the source image.
Rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner).
Isotropic scale factor.
The function calculates the 2×3 rotation matrix. The transformation maps the rotation center to itself. If this is not the target, adjust the shift.
***
### getAffineTransform
Calculates an affine transform from three pairs of the corresponding points.
```cpp theme={null}
Mat getAffineTransform(const Point2f src[], const Point2f dst[]);
Mat getAffineTransform(InputArray src, InputArray dst);
```
Coordinates of triangle vertices in the source image.
Coordinates of the corresponding triangle vertices in the destination image.
The function calculates the 2 × 3 matrix of an affine transform so that the three source points are mapped to the three destination points.
***
### invertAffineTransform
Inverts an affine transformation.
```cpp theme={null}
void invertAffineTransform(InputArray M, OutputArray iM);
```
Original affine transformation.
Output reverse affine transformation.
The function computes an inverse affine transformation represented by 2 × 3 matrix M.
***
## Perspective Transformations
### warpPerspective
Applies a perspective transformation to an image.
```cpp theme={null}
void warpPerspective(InputArray src, OutputArray dst,
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
```
Input image.
Output image that has the size dsize and the same type as src.
3×3 transformation matrix.
Size of the output image.
Combination of interpolation methods (INTER\_LINEAR or INTER\_NEAREST) and the optional flag WARP\_INVERSE\_MAP.
Pixel extrapolation method (BORDER\_CONSTANT or BORDER\_REPLICATE).
Value used in case of a constant border; by default, it equals 0.
The function warpPerspective transforms the source image using the specified matrix:
$$
\texttt{dst}(x,y) = \texttt{src}\left(\frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}}, \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}}\right)
$$
when the flag WARP\_INVERSE\_MAP is set.
The function cannot operate in-place.
***
### getPerspectiveTransform
Calculates a perspective transform from four pairs of the corresponding points.
```cpp theme={null}
Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);
Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
```
Coordinates of quadrangle vertices in the source image.
Coordinates of the corresponding quadrangle vertices in the destination image.
Method passed to cv::solve.
The function calculates the 3 × 3 matrix of a perspective transform so that the four source points are mapped to the four destination points.
***
## Generic Remapping
### remap
Applies a generic geometrical transformation to an image.
```cpp theme={null}
void remap(InputArray src, OutputArray dst,
InputArray map1, InputArray map2,
int interpolation, int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
```
Source image.
Destination image. It has the same size as map1 and the same type as src.
The first map of either (x,y) points or just x values having the type CV\_16SC2, CV\_32FC1, or CV\_32FC2.
The second map of y values having the type CV\_16UC1, CV\_32FC1, or none (empty map if map1 is (x,y) points), respectively.
Interpolation method. The methods INTER\_AREA, INTER\_LINEAR\_EXACT and INTER\_NEAREST\_EXACT are not supported by this function.
Pixel extrapolation method. When borderMode=BORDER\_TRANSPARENT, it means that the pixels in the destination image that corresponds to the "outliers" in the source image are not modified by the function.
Value used in case of a constant border. By default, it is 0.
The function remap transforms the source image using the specified map:
$$
\texttt{dst}(x,y) = \texttt{src}(\texttt{map}_x(x,y), \texttt{map}_y(x,y))
$$
This function cannot operate in-place. Due to current implementation limitations the size of an input and output images should be less than 32767x32767.
***
### getRectSubPix
Retrieves a pixel rectangle from an image with sub-pixel accuracy.
```cpp theme={null}
void getRectSubPix(InputArray image, Size patchSize,
Point2f center, OutputArray patch, int patchType = -1);
```
Source image.
Size of the extracted patch.
Floating point coordinates of the center of the extracted rectangle within the source image. The center must be inside the image.
Extracted patch that has the size patchSize and the same number of channels as src.
Depth of the extracted pixels. By default, they have the same depth as src.
The function getRectSubPix extracts pixels from src using bilinear interpolation. While the center of the rectangle must be inside the image, parts of the rectangle may be outside.
***
## Enumerations
### InterpolationFlags
Interpolation algorithm:
* `INTER_NEAREST` - Nearest neighbor interpolation
* `INTER_LINEAR` - Bilinear interpolation
* `INTER_CUBIC` - Bicubic interpolation
* `INTER_AREA` - Resampling using pixel area relation (preferred for image decimation)
* `INTER_LANCZOS4` - Lanczos interpolation over 8x8 neighborhood
* `INTER_LINEAR_EXACT` - Bit exact bilinear interpolation
* `INTER_NEAREST_EXACT` - Bit exact nearest neighbor interpolation
* `INTER_MAX` - Mask for interpolation codes
* `WARP_FILL_OUTLIERS` - Flag, fills all of the destination image pixels
* `WARP_INVERSE_MAP` - Flag, inverse transformation
### WarpPolarMode
Polar mapping mode:
* `WARP_POLAR_LINEAR` - Remaps an image to/from polar space
* `WARP_POLAR_LOG` - Remaps an image to/from semilog-polar space
# Classification Algorithms
Source: https://opencv-opencv.mintlify.app/api/ml/classification
Machine learning classification algorithms including SVM, K-Nearest Neighbors, Decision Trees, Boosting, Random Trees, and Naive Bayes classifier
The OpenCV Machine Learning module provides several powerful classification algorithms for supervised learning tasks.
## SVM - Support Vector Machines
Support Vector Machines are powerful classifiers that work well for both linear and non-linear classification problems.
### Creating an SVM Model
```cpp theme={null}
Ptr svm = SVM::create();
```
### Key Methods
Sets the type of SVM formulation
**Parameters:**
* `val` (int): SVM type. See `SVM::Types`
**Types:**
* `SVM::C_SVC` (100): C-Support Vector Classification for n-class classification
* `SVM::NU_SVC` (101): ν-Support Vector Classification with parameter ν
* `SVM::ONE_CLASS` (102): Distribution Estimation (One-class SVM)
* `SVM::EPS_SVR` (103): ε-Support Vector Regression
* `SVM::NU_SVR` (104): ν-Support Vector Regression
Initialize with one of predefined kernels
**Parameters:**
* `kernelType` (int): Kernel type. See `SVM::KernelTypes`
**Kernel Types:**
* `SVM::LINEAR` (0): Linear kernel, no mapping done
* `SVM::POLY` (1): Polynomial kernel
* `SVM::RBF` (2): Radial basis function, good choice in most cases
* `SVM::SIGMOID` (3): Sigmoid kernel
* `SVM::CHI2` (4): Exponential Chi2 kernel
* `SVM::INTER` (5): Histogram intersection kernel
Sets parameter C of a SVM optimization problem
**Parameters:**
* `val` (double): Parameter C for C\_SVC, EPS\_SVR or NU\_SVR
Sets parameter γ of a kernel function
**Parameters:**
* `val` (double): Parameter gamma for POLY, RBF, SIGMOID or CHI2 kernels
Trains the SVM model
**Parameters:**
* `trainData` (Ptr\): Training data
* `flags` (int): Optional flags
**Returns:** bool - true if training succeeded
Predicts response for input samples
**Parameters:**
* `samples` (InputArray): Input samples, floating-point matrix
* `results` (OutputArray): Optional output matrix of results
* `flags` (int): Optional flags
**Returns:** float - predicted response for single sample
Trains an SVM with optimal parameters using cross-validation
**Parameters:**
* `data` (Ptr\): Training data
* `kFold` (int): Cross-validation parameter (default: 10)
* `Cgrid` (ParamGrid): Grid for C parameter
* `gammaGrid` (ParamGrid): Grid for gamma parameter
* `pGrid` (ParamGrid): Grid for p parameter
* `nuGrid` (ParamGrid): Grid for nu parameter
* `coeffGrid` (ParamGrid): Grid for coeff parameter
* `degreeGrid` (ParamGrid): Grid for degree parameter
* `balanced` (bool): Create balanced cross-validation subsets
**Returns:** bool - true if training succeeded
Retrieves all the support vectors
**Returns:** Mat - matrix where support vectors are stored as rows
### Example Usage
```cpp theme={null}
#include
using namespace cv::ml;
// Create and configure SVM
Ptr svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::RBF);
svm->setGamma(0.5);
svm->setC(1.0);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
// Train the SVM
Ptr trainData = TrainData::create(samples, ROW_SAMPLE, labels);
svm->train(trainData);
// Predict
Mat results;
svm->predict(testSamples, results);
```
```python theme={null}
import cv2 as cv
import numpy as np
# Create and configure SVM
svm = cv.ml.SVM_create()
svm.setType(cv.ml.SVM_C_SVC)
svm.setKernel(cv.ml.SVM_RBF)
svm.setGamma(0.5)
svm.setC(1.0)
svm.setTermCriteria((cv.TERM_CRITERIA_MAX_ITER, 100, 1e-6))
# Train the SVM
svm.train(samples, cv.ml.ROW_SAMPLE, labels)
# Predict
result = svm.predict(test_samples)
```
***
## KNearest - K-Nearest Neighbors
The K-Nearest Neighbors algorithm finds the k nearest neighbors and predicts the response based on their values.
### Creating a KNearest Model
```cpp theme={null}
Ptr knn = KNearest::create();
```
### Key Methods
Sets the default number of neighbors to use in predict method
**Parameters:**
* `val` (int): Number of neighbors (must be greater than 1)
Sets whether classification or regression model should be trained
**Parameters:**
* `val` (bool): true for classification, false for regression
Sets the algorithm type
**Parameters:**
* `val` (int): Algorithm type
**Types:**
* `KNearest::BRUTE_FORCE` (1): Brute force search
* `KNearest::KDTREE` (2): KD-tree based search
Finds the neighbors and predicts responses for input vectors
**Parameters:**
* `samples` (InputArray): Input samples (rows are samples)
* `k` (int): Number of nearest neighbors
* `results` (OutputArray): Vector with prediction results
* `neighborResponses` (OutputArray): Optional output for neighbor responses
* `dist` (OutputArray): Optional output distances to neighbors
**Returns:** float - predicted value for single input vector
### Example Usage
```cpp theme={null}
#include
using namespace cv::ml;
// Create KNN classifier
Ptr knn = KNearest::create();
knn->setDefaultK(5);
knn->setIsClassifier(true);
knn->setAlgorithmType(KNearest::BRUTE_FORCE);
// Train
knn->train(trainSamples, ROW_SAMPLE, trainLabels);
// Predict
Mat results, neighbors, distances;
knn->findNearest(testSamples, 5, results, neighbors, distances);
```
***
## DTrees - Decision Trees
Decision trees are tree-based classifiers that split data based on feature values.
### Creating a Decision Tree Model
```cpp theme={null}
Ptr dtree = DTrees::create();
```
### Key Methods
Sets the maximum possible depth of the tree
**Parameters:**
* `val` (int): Maximum depth (root node has depth 0)
Sets the minimum number of samples required to split a node
**Parameters:**
* `val` (int): Minimum sample count (default: 10)
Sets the maximum number of categories for clustering
**Parameters:**
* `val` (int): Maximum categories (default: 10)
Sets the number of folds for cross-validation pruning
**Parameters:**
* `val` (int): Number of folds (default: 10)
Sets a priori class probabilities
**Parameters:**
* `val` (Mat): Array of class probabilities sorted by label
### Example Usage
```cpp theme={null}
// Create and configure decision tree
Ptr dtree = DTrees::create();
dtree->setMaxDepth(10);
dtree->setMinSampleCount(10);
dtree->setCVFolds(10);
// Train
dtree->train(trainData);
// Predict
float response = dtree->predict(testSample);
```
***
## Boost - Boosted Trees
Boosted tree classifier that combines multiple weak classifiers into a strong one.
### Creating a Boost Model
```cpp theme={null}
Ptr boost = Boost::create();
```
### Key Methods
Sets the type of boosting algorithm
**Parameters:**
* `val` (int): Boost type
**Types:**
* `Boost::DISCRETE` (0): Discrete AdaBoost
* `Boost::REAL` (1): Real AdaBoost (default, works well with categorical data)
* `Boost::LOGIT` (2): LogitBoost (good for regression)
* `Boost::GENTLE` (3): Gentle AdaBoost (good with regression data)
Sets the number of weak classifiers
**Parameters:**
* `val` (int): Number of weak classifiers (default: 100)
Sets the threshold for computational time savings
**Parameters:**
* `val` (double): Weight trim rate between 0 and 1 (default: 0.95)
### Example Usage
```cpp theme={null}
// Create and configure Boost
Ptr boost = Boost::create();
boost->setBoostType(Boost::REAL);
boost->setWeakCount(100);
boost->setWeightTrimRate(0.95);
boost->setMaxDepth(1);
// Train
boost->train(trainData);
// Predict
float result = boost->predict(testSample);
```
***
## RTrees - Random Trees (Random Forest)
Random Forest is an ensemble learning method that constructs multiple decision trees.
### Creating a Random Trees Model
```cpp theme={null}
Ptr rtrees = RTrees::create();
```
### Key Methods
Enable/disable variable importance calculation
**Parameters:**
* `val` (bool): true to calculate variable importance
Sets the size of randomly selected subset of features at each tree node
**Parameters:**
* `val` (int): Number of active variables (0 = sqrt of total features)
Sets termination criteria for training
**Parameters:**
* `val` (TermCriteria): Criteria specifying max iterations or accuracy
Returns the variable importance array
**Returns:** Mat - variable importance vector (if enabled during training)
Returns the result of each individual tree in the forest
**Parameters:**
* `samples` (InputArray): Samples for which votes will be calculated
* `results` (OutputArray): Matrix where results will be written
* `flags` (int): Flags for defining the type of RTrees
### Example Usage
```cpp theme={null}
// Create and configure Random Forest
Ptr rtrees = RTrees::create();
rtrees->setMaxDepth(10);
rtrees->setMinSampleCount(10);
rtrees->setCalculateVarImportance(true);
rtrees->setActiveVarCount(0); // sqrt of total features
rtrees->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 0));
// Train
rtrees->train(trainData);
// Get variable importance
Mat varImportance = rtrees->getVarImportance();
// Predict
float result = rtrees->predict(testSample);
```
***
## NormalBayesClassifier - Naive Bayes
Bayes classifier for normally distributed data using Bayesian statistics.
### Creating a Naive Bayes Model
```cpp theme={null}
Ptr bayes = NormalBayesClassifier::create();
```
### Key Methods
Trains the Bayes classifier
**Parameters:**
* `trainData` (Ptr\): Training data
* `flags` (int): Optional flags
**Returns:** bool - true if training succeeded
Predicts response for input samples
**Parameters:**
* `samples` (InputArray): Input samples
* `results` (OutputArray): Output predictions
* `flags` (int): Optional flags
**Returns:** float - predicted class for single sample
Predicts the response and returns probabilities
**Parameters:**
* `inputs` (InputArray): Input vectors (one or more)
* `outputs` (OutputArray): Predicted classes
* `outputProbs` (OutputArray): Output probabilities for each class
* `flags` (int): Optional flags
**Returns:** float - predicted class for single input
### Example Usage
```cpp theme={null}
// Create Naive Bayes classifier
Ptr bayes = NormalBayesClassifier::create();
// Train
bayes->train(trainData);
// Predict with probabilities
Mat results, probs;
bayes->predictProb(testSamples, results, probs);
```
The Naive Bayes classifier assumes that features are normally distributed and independent. It works best when these assumptions hold true.
## See Also
* [Regression Algorithms](/api/ml/regression) - Linear and logistic regression methods
* [Clustering Algorithms](/api/ml/clustering) - K-means and EM clustering
* [StatModel Base Class](https://docs.opencv.org/4.x/dd/ded/classcv_1_1ml_1_1StatModel.html) - Base class for all ML models
# Clustering Algorithms
Source: https://opencv-opencv.mintlify.app/api/ml/clustering
Unsupervised machine learning clustering algorithms including k-means and Expectation Maximization (EM) for Gaussian mixture models
Clustering algorithms group data points into clusters based on their similarity without requiring labeled training data.
## kmeans - K-Means Clustering
The k-means algorithm finds centers of clusters and groups input samples around the clusters. It's one of the most popular clustering algorithms.
### Function Signature
```cpp theme={null}
double cv::kmeans(
InputArray data,
int K,
InputOutputArray bestLabels,
TermCriteria criteria,
int attempts,
int flags,
OutputArray centers = noArray()
);
```
### Parameters
Data for clustering. An array of N-dimensional points with float coordinates.
Examples:
* `Mat points(count, 2, CV_32F)` - 2D points as rows
* `Mat points(count, 1, CV_32FC2)` - 2D points as single channel
* `Mat points(1, count, CV_32FC2)` - 2D points as columns
* `std::vector points(sampleCount)` - vector of points
Number of clusters to split the set by. Must be at least 2.
Input/output integer array that stores the cluster indices for every sample.
Each element is in the range \[0, K-1] indicating which cluster the sample belongs to.
The algorithm termination criteria: maximum number of iterations and/or desired accuracy.
The accuracy is specified as `criteria.epsilon`. The algorithm stops when each cluster center moves by less than epsilon.
Example: `TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 100, 0.01)`
Number of times the algorithm is executed using different initial labellings.
The algorithm returns the labels that yield the best compactness. Use at least 3 attempts for better results.
Flag specifying the method for center initialization.
**Flags:**
* `KMEANS_RANDOM_CENTERS` (0): Select random initial centers in each attempt
* `KMEANS_PP_CENTERS` (2): Use kmeans++ center initialization (recommended)
* `KMEANS_USE_INITIAL_LABELS` (1): Use user-supplied labels for first attempt
Output matrix of the cluster centers, one row per each cluster center.
Size: K × dimensions
### Returns
**Type:** `double`
The function returns the compactness measure computed as:
$\sum_i \|\text{samples}_i - \text{centers}_{\text{labels}_i}\|^2$
The best (minimum) compactness value is chosen among all attempts, and the corresponding labels and cluster centers are returned.
### Example Usage
```cpp theme={null}
#include
#include
#include
using namespace cv;
using namespace std;
int main() {
// Generate random 2D points
int sampleCount = 100;
Mat points(sampleCount, 2, CV_32F);
randu(points, Scalar(0, 0), Scalar(100, 100));
// K-means parameters
int K = 3;
Mat labels;
Mat centers;
TermCriteria criteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 100, 0.01);
// Run k-means
double compactness = kmeans(
points,
K,
labels,
criteria,
3, // attempts
KMEANS_PP_CENTERS,
centers
);
cout << "Compactness: " << compactness << endl;
cout << "Centers:\n" << centers << endl;
// Access cluster labels
for (int i = 0; i < 10; i++) {
cout << "Point " << i << " belongs to cluster "
<< labels.at(i) << endl;
}
return 0;
}
```
```python theme={null}
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# Generate random 2D points
points = np.random.randint(0, 100, (100, 2)).astype(np.float32)
# K-means parameters
K = 3
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.01)
# Run k-means
compactness, labels, centers = cv.kmeans(
points,
K,
None,
criteria,
attempts=3,
flags=cv.KMEANS_PP_CENTERS
)
print(f"Compactness: {compactness}")
print(f"Centers:\n{centers}")
# Visualize results
colors = ['red', 'blue', 'green']
for i in range(K):
cluster_points = points[labels.flatten() == i]
plt.scatter(cluster_points[:, 0], cluster_points[:, 1],
c=colors[i], label=f'Cluster {i}')
plt.scatter(centers[:, 0], centers[:, 1],
marker='x', s=200, c='black', label='Centers')
plt.legend()
plt.show()
```
For best results, use `KMEANS_PP_CENTERS` flag which implements the kmeans++ initialization algorithm by Arthur and Vassilvitskii. This provides better initial centers than random selection.
***
## EM - Expectation Maximization
The Expectation Maximization algorithm implements Gaussian Mixture Models (GMM) for clustering. It models data as a mixture of multiple Gaussian distributions.
### Creating an EM Model
```cpp theme={null}
Ptr em = EM::create();
```
### Key Methods
Sets the number of mixture components
**Parameters:**
* `val` (int): Number of clusters/mixtures (default: 5)
Sets the constraint on covariance matrices
**Parameters:**
* `val` (int): Type of covariance matrices
**Types:**
* `EM::COV_MAT_SPHERICAL` (0): Scaled identity matrix μ\_k \* I
* `EM::COV_MAT_DIAGONAL` (1): Diagonal matrix with positive diagonal elements (recommended)
* `EM::COV_MAT_GENERIC` (2): Symmetric positive definite matrix
Sets the termination criteria of the EM algorithm
**Parameters:**
* `val` (TermCriteria): Criteria for max iterations or likelihood change
The EM algorithm terminates when:
* Maximum number of iterations (M-steps) is reached, OR
* Relative change of likelihood logarithm is less than epsilon
Default: `TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 100, epsilon)`
Estimates Gaussian mixture parameters from a sample set (Expectation step start)
**Parameters:**
* `samples` (InputArray): Samples from which GMM will be estimated (CV\_64F or will be converted)
* `logLikelihoods` (OutputArray): Optional output matrix of likelihood logarithm values
* `labels` (OutputArray): Optional output "class label" for each sample
* `probs` (OutputArray): Optional posterior probabilities matrix (nsamples × nclusters)
**Returns:** bool - true if training succeeded
This variation starts with Expectation step. Initial values are estimated by k-means algorithm.
Estimates Gaussian mixture parameters with initial means provided
**Parameters:**
* `samples` (InputArray): Training samples matrix
* `means0` (InputArray): Initial means of mixture components (nclusters × dims)
* `covs0` (InputArray): Optional initial covariance matrices
* `weights0` (InputArray): Optional initial weights of mixture components
* `logLikelihoods` (OutputArray): Optional likelihood logarithm output
* `labels` (OutputArray): Optional cluster labels output
* `probs` (OutputArray): Optional posterior probabilities output
**Returns:** bool - true if training succeeded
Estimates Gaussian mixture parameters starting with Maximization step
**Parameters:**
* `samples` (InputArray): Training samples
* `probs0` (InputArray): Initial probabilities
* `logLikelihoods` (OutputArray): Optional likelihood output
* `labels` (OutputArray): Optional labels output
* `probs` (OutputArray): Optional probabilities output
**Returns:** bool - true if training succeeded
Returns posterior probabilities for the provided samples
**Parameters:**
* `samples` (InputArray): Input samples matrix
* `results` (OutputArray): Optional output matrix of results (nsamples × nclusters)
* `flags` (int): Optional flags (ignored)
**Returns:** float - predicted class for single sample
Returns likelihood logarithm value and index of most probable mixture component
**Parameters:**
* `sample` (InputArray): A sample for classification (1 × dims or dims × 1)
* `probs` (OutputArray): Optional posterior probabilities (1 × nclusters, CV\_64FC1)
**Returns:** Vec2d
* Element \[0]: Likelihood logarithm value
* Element \[1]: Index of most probable mixture component
Returns weights of the mixtures
**Returns:** Mat - vector with number of elements equal to number of mixtures
Returns the cluster centers (means of the Gaussian mixture)
**Returns:** Mat - matrix with rows = number of mixtures, cols = space dimensionality
Returns covariance matrices
**Parameters:**
* `covs` (std::vector\&): Output vector of covariance matrices
Returns vector of covariation matrices (one per mixture, each is NxN where N is dimensionality)
### Example Usage
```cpp theme={null}
#include
#include
using namespace cv;
using namespace cv::ml;
using namespace std;
int main() {
// Generate sample data
Mat samples(300, 2, CV_32F);
randn(samples.rowRange(0, 100), Scalar(0, 0), Scalar(10, 10));
randn(samples.rowRange(100, 200), Scalar(50, 50), Scalar(10, 10));
randn(samples.rowRange(200, 300), Scalar(25, 75), Scalar(10, 10));
// Create and configure EM
Ptr em = EM::create();
em->setClustersNumber(3);
em->setCovarianceMatrixType(EM::COV_MAT_DIAGONAL);
em->setTermCriteria(TermCriteria(
TermCriteria::MAX_ITER + TermCriteria::EPS,
100,
0.1
));
// Train EM model
Mat labels, probs, logLikelihoods;
em->trainEM(samples, logLikelihoods, labels, probs);
// Get model parameters
Mat means = em->getMeans();
Mat weights = em->getWeights();
vector covs;
em->getCovs(covs);
cout << "Means:\n" << means << endl;
cout << "Weights:\n" << weights << endl;
// Predict for new sample
Mat testSample = (Mat_(1, 2) << 5.0, 5.0);
Mat outputProbs;
Vec2d prediction = em->predict2(testSample, outputProbs);
cout << "Log likelihood: " << prediction[0] << endl;
cout << "Most probable cluster: " << prediction[1] << endl;
cout << "Probabilities: " << outputProbs << endl;
return 0;
}
```
```python theme={null}
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# Generate sample data (3 Gaussian clusters)
samples1 = np.random.randn(100, 2) * 10 + [0, 0]
samples2 = np.random.randn(100, 2) * 10 + [50, 50]
samples3 = np.random.randn(100, 2) * 10 + [25, 75]
samples = np.vstack([samples1, samples2, samples3]).astype(np.float32)
# Create and configure EM
em = cv.ml.EM_create()
em.setClustersNumber(3)
em.setCovarianceMatrixType(cv.ml.EM_COV_MAT_DIAGONAL)
em.setTermCriteria((cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS,
100, 0.1))
# Train EM model
em.trainEM(samples)
# Get model parameters
means = em.getMeans()
weights = em.getWeights()
print(f"Means:\n{means}")
print(f"Weights:\n{weights}")
# Predict for new samples
retval, probs = em.predict(samples)
labels = probs.argmax(axis=1)
# Visualize
colors = ['red', 'blue', 'green']
for i in range(3):
cluster_points = samples[labels == i]
plt.scatter(cluster_points[:, 0], cluster_points[:, 1],
c=colors[i], label=f'Cluster {i}')
plt.scatter(means[:, 0], means[:, 1],
marker='x', s=200, c='black', label='Means')
plt.legend()
plt.title('EM Clustering')
plt.show()
```
### When to Use EM vs K-Means
**Use EM when:**
* Clusters have different shapes and sizes
* You need probabilistic cluster assignments
* Data follows Gaussian distributions
* You want to model uncertainty in cluster membership
**Use K-Means when:**
* Clusters are roughly spherical and similar in size
* You need hard cluster assignments
* Speed is critical (K-means is faster)
* You have very large datasets
The EM algorithm is more flexible than k-means as it can model elliptical clusters with different orientations and sizes. However, it's more computationally expensive and requires more samples for reliable estimation.
## See Also
* [Classification Algorithms](/api/ml/classification) - SVM, KNN, Decision Trees, and more
* [Regression Algorithms](/api/ml/regression) - Linear and logistic regression methods
* [TrainData Class](https://docs.opencv.org/4.x/dc/d32/classcv_1_1ml_1_1TrainData.html) - Managing training data
# Regression Algorithms
Source: https://opencv-opencv.mintlify.app/api/ml/regression
Machine learning regression algorithms including Logistic Regression and linear regression methods for predicting continuous and categorical outputs
Regression algorithms predict continuous or categorical output values based on input features.
## LogisticRegression - Logistic Regression Classifier
Logistic Regression is a statistical method for binary and multi-class classification problems. Despite its name, it's primarily used for classification rather than regression.
### Creating a Logistic Regression Model
```cpp theme={null}
Ptr lr = LogisticRegression::create();
```
### Key Methods
Sets the learning rate for gradient descent
**Parameters:**
* `val` (double): Learning rate (step size for parameter updates)
Typical values: 0.001 to 0.1. Higher values train faster but may overshoot the optimal solution.
Sets the number of training iterations
**Parameters:**
* `val` (int): Maximum number of iterations
More iterations can lead to better convergence but increase training time.
Sets the kind of regularization to be applied
**Parameters:**
* `val` (int): Regularization type
**Types:**
* `LogisticRegression::REG_DISABLE` (-1): No regularization
* `LogisticRegression::REG_L1` (0): L1 norm regularization (promotes sparsity)
* `LogisticRegression::REG_L2` (1): L2 norm regularization (prevents overfitting)
Sets the training method used
**Parameters:**
* `val` (int): Training method
**Methods:**
* `LogisticRegression::BATCH` (0): Batch gradient descent
* `LogisticRegression::MINI_BATCH` (1): Mini-batch gradient descent
Sets the number of training samples taken in each Mini-Batch Gradient Descent step
**Parameters:**
* `val` (int): Mini-batch size (must be less than total training samples)
Only used when training method is `MINI_BATCH`. Smaller batches provide more frequent updates but noisier gradients.
Sets the termination criteria of the algorithm
**Parameters:**
* `val` (TermCriteria): Criteria for stopping training
Example: `TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.001)`
Trains the logistic regression model
**Parameters:**
* `samples` (InputArray): Training samples (CV\_32F type)
* `layout` (int): Sample layout (ROW\_SAMPLE or COL\_SAMPLE)
* `responses` (InputArray): Training labels/responses
**Returns:** bool - true if training succeeded
Predicts responses for input samples
**Parameters:**
* `samples` (InputArray): Input data for prediction (CV\_32F type, m × n matrix)
* `results` (OutputArray): Predicted labels as column matrix (CV\_32S type)
* `flags` (int): Optional flags (not used)
**Returns:** float - predicted value for single sample
Returns the trained parameters
**Returns:** Mat - learnt parameters of Logistic Regression (CV\_32F type)
For two-class classification, returns a row matrix. These are the weights/coefficients learned during training.
### Example Usage
```cpp theme={null}
#include
#include
using namespace cv;
using namespace cv::ml;
using namespace std;
int main() {
// Prepare training data (binary classification)
Mat trainData = (Mat_(6, 2) <<
1.0, 1.0, // Class 0
2.0, 1.0,
1.0, 2.0,
6.0, 6.0, // Class 1
5.0, 6.0,
6.0, 5.0
);
Mat labels = (Mat_(6, 1) << 0, 0, 0, 1, 1, 1);
// Create and configure Logistic Regression
Ptr lr = LogisticRegression::create();
lr->setLearningRate(0.001);
lr->setIterations(10000);
lr->setRegularization(LogisticRegression::REG_L2);
lr->setTrainMethod(LogisticRegression::BATCH);
lr->setMiniBatchSize(1);
// Train the model
Ptr tData = TrainData::create(
trainData, ROW_SAMPLE, labels
);
lr->train(tData);
// Get learned parameters
Mat theta = lr->get_learnt_thetas();
cout << "Learned parameters (theta):\n" << theta << endl;
// Predict on test data
Mat testData = (Mat_(2, 2) <<
1.5, 1.5, // Should predict class 0
5.5, 5.5 // Should predict class 1
);
Mat predictions;
lr->predict(testData, predictions);
cout << "Predictions:\n" << predictions << endl;
// Evaluate accuracy
Mat trainPredictions;
lr->predict(trainData, trainPredictions);
int correct = 0;
for (int i = 0; i < labels.rows; i++) {
if (trainPredictions.at(i) == labels.at(i))
correct++;
}
cout << "Training accuracy: "
<< (100.0 * correct / labels.rows) << "%" << endl;
return 0;
}
```
```python theme={null}
import cv2 as cv
import numpy as np
# Prepare training data (binary classification)
train_data = np.array([
[1.0, 1.0], # Class 0
[2.0, 1.0],
[1.0, 2.0],
[6.0, 6.0], # Class 1
[5.0, 6.0],
[6.0, 5.0]
], dtype=np.float32)
labels = np.array([[0], [0], [0], [1], [1], [1]], dtype=np.int32)
# Create and configure Logistic Regression
lr = cv.ml.LogisticRegression_create()
lr.setLearningRate(0.001)
lr.setIterations(10000)
lr.setRegularization(cv.ml.LogisticRegression_REG_L2)
lr.setTrainMethod(cv.ml.LogisticRegression_BATCH)
lr.setMiniBatchSize(1)
# Train the model
lr.train(train_data, cv.ml.ROW_SAMPLE, labels)
# Get learned parameters
theta = lr.get_learnt_thetas()
print(f"Learned parameters (theta):\n{theta}")
# Predict on test data
test_data = np.array([
[1.5, 1.5], # Should predict class 0
[5.5, 5.5] # Should predict class 1
], dtype=np.float32)
retval, predictions = lr.predict(test_data)
print(f"Predictions:\n{predictions}")
# Evaluate accuracy
retval, train_predictions = lr.predict(train_data)
accuracy = np.mean(train_predictions.flatten() == labels.flatten()) * 100
print(f"Training accuracy: {accuracy}%")
```
### Multi-Class Classification
For multi-class problems (more than 2 classes), Logistic Regression uses a one-vs-rest approach:
```cpp theme={null}
// Multi-class example (3 classes)
Mat trainData = (Mat_(9, 2) <<
1.0, 1.0, // Class 0
2.0, 1.0,
1.0, 2.0,
6.0, 6.0, // Class 1
5.0, 6.0,
6.0, 5.0,
3.0, 8.0, // Class 2
4.0, 9.0,
3.5, 8.5
);
Mat labels = (Mat_(9, 1) << 0, 0, 0, 1, 1, 1, 2, 2, 2);
// Train and predict as before
Ptr lr = LogisticRegression::create();
lr->setLearningRate(0.01);
lr->setIterations(5000);
lr->train(trainData, ROW_SAMPLE, labels);
Mat predictions;
lr->predict(testData, predictions);
```
For binary classification, ensure your labels are 0 and 1. For multi-class classification, use consecutive integers starting from 0 (e.g., 0, 1, 2, 3...).
***
## Linear Regression with Normal Equations
While OpenCV doesn't have a dedicated linear regression class, you can perform linear regression using the `solve()` function with normal equations or use the `SVM` class with `SVM::EPS_SVR` type.
### Method 1: Using Normal Equations
Linear regression can be solved directly using the normal equation: θ = (X^T X)^(-1) X^T y
```cpp theme={null}
#include
#include
using namespace cv;
using namespace std;
int main() {
// Training data: y = 2x + 3
Mat X = (Mat_(5, 2) <<
1.0, 1.0,
1.0, 2.0,
1.0, 3.0,
1.0, 4.0,
1.0, 5.0
); // First column is bias term (1s)
Mat y = (Mat_(5, 1) << 5.0, 7.0, 9.0, 11.0, 13.0);
// Solve normal equation: theta = (X^T * X)^(-1) * X^T * y
Mat theta;
solve(X, y, theta, DECOMP_SVD);
cout << "Learned parameters:\n" << theta << endl;
// Should be approximately [3.0, 2.0] (intercept, slope)
// Make predictions
Mat testX = (Mat_(3, 2) <<
1.0, 6.0,
1.0, 7.0,
1.0, 8.0
);
Mat predictions = testX * theta;
cout << "Predictions:\n" << predictions << endl;
return 0;
}
```
### Method 2: Using SVM for Regression
For more robust regression with regularization, use `SVM::EPS_SVR`:
```cpp theme={null}
#include
using namespace cv;
using namespace cv::ml;
// Prepare training data
Mat trainData = (Mat_(5, 1) << 1.0, 2.0, 3.0, 4.0, 5.0);
Mat responses = (Mat_(5, 1) << 5.0, 7.0, 9.0, 11.0, 13.0);
// Create SVM for regression
Ptr svm = SVM::create();
svm->setType(SVM::EPS_SVR);
svm->setKernel(SVM::LINEAR);
svm->setC(1.0);
svm->setP(0.1); // epsilon parameter
// Train
Ptr tData = TrainData::create(
trainData, ROW_SAMPLE, responses
);
svm->train(tData);
// Predict
Mat testData = (Mat_(3, 1) << 6.0, 7.0, 8.0);
Mat predictions;
svm->predict(testData, predictions);
```
### Method 3: Using Decision Trees for Regression
`DTrees` can also be used for regression by setting appropriate parameters:
```cpp theme={null}
#include
using namespace cv::ml;
Ptr dtree = DTrees::create();
dtree->setMaxDepth(10);
dtree->setMinSampleCount(2);
dtree->setRegressionAccuracy(0.01f);
// Train with continuous response values
Ptr trainData = TrainData::create(
samples,
ROW_SAMPLE,
continuousResponses // Regression targets
);
dtree->train(trainData);
// Predict
float prediction = dtree->predict(testSample);
```
***
## Polynomial Regression
For polynomial regression, transform your input features to include polynomial terms:
```cpp theme={null}
#include
using namespace cv;
// Function to create polynomial features
Mat createPolynomialFeatures(const Mat& X, int degree) {
int rows = X.rows;
int cols = X.cols;
// Calculate number of output features
int outCols = 1; // bias term
for (int d = 1; d <= degree; d++) {
outCols += cols; // Add linear terms, squared terms, etc.
}
Mat polyFeatures(rows, outCols, CV_32F);
for (int i = 0; i < rows; i++) {
int colIdx = 0;
polyFeatures.at(i, colIdx++) = 1.0f; // bias
for (int d = 1; d <= degree; d++) {
for (int j = 0; j < cols; j++) {
float val = X.at(i, j);
polyFeatures.at(i, colIdx++) = pow(val, d);
}
}
}
return polyFeatures;
}
// Example usage
Mat X = (Mat_(5, 1) << 1.0, 2.0, 3.0, 4.0, 5.0);
Mat y = (Mat_(5, 1) << 1.0, 4.0, 9.0, 16.0, 25.0); // y = x^2
// Create polynomial features (degree 2)
Mat X_poly = createPolynomialFeatures(X, 2);
// Solve using normal equations
Mat theta;
solve(X_poly, y, theta, DECOMP_SVD);
```
When using polynomial features, consider normalizing your data first to prevent numerical instability. Higher degree polynomials can lead to overfitting.
***
## Regularized Regression
For Ridge Regression (L2 regularization), modify the normal equation:
θ = (X^T X + λI)^(-1) X^T y
```cpp theme={null}
Mat XtX = X.t() * X;
Mat identity = Mat::eye(XtX.rows, XtX.cols, XtX.type());
float lambda = 0.1; // Regularization parameter
Mat regularized = XtX + lambda * identity;
Mat Xty = X.t() * y;
Mat theta;
solve(regularized, Xty, theta, DECOMP_CHOLESKY);
```
***
## Best Practices
### Feature Scaling
Always normalize features when using gradient-based methods:
```cpp theme={null}
// Normalize features to [0, 1] or standardize to mean=0, std=1
Mat mean, stddev;
cv::meanStdDev(trainData, mean, stddev);
Mat normalizedData = (trainData - mean) / stddev;
```
### Cross-Validation
Use cross-validation to evaluate model performance:
```cpp theme={null}
Ptr data = TrainData::create(
samples, ROW_SAMPLE, responses
);
// Split into train and test
data->setTrainTestSplitRatio(0.8, true);
Ptr lr = LogisticRegression::create();
lr->train(data->getTrainSamples(),
ROW_SAMPLE,
data->getTrainResponses());
float trainError = lr->calcError(data, false, noArray());
float testError = lr->calcError(data, true, noArray());
```
### Hyperparameter Tuning
Try different learning rates and regularization parameters:
```cpp theme={null}
vector learningRates = {0.001, 0.01, 0.1};
vector regularizations = {
LogisticRegression::REG_DISABLE,
LogisticRegression::REG_L1,
LogisticRegression::REG_L2
};
float bestError = FLT_MAX;
Ptr bestModel;
for (double lr : learningRates) {
for (int reg : regularizations) {
Ptr model = LogisticRegression::create();
model->setLearningRate(lr);
model->setRegularization(reg);
model->train(trainData);
float error = model->calcError(testData, true, noArray());
if (error < bestError) {
bestError = error;
bestModel = model;
}
}
}
```
## See Also
* [Classification Algorithms](/api/ml/classification) - SVM, Decision Trees, and classifiers
* [Clustering Algorithms](/api/ml/clustering) - K-means and EM clustering
* [StatModel Base Class](https://docs.opencv.org/4.x/dd/ded/classcv_1_1ml_1_1StatModel.html) - Base class for all ML models
# ArUco Marker Detection
Source: https://opencv-opencv.mintlify.app/api/objdetect/aruco
API reference for ArUco marker detection, CharUco board detection, and dictionary management
# ArUco Marker Detection
API reference for detecting ArUco markers and CharUco boards for robust camera pose estimation.
## ArucoDetector
Main class for detecting ArUco markers in images.
### Constructor
```cpp theme={null}
cv::aruco::ArucoDetector::ArucoDetector(
const Dictionary& dictionary = getPredefinedDictionary(cv::aruco::DICT_4X4_50),
const DetectorParameters& detectorParams = DetectorParameters(),
const RefineParameters& refineParams = RefineParameters()
)
```
Dictionary indicating the type of markers that will be searched
Marker detection parameters
Marker refine detection parameters
#### Multi-Dictionary Constructor
```cpp theme={null}
cv::aruco::ArucoDetector::ArucoDetector(
const std::vector& dictionaries,
const DetectorParameters& detectorParams = DetectorParameters(),
const RefineParameters& refineParams = RefineParameters()
)
```
Multiple dictionaries for marker detection. Cannot be empty.
### Methods
#### detectMarkers
Basic marker detection in an image.
```cpp theme={null}
void detectMarkers(
InputArray image,
OutputArrayOfArrays corners,
OutputArray ids,
OutputArrayOfArrays rejectedImgPoints = noArray()
) const
```
Input image where markers will be detected
Vector of detected marker corners. For each marker, its four corners are provided (clockwise order). For N detected markers, dimensions are Nx4.
Vector of identifiers of the detected markers. For N detected markers, the size is N.
Contains the corners of squares whose inner code has incorrect codification. Useful for debugging.
The function does not correct lens distortion. It's recommended to undistort the input image if camera parameters are known.
#### detectMarkersWithConfidence
Marker detection with confidence computation.
```cpp theme={null}
void detectMarkersWithConfidence(
InputArray image,
OutputArrayOfArrays corners,
OutputArray ids,
OutputArray markersConfidence,
OutputArrayOfArrays rejectedImgPoints = noArray()
) const
```
Contains the normalized confidence \[0;1] of the markers' detection, defined as 1 minus the normalized uncertainty (percentage of incorrect pixel detections).
#### refineDetectedMarkers
Refine undetected markers based on already detected markers and board layout.
```cpp theme={null}
void refineDetectedMarkers(
InputArray image,
const Board& board,
InputOutputArrayOfArrays detectedCorners,
InputOutputArray detectedIds,
InputOutputArrayOfArrays rejectedCorners,
InputArray cameraMatrix = noArray(),
InputArray distCoeffs = noArray(),
OutputArray recoveredIdxs = noArray()
) const
```
Input image
Layout of markers in the board
Vector of already detected marker corners
Vector of already detected marker identifiers
Vector of rejected candidates during the marker detection process
Optional 3x3 floating-point camera matrix
Optional vector of distortion coefficients
Optional array to return the indexes of recovered candidates in the original rejectedCorners array
#### getDictionary / setDictionary
```cpp theme={null}
const Dictionary& getDictionary() const
void setDictionary(const Dictionary& dictionary)
```
Gets or sets the first dictionary used for marker detection.
#### getDetectorParameters / setDetectorParameters
```cpp theme={null}
const DetectorParameters& getDetectorParameters() const
void setDetectorParameters(const DetectorParameters& detectorParameters)
```
Gets or sets the detector parameters.
#### getRefineParameters / setRefineParameters
```cpp theme={null}
const RefineParameters& getRefineParameters() const
void setRefineParameters(const RefineParameters& refineParameters)
```
Gets or sets the refine parameters.
### Example Usage
```cpp theme={null}
#include
#include
// Create ArUco detector with 6x6 dictionary
cv::aruco::Dictionary dictionary =
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::DetectorParameters detectorParams =
cv::aruco::DetectorParameters();
cv::aruco::ArucoDetector detector(dictionary, detectorParams);
// Detect markers
std::vector> corners;
std::vector ids;
std::vector> rejected;
detector.detectMarkers(image, corners, ids, rejected);
// Draw detected markers
if (!ids.empty()) {
cv::aruco::drawDetectedMarkers(image, corners, ids);
}
std::cout << "Detected " << ids.size() << " markers" << std::endl;
```
```python theme={null}
import cv2
import numpy as np
# Create ArUco detector with 6x6 dictionary
dictionary = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)
parameters = cv2.aruco.DetectorParameters()
detector = cv2.aruco.ArucoDetector(dictionary, parameters)
# Detect markers
corners, ids, rejected = detector.detectMarkers(image)
# Draw detected markers
if ids is not None:
cv2.aruco.drawDetectedMarkers(image, corners, ids)
print(f"Detected {len(ids) if ids is not None else 0} markers")
```
***
## Dictionary
A dictionary is a set of unique ArUco markers of the same size.
### Constructor
```cpp theme={null}
cv::aruco::Dictionary::Dictionary()
cv::aruco::Dictionary::Dictionary(
const Mat& bytesList,
int markerSize,
int maxCorrectionBits = 0
)
```
Bits for all ArUco markers in dictionary (CV\_8UC4 type)
ArUco marker size in units (number of bits per dimension)
Maximum number of bits that can be corrected
### Properties
* `bytesList` (Mat): Marker code information stored as 2D matrix with 4 channels
* `markerSize` (int): Number of bits per dimension
* `maxCorrectionBits` (int): Maximum number of bits that can be corrected
### Methods
#### identify
Given a matrix of bits, returns whether the marker is identified.
```cpp theme={null}
bool identify(
const Mat& onlyBits,
int& idx,
int& rotation,
double maxCorrectionRate
) const
```
Input matrix of bits
Output marker ID in the dictionary (if any)
Output marker rotation (0-3)
Maximum error correction rate
**Returns:** `true` if marker is identified
#### generateImageMarker
Generates a canonical marker image.
```cpp theme={null}
void generateImageMarker(
int id,
int sidePixels,
OutputArray img,
int borderBits = 1
) const
```
Marker ID to generate
Size of the output image in pixels
Output marker image
Width of the marker border
### Predefined Dictionaries
#### getPredefinedDictionary
```cpp theme={null}
Dictionary getPredefinedDictionary(PredefinedDictionaryType name)
Dictionary getPredefinedDictionary(int dict)
```
Available predefined dictionaries:
* `DICT_4X4_50` - 4x4 bits, 50 markers, hamming distance 4
* `DICT_4X4_100` - 4x4 bits, 100 markers, hamming distance 3
* `DICT_4X4_250` - 4x4 bits, 250 markers, hamming distance 3
* `DICT_4X4_1000` - 4x4 bits, 1000 markers, hamming distance 2
* `DICT_5X5_50` - 5x5 bits, 50 markers, hamming distance 8
* `DICT_5X5_100` - 5x5 bits, 100 markers, hamming distance 7
* `DICT_5X5_250` - 5x5 bits, 250 markers, hamming distance 6
* `DICT_5X5_1000` - 5x5 bits, 1000 markers, hamming distance 5
* `DICT_6X6_50` - 6x6 bits, 50 markers, hamming distance 13
* `DICT_6X6_100` - 6x6 bits, 100 markers, hamming distance 12
* `DICT_6X6_250` - 6x6 bits, 250 markers, hamming distance 11
* `DICT_6X6_1000` - 6x6 bits, 1000 markers, hamming distance 9
* `DICT_7X7_50` - 7x7 bits, 50 markers, hamming distance 19
* `DICT_7X7_100` - 7x7 bits, 100 markers, hamming distance 18
* `DICT_7X7_250` - 7x7 bits, 250 markers, hamming distance 17
* `DICT_7X7_1000` - 7x7 bits, 1000 markers, hamming distance 14
* `DICT_ARUCO_ORIGINAL` - 6x6 bits, 1024 markers (standard ArUco Library)
* `DICT_APRILTAG_16h5` - 4x4 bits, 30 markers, hamming distance 5
* `DICT_APRILTAG_25h9` - 5x5 bits, 35 markers, hamming distance 9
* `DICT_APRILTAG_36h10` - 6x6 bits, 2320 markers, hamming distance 10
* `DICT_APRILTAG_36h11` - 6x6 bits, 587 markers, hamming distance 11
* `DICT_ARUCO_MIP_36h12` - 6x6 bits, 250 markers, hamming distance 12
***
## CharucoDetector
Detector for ChArUco boards (chessboard + ArUco markers).
### Constructor
```cpp theme={null}
cv::aruco::CharucoDetector::CharucoDetector(
const CharucoBoard& board,
const CharucoParameters& charucoParams = CharucoParameters(),
const DetectorParameters& detectorParams = DetectorParameters(),
const RefineParameters& refineParams = RefineParameters()
)
```
ChArUco board configuration
ChArUco detection parameters
Marker detection parameters
Marker refine detection parameters
### Methods
#### detectBoard
Detects ArUco markers and interpolates ChArUco board corners.
```cpp theme={null}
void detectBoard(
InputArray image,
OutputArray charucoCorners,
OutputArray charucoIds,
InputOutputArrayOfArrays markerCorners = noArray(),
InputOutputArray markerIds = noArray()
) const
```
Input image necessary for corner refinement
Interpolated chessboard corners
Interpolated chessboard corner identifiers
Vector of already detected marker corners. If empty, the function will detect markers.
List of identifiers for each marker in corners. If empty, the function will detect markers.
After OpenCV 4.6.0, there was an incompatible change in the ChArUco pattern generation algorithm for even row counts. Use `CharucoBoard::setLegacyPattern()` to ensure compatibility with patterns created before 4.6.0.
#### detectDiamonds
Detects ChArUco Diamond markers.
```cpp theme={null}
void detectDiamonds(
InputArray image,
OutputArrayOfArrays diamondCorners,
OutputArray diamondIds,
InputOutputArrayOfArrays markerCorners = noArray(),
InputOutputArray markerIds = noArray()
) const
```
Input image necessary for corner subpixel accuracy
Output list of detected diamond corners (4 corners per diamond) in clockwise order
IDs of the diamonds. Each diamond has 4 IDs corresponding to the ArUco markers composing it.
List of detected marker corners. If empty, the function will detect markers.
List of marker IDs. If empty, the function will detect markers.
### Example Usage
```cpp theme={null}
#include
#include
// Create ChArUco board
cv::aruco::Dictionary dictionary =
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
cv::aruco::CharucoBoard board(cv::Size(5, 7), 0.04f, 0.02f, dictionary);
// Create detector
cv::aruco::CharucoDetector detector(board);
// Detect ChArUco corners
std::vector charucoCorners;
std::vector charucoIds;
std::vector> markerCorners;
std::vector markerIds;
detector.detectBoard(image, charucoCorners, charucoIds,
markerCorners, markerIds);
// Draw detected corners
if (!charucoIds.empty()) {
cv::aruco::drawDetectedCornersCharuco(image, charucoCorners,
charucoIds, cv::Scalar(255, 0, 0));
}
```
```python theme={null}
import cv2
import numpy as np
# Create ChArUco board
dictionary = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)
board = cv2.aruco.CharucoBoard((5, 7), 0.04, 0.02, dictionary)
# Create detector
detector = cv2.aruco.CharucoDetector(board)
# Detect ChArUco corners
charuco_corners, charuco_ids, marker_corners, marker_ids = \
detector.detectBoard(image)
# Draw detected corners
if charuco_ids is not None and len(charuco_ids) > 0:
cv2.aruco.drawDetectedCornersCharuco(image, charuco_corners,
charuco_ids, (255, 0, 0))
```
## DetectorParameters
Parameters for ArUco marker detection.
### Key Parameters
```cpp theme={null}
struct DetectorParameters {
int adaptiveThreshWinSizeMin; // default: 3
int adaptiveThreshWinSizeMax; // default: 23
int adaptiveThreshWinSizeStep; // default: 10
double adaptiveThreshConstant; // default: 7
double minMarkerPerimeterRate; // default: 0.03
double maxMarkerPerimeterRate; // default: 4.0
double polygonalApproxAccuracyRate; // default: 0.03
double minCornerDistanceRate; // default: 0.05
int minDistanceToBorder; // default: 3
double minMarkerDistanceRate; // default: 0.125
int cornerRefinementMethod; // default: CORNER_REFINE_NONE
int cornerRefinementWinSize; // default: 5
int cornerRefinementMaxIterations; // default: 30
double cornerRefinementMinAccuracy; // default: 0.1
int markerBorderBits; // default: 1
int perspectiveRemovePixelPerCell; // default: 4
double errorCorrectionRate; // default: 0.6
bool detectInvertedMarker; // default: false
bool useAruco3Detection; // default: false
}
```
Corner refinement method:
* `CORNER_REFINE_NONE` - No refinement
* `CORNER_REFINE_SUBPIX` - Subpixel corner refinement
* `CORNER_REFINE_CONTOUR` - Contour-based refinement
* `CORNER_REFINE_APRILTAG` - AprilTag approach
Enable the new and faster ArUco 3 detection strategy (from Romero-Ramirez et al. 2018)
## Utility Functions
### drawDetectedMarkers
Draws detected markers in an image.
```cpp theme={null}
void drawDetectedMarkers(
InputOutputArray image,
InputArrayOfArrays corners,
InputArray ids = noArray(),
Scalar borderColor = Scalar(0, 255, 0)
)
```
### generateImageMarker
Generates a canonical marker image.
```cpp theme={null}
void generateImageMarker(
const Dictionary& dictionary,
int id,
int sidePixels,
OutputArray img,
int borderBits = 1
)
```
## See Also
* [Cascade Classifier](/api/objdetect/cascade)
* [Face Detection](/api/objdetect/face)
* [QR Code Detection](/api/objdetect/qrcode)
# Cascade Classifier
Source: https://opencv-opencv.mintlify.app/api/objdetect/cascade
API reference for CascadeClassifier and HOGDescriptor classes for object detection
# Cascade Classifier
API reference for cascade-based object detection and HOG descriptor computation.
## CascadeClassifier
Cascade classifier class for object detection using Haar or LBP features.
### Constructor
```cpp theme={null}
cv::CascadeClassifier::CascadeClassifier()
cv::CascadeClassifier::CascadeClassifier(const String& filename)
```
Path to the classifier file (e.g., haarcascade\_frontalface\_default.xml)
### Methods
#### load
Loads a classifier from a file.
```cpp theme={null}
bool load(const String& filename)
```
Name of the file from which the classifier is loaded. The file may contain an old HAAR classifier trained by the haartraining application or a new cascade classifier trained by the traincascade application.
**Returns:** `true` if the classifier was loaded successfully
#### detectMultiScale
Detects objects of different sizes in the input image.
```cpp theme={null}
void detectMultiScale(
InputArray image,
std::vector& objects,
double scaleFactor = 1.1,
int minNeighbors = 3,
int flags = 0,
Size minSize = Size(),
Size maxSize = Size()
)
```
Matrix of type CV\_8U containing an image where objects are detected
Output vector of rectangles where each rectangle contains a detected object
Parameter specifying how much the image size is reduced at each image scale
Parameter specifying how many neighbors each candidate rectangle should have to retain it
Parameter with the same meaning for an old cascade as in cvHaarDetectObjects. Not used for new cascades.
Minimum possible object size. Objects smaller than this are ignored.
Maximum possible object size. Objects larger than this are ignored. If maxSize == minSize, model is evaluated on single scale.
The function does not correct lens distortion. If camera parameters are known, it's recommended to undistort the input image first.
#### detectMultiScale (with detection counts)
```cpp theme={null}
void detectMultiScale(
InputArray image,
std::vector& objects,
std::vector& numDetections,
double scaleFactor = 1.1,
int minNeighbors = 3,
int flags = 0,
Size minSize = Size(),
Size maxSize = Size()
)
```
Vector of detection numbers for the corresponding objects. An object's number of detections is the number of neighboring positively classified rectangles that were joined together.
#### detectMultiScale (with confidence levels)
```cpp theme={null}
void detectMultiScale(
InputArray image,
std::vector& objects,
std::vector& rejectLevels,
std::vector& levelWeights,
double scaleFactor = 1.1,
int minNeighbors = 3,
int flags = 0,
Size minSize = Size(),
Size maxSize = Size(),
bool outputRejectLevels = false
)
```
Output vector of reject levels for each detection
Output vector containing the certainty of classification at the final stage for each detection
Set to true to retrieve the final stage decision certainty of classification
#### empty
Checks whether the classifier has been loaded.
```cpp theme={null}
bool empty() const
```
**Returns:** `true` if the classifier is empty
### Example Usage
```cpp theme={null}
#include
#include
// Load the cascade classifier
cv::CascadeClassifier face_cascade;
face_cascade.load("haarcascade_frontalface_default.xml");
// Detect faces
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
std::vector faces;
face_cascade.detectMultiScale(gray, faces, 1.1, 3);
// Draw rectangles around detected faces
for (const auto& face : faces) {
cv::rectangle(image, face, cv::Scalar(255, 0, 0), 2);
}
```
```python theme={null}
import cv2
# Load the cascade classifier
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# Convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Detect faces
faces = face_cascade.detectMultiScale(gray, 1.1, 3)
# Draw rectangles around detected faces
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2)
```
***
## HOGDescriptor
Implementation of HOG (Histogram of Oriented Gradients) descriptor and object detector.
Based on the algorithm introduced by Navneet Dalal and Bill Triggs.
### Constructor
```cpp theme={null}
cv::HOGDescriptor::HOGDescriptor()
cv::HOGDescriptor::HOGDescriptor(
Size winSize,
Size blockSize,
Size blockStride,
Size cellSize,
int nbins,
int derivAperture = 1,
double winSigma = -1,
HOGDescriptor::HistogramNormType histogramNormType = HOGDescriptor::L2Hys,
double L2HysThreshold = 0.2,
bool gammaCorrection = false,
int nlevels = HOGDescriptor::DEFAULT_NLEVELS,
bool signedGradient = false
)
cv::HOGDescriptor::HOGDescriptor(const String& filename)
```
Detection window size. Default is Size(64, 128). Must align to block size and block stride.
Block size in pixels. Default is Size(16, 16). Must align to cell size.
Block stride. Default is Size(8, 8). Must be a multiple of cell size.
Cell size. Default is Size(8, 8).
Number of bins used in the calculation of histogram of gradients. Default is 9.
File name containing HOGDescriptor properties and coefficients for the linear SVM classifier
### Methods
#### compute
Computes HOG descriptors of given image.
```cpp theme={null}
void compute(
InputArray img,
std::vector& descriptors,
Size winStride = Size(),
Size padding = Size(),
const std::vector& locations = std::vector()
) const
```
Matrix of type CV\_8U containing an image where HOG features will be calculated
Output matrix of type CV\_32F containing computed descriptors
Window stride. Must be a multiple of block stride.
Padding around the image
Vector of specific locations to compute descriptors at
#### detect
Performs object detection without a multi-scale window.
```cpp theme={null}
void detect(
InputArray img,
std::vector& foundLocations,
std::vector& weights,
double hitThreshold = 0,
Size winStride = Size(),
Size padding = Size(),
const std::vector& searchLocations = std::vector()
) const
```
Matrix of type CV\_8U or CV\_8UC3 containing an image where objects are detected
Vector of points where each point contains left-top corner of detected object boundaries
Vector that will contain confidence values for each detected object
Threshold for the distance between features and SVM classifying plane
Window stride. Must be a multiple of block stride.
Padding around the image
Vector of specific locations to search
#### detectMultiScale
Detects objects of different sizes in the input image.
```cpp theme={null}
void detectMultiScale(
InputArray img,
std::vector& foundLocations,
std::vector& foundWeights,
double hitThreshold = 0,
Size winStride = Size(),
Size padding = Size(),
double scale = 1.05,
double groupThreshold = 2.0,
bool useMeanshiftGrouping = false
) const
```
Matrix of type CV\_8U or CV\_8UC3 containing an image where objects are detected
Vector of rectangles where each rectangle contains the detected object
Vector that will contain confidence values for each detected object
Coefficient of the detection window increase
Coefficient to regulate the similarity threshold. When detected, some objects can be covered by many rectangles. 0 means not to perform grouping.
Indicates whether to use meanshift grouping algorithm
#### setSVMDetector
Sets coefficients for the linear SVM classifier.
```cpp theme={null}
void setSVMDetector(InputArray svmdetector)
```
Coefficients for the linear SVM classifier
#### getDefaultPeopleDetector
Returns coefficients of the classifier trained for people detection (for 64x128 windows).
```cpp theme={null}
static std::vector getDefaultPeopleDetector()
```
**Returns:** Vector of SVM coefficients for people detection
#### getDaimlerPeopleDetector
Returns coefficients of the classifier trained for people detection (for 48x96 windows).
```cpp theme={null}
static std::vector getDaimlerPeopleDetector()
```
**Returns:** Vector of SVM coefficients for Daimler people detection
### Properties
* `winSize` (Size): Detection window size. Default Size(64, 128).
* `blockSize` (Size): Block size in pixels. Default Size(16, 16).
* `blockStride` (Size): Block stride. Default Size(8, 8).
* `cellSize` (Size): Cell size. Default Size(8, 8).
* `nbins` (int): Number of bins. Default 9.
* `derivAperture` (int): Derivative aperture.
* `winSigma` (double): Gaussian smoothing window parameter.
* `histogramNormType` (HistogramNormType): Histogram normalization type.
* `L2HysThreshold` (double): L2-Hys normalization method shrinkage.
* `gammaCorrection` (bool): Flag to specify gamma correction preprocessing.
* `svmDetector` (std::vector\): Coefficients for the linear SVM classifier.
* `nlevels` (int): Maximum number of detection window increases. Default 64.
* `signedGradient` (bool): Indicates whether signed gradient will be used.
### Example Usage
```cpp theme={null}
#include
#include
// Create HOG descriptor with default people detector
cv::HOGDescriptor hog;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
// Detect people in the image
std::vector found;
std::vector weights;
hog.detectMultiScale(image, found, weights, 0, cv::Size(8, 8),
cv::Size(32, 32), 1.05, 2, false);
// Draw rectangles around detected people
for (const auto& rect : found) {
cv::rectangle(image, rect, cv::Scalar(0, 255, 0), 2);
}
```
```python theme={null}
import cv2
# Create HOG descriptor with default people detector
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
# Detect people in the image
found, weights = hog.detectMultiScale(image, winStride=(8, 8),
padding=(32, 32), scale=1.05)
# Draw rectangles around detected people
for (x, y, w, h) in found:
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
```
## See Also
* [Face Detection](/api/objdetect/face)
* [ArUco Detection](/api/objdetect/aruco)
* [QR Code Detection](/api/objdetect/qrcode)
# Face Detection and Recognition
Source: https://opencv-opencv.mintlify.app/api/objdetect/face
API reference for DNN-based face detection and recognition classes
# Face Detection and Recognition
DNN-based face detection and recognition using the FaceDetectorYN and FaceRecognizerSF classes.
## FaceDetectorYN
DNN-based face detector class.
Model download link: [Face Detection YuNet](https://github.com/opencv/opencv_zoo/tree/master/models/face_detection_yunet)
### Constructor
Use the static `create()` method to create an instance.
#### create (from file)
```cpp theme={null}
static Ptr create(
const String& model,
const String& config,
const Size& input_size,
float score_threshold = 0.9f,
float nms_threshold = 0.3f,
int top_k = 5000,
int backend_id = 0,
int target_id = 0
)
```
Path to the requested model file
Path to the config file for compatibility (not requested for ONNX models)
Size of the input image
Threshold to filter out bounding boxes of score less than the given value
Threshold to suppress bounding boxes that have IoU greater than the given value
Number of bounding boxes to preserve from top rank based on score before NMS
ID of the backend (DNN backend)
ID of the target device
**Returns:** Pointer to FaceDetectorYN instance
#### create (from buffer)
```cpp theme={null}
static Ptr create(
const String& framework,
const std::vector& bufferModel,
const std::vector& bufferConfig,
const Size& input_size,
float score_threshold = 0.9f,
float nms_threshold = 0.3f,
int top_k = 5000,
int backend_id = 0,
int target_id = 0
)
```
Name of origin framework
Buffer with content of binary file with model weights
Buffer with content of text file containing network configuration
### Methods
#### setInputSize
Sets the size for the network input.
```cpp theme={null}
void setInputSize(const Size& input_size)
```
Size of the input image. This overwrites the input size used when creating the model.
Call this method when the size of the input image does not match the input size when creating the model.
#### getInputSize
Gets the current input size.
```cpp theme={null}
Size getInputSize()
```
**Returns:** Current input size
#### setScoreThreshold
Sets the score threshold to filter out bounding boxes.
```cpp theme={null}
void setScoreThreshold(float score_threshold)
```
Threshold for filtering out bounding boxes
#### getScoreThreshold
Gets the current score threshold.
```cpp theme={null}
float getScoreThreshold()
```
**Returns:** Current score threshold
#### setNMSThreshold
Sets the Non-maximum-suppression threshold.
```cpp theme={null}
void setNMSThreshold(float nms_threshold)
```
Threshold for NMS operation to suppress bounding boxes that have IoU greater than the given value
#### getNMSThreshold
Gets the current NMS threshold.
```cpp theme={null}
float getNMSThreshold()
```
**Returns:** Current NMS threshold
#### setTopK
Sets the number of bounding boxes preserved before NMS.
```cpp theme={null}
void setTopK(int top_k)
```
Number of bounding boxes to preserve from top rank based on score
#### getTopK
Gets the current top K value.
```cpp theme={null}
int getTopK()
```
**Returns:** Current top K value
#### detect
Detects faces in the input image.
```cpp theme={null}
int detect(InputArray image, OutputArray faces)
```
Input image to detect faces in
Detection results stored in a 2D cv::Mat of shape \[num\_faces, 15]:
* 0-1: x, y of bbox top left corner
* 2-3: width, height of bbox
* 4-5: x, y of right eye
* 6-7: x, y of left eye
* 8-9: x, y of nose tip
* 10-11: x, y of right corner of mouth
* 12-13: x, y of left corner of mouth
* 14: face score
**Returns:** Number of faces detected
### Example Usage
```cpp theme={null}
#include
#include
// Create face detector
auto detector = cv::FaceDetectorYN::create(
"face_detection_yunet_2023mar.onnx",
"",
cv::Size(320, 320),
0.9f,
0.3f,
5000
);
// Set input size to match image
detector->setInputSize(image.size());
// Detect faces
cv::Mat faces;
detector->detect(image, faces);
// Draw bounding boxes and landmarks
for (int i = 0; i < faces.rows; i++) {
// Get bounding box
int x = faces.at(i, 0);
int y = faces.at(i, 1);
int w = faces.at(i, 2);
int h = faces.at(i, 3);
cv::rectangle(image, cv::Rect(x, y, w, h), cv::Scalar(0, 255, 0), 2);
// Draw facial landmarks
for (int j = 4; j < 14; j += 2) {
cv::circle(image,
cv::Point(faces.at(i, j), faces.at(i, j+1)),
2, cv::Scalar(255, 0, 0), -1);
}
}
```
```python theme={null}
import cv2
# Create face detector
detector = cv2.FaceDetectorYN.create(
'face_detection_yunet_2023mar.onnx',
'',
(320, 320),
0.9,
0.3,
5000
)
# Set input size to match image
detector.setInputSize(image.shape[1::-1])
# Detect faces
_, faces = detector.detect(image)
if faces is not None:
for face in faces:
# Get bounding box
x, y, w, h = face[:4].astype(int)
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Draw facial landmarks
for i in range(4, 14, 2):
cv2.circle(image, (int(face[i]), int(face[i+1])),
2, (255, 0, 0), -1)
```
***
## FaceRecognizerSF
DNN-based face recognizer class.
Model download link: [Face Recognition SFace](https://github.com/opencv/opencv_zoo/tree/master/models/face_recognition_sface)
### Constructor
Use the static `create()` method to create an instance.
#### create (from file)
```cpp theme={null}
static Ptr create(
const String& model,
const String& config,
int backend_id = 0,
int target_id = 0
)
```
Path to the ONNX model used for face recognition
Path to the config file for compatibility (not requested for ONNX models)
ID of the backend
ID of the target device
**Returns:** Pointer to FaceRecognizerSF instance
#### create (from buffer)
```cpp theme={null}
static Ptr create(
const String& framework,
const std::vector& bufferModel,
const std::vector& bufferConfig,
int backend_id = 0,
int target_id = 0
)
```
Name of the framework (ONNX, etc.)
Buffer containing the binary model weights
Buffer containing the network configuration
### Enums
#### DisType
Distance types for calculating distance between face features.
```cpp theme={null}
enum DisType {
FR_COSINE = 0, // Cosine distance
FR_NORM_L2 = 1 // L2 norm distance
}
```
### Methods
#### alignCrop
Aligns detected face with the source input image and crops it.
```cpp theme={null}
void alignCrop(
InputArray src_img,
InputArray face_box,
OutputArray aligned_img
) const
```
Input image
Detected face result from the input image (from FaceDetectorYN)
Output aligned and cropped face image
#### feature
Extracts face feature from aligned image.
```cpp theme={null}
void feature(
InputArray aligned_img,
OutputArray face_feature
)
```
Input aligned face image
Output face feature vector
#### match
Calculates the distance between two face features.
```cpp theme={null}
double match(
InputArray face_feature1,
InputArray face_feature2,
int dis_type = FaceRecognizerSF::FR_COSINE
) const
```
First input feature vector
Second input feature vector of the same size and type as face\_feature1
Distance calculation method: FR\_COSINE (cosine distance) or FR\_NORM\_L2 (L2 norm distance)
**Returns:** Distance between the two face features. Lower values indicate more similar faces.
### Example Usage
```cpp theme={null}
#include
// Create face recognizer
auto recognizer = cv::FaceRecognizerSF::create(
"face_recognition_sface_2021dec.onnx",
""
);
// Assume we have detected faces using FaceDetectorYN
cv::Mat face1_aligned, face2_aligned;
// Align and crop faces
recognizer->alignCrop(image1, face1_box, face1_aligned);
recognizer->alignCrop(image2, face2_box, face2_aligned);
// Extract features
cv::Mat feature1, feature2;
recognizer->feature(face1_aligned, feature1);
recognizer->feature(face2_aligned, feature2);
// Calculate similarity
double cosine_score = recognizer->match(
feature1, feature2,
cv::FaceRecognizerSF::FR_COSINE
);
// Threshold for face matching (typical: 0.363 for cosine)
bool is_same_person = cosine_score >= 0.363;
std::cout << "Cosine similarity: " << cosine_score << std::endl;
std::cout << "Same person: " << (is_same_person ? "Yes" : "No") << std::endl;
```
```python theme={null}
import cv2
# Create face recognizer
recognizer = cv2.FaceRecognizerSF.create(
'face_recognition_sface_2021dec.onnx',
''
)
# Assume we have detected faces using FaceDetectorYN
# Align and crop faces
face1_aligned = recognizer.alignCrop(image1, face1_box)
face2_aligned = recognizer.alignCrop(image2, face2_box)
# Extract features
feature1 = recognizer.feature(face1_aligned)
feature2 = recognizer.feature(face2_aligned)
# Calculate similarity
cosine_score = recognizer.match(
feature1, feature2,
cv2.FaceRecognizerSF_FR_COSINE
)
# Threshold for face matching (typical: 0.363 for cosine)
is_same_person = cosine_score >= 0.363
print(f"Cosine similarity: {cosine_score}")
print(f"Same person: {'Yes' if is_same_person else 'No'}")
```
## Complete Workflow Example
```cpp theme={null}
#include
#include
#include
int main() {
// Load images
cv::Mat img1 = cv::imread("person1.jpg");
cv::Mat img2 = cv::imread("person2.jpg");
// Create detector and recognizer
auto detector = cv::FaceDetectorYN::create(
"face_detection_yunet_2023mar.onnx", "",
cv::Size(320, 320)
);
auto recognizer = cv::FaceRecognizerSF::create(
"face_recognition_sface_2021dec.onnx", ""
);
// Detect faces in both images
detector->setInputSize(img1.size());
cv::Mat faces1;
detector->detect(img1, faces1);
detector->setInputSize(img2.size());
cv::Mat faces2;
detector->detect(img2, faces2);
if (faces1.rows > 0 && faces2.rows > 0) {
// Get first face from each image
cv::Mat face1_box = faces1.row(0);
cv::Mat face2_box = faces2.row(0);
// Align and extract features
cv::Mat aligned1, aligned2;
recognizer->alignCrop(img1, face1_box, aligned1);
recognizer->alignCrop(img2, face2_box, aligned2);
cv::Mat feature1, feature2;
recognizer->feature(aligned1, feature1);
recognizer->feature(aligned2, feature2);
// Compare faces
double score = recognizer->match(feature1, feature2);
std::cout << "Match score: " << score << std::endl;
}
return 0;
}
```
```python theme={null}
import cv2
# Load images
img1 = cv2.imread('person1.jpg')
img2 = cv2.imread('person2.jpg')
# Create detector and recognizer
detector = cv2.FaceDetectorYN.create(
'face_detection_yunet_2023mar.onnx',
'',
(320, 320)
)
recognizer = cv2.FaceRecognizerSF.create(
'face_recognition_sface_2021dec.onnx',
''
)
# Detect faces in both images
detector.setInputSize((img1.shape[1], img1.shape[0]))
_, faces1 = detector.detect(img1)
detector.setInputSize((img2.shape[1], img2.shape[0]))
_, faces2 = detector.detect(img2)
if faces1 is not None and faces2 is not None:
# Get first face from each image
face1_box = faces1[0]
face2_box = faces2[0]
# Align and extract features
aligned1 = recognizer.alignCrop(img1, face1_box)
aligned2 = recognizer.alignCrop(img2, face2_box)
feature1 = recognizer.feature(aligned1)
feature2 = recognizer.feature(aligned2)
# Compare faces
score = recognizer.match(feature1, feature2)
print(f"Match score: {score}")
```
## See Also
* [Cascade Classifier](/api/objdetect/cascade)
* [ArUco Detection](/api/objdetect/aruco)
* [QR Code Detection](/api/objdetect/qrcode)
# QR Code and Barcode Detection
Source: https://opencv-opencv.mintlify.app/api/objdetect/qrcode
API reference for QR code and barcode detection and decoding
# QR Code and Barcode Detection
API reference for detecting and decoding QR codes, barcodes, and other graphical codes.
## GraphicalCodeDetector
Base class for graphical code detection and decoding.
### Methods
#### detect
Detects graphical code in image and returns the quadrangle containing the code.
```cpp theme={null}
bool detect(InputArray img, OutputArray points) const
```
Grayscale or color (BGR) image containing (or not) graphical code
Output vector of vertices of the minimum-area quadrangle containing the code
**Returns:** `true` if a code is detected
#### decode
Decodes graphical code once it's found by the detect() method.
```cpp theme={null}
std::string decode(
InputArray img,
InputArray points,
OutputArray straight_code = noArray()
) const
```
Grayscale or color (BGR) image containing graphical code
Quadrangle vertices found by detect() method
Optional output image containing binarized code
**Returns:** UTF8-encoded output string or empty string if the code cannot be decoded
#### detectAndDecode
Both detects and decodes graphical code.
```cpp theme={null}
std::string detectAndDecode(
InputArray img,
OutputArray points = noArray(),
OutputArray straight_code = noArray()
) const
```
Grayscale or color (BGR) image containing graphical code
Optional output array of vertices of the found graphical code quadrangle
Optional output image containing binarized code
**Returns:** Decoded string or empty string if not found
#### detectMulti
Detects multiple graphical codes in image.
```cpp theme={null}
bool detectMulti(InputArray img, OutputArray points) const
```
Grayscale or color (BGR) image
Output vector of vector of vertices of the minimum-area quadrangles containing the codes
**Returns:** `true` if at least one code is detected
#### decodeMulti
Decodes multiple graphical codes.
```cpp theme={null}
bool decodeMulti(
InputArray img,
InputArray points,
std::vector& decoded_info,
OutputArrayOfArrays straight_code = noArray()
) const
```
Grayscale or color (BGR) image containing graphical codes
Vector of quadrangle vertices found by detect() method
UTF8-encoded output vector of strings or empty vector if codes cannot be decoded
Optional output vector of images containing binarized codes
**Returns:** `true` if at least one code is decoded
#### detectAndDecodeMulti
Both detects and decodes multiple graphical codes.
```cpp theme={null}
bool detectAndDecodeMulti(
InputArray img,
std::vector& decoded_info,
OutputArray points = noArray(),
OutputArrayOfArrays straight_code = noArray()
) const
```
UTF8-encoded output vector of strings or empty vector if codes cannot be decoded
If there are QR codes encoded with Structured Append mode and all are detected and decoded correctly, the method writes the full message to the position corresponding to the 0-th code in the sequence. The rest of the QR codes from the same sequence have empty strings.
***
## QRCodeDetector
QR code detector and decoder.
### Constructor
```cpp theme={null}
cv::QRCodeDetector::QRCodeDetector()
```
### Methods
#### setEpsX
Sets the epsilon used during horizontal scan of QR code stop marker detection.
```cpp theme={null}
QRCodeDetector& setEpsX(double epsX)
```
Epsilon neighborhood for determining the horizontal pattern of the scheme 1:1:3:1:1 according to QR code standard
**Returns:** Reference to this QRCodeDetector
#### setEpsY
Sets the epsilon used during vertical scan of QR code stop marker detection.
```cpp theme={null}
QRCodeDetector& setEpsY(double epsY)
```
Epsilon neighborhood for determining the vertical pattern of the scheme 1:1:3:1:1 according to QR code standard
**Returns:** Reference to this QRCodeDetector
#### setUseAlignmentMarkers
Enables or disables use of alignment markers to improve corner position.
```cpp theme={null}
QRCodeDetector& setUseAlignmentMarkers(bool useAlignmentMarkers)
```
Flag to enable alignment markers (enabled by default)
**Returns:** Reference to this QRCodeDetector
#### decodeCurved
Decodes QR code on a curved surface once found by detect().
```cpp theme={null}
std::string decodeCurved(
InputArray img,
InputArray points,
OutputArray straight_qrcode = noArray()
)
```
Grayscale or color (BGR) image containing QR code
Quadrangle vertices found by detect() method
Optional output image containing rectified and binarized QR code
**Returns:** UTF8-encoded output string or empty string if the code cannot be decoded
#### detectAndDecodeCurved
Both detects and decodes QR code on a curved surface.
```cpp theme={null}
std::string detectAndDecodeCurved(
InputArray img,
OutputArray points = noArray(),
OutputArray straight_qrcode = noArray()
)
```
#### getEncoding
Returns the encoding type for the decoded info from the latest decode call.
```cpp theme={null}
QRCodeEncoder::ECIEncodings getEncoding(int codeIdx = 0)
```
Index of the previously decoded QR code. For single code detection, use 0.
**Returns:** Encoding type (e.g., ECI\_UTF8, ECI\_SHIFT\_JIS)
### Example Usage
```cpp theme={null}
#include
#include
#include
// Create QR code detector
cv::QRCodeDetector detector;
// Detect and decode QR code
std::vector points;
std::string decoded_info = detector.detectAndDecode(image, points);
if (!decoded_info.empty()) {
std::cout << "QR Code decoded: " << decoded_info << std::endl;
// Draw quadrangle around QR code
for (size_t i = 0; i < points.size(); i++) {
cv::line(image, points[i], points[(i+1) % points.size()],
cv::Scalar(0, 255, 0), 3);
}
} else {
std::cout << "QR Code not detected" << std::endl;
}
```
```python theme={null}
import cv2
# Create QR code detector
detector = cv2.QRCodeDetector()
# Detect and decode QR code
decoded_info, points, _ = detector.detectAndDecode(image)
if decoded_info:
print(f"QR Code decoded: {decoded_info}")
# Draw quadrangle around QR code
if points is not None:
points = points.astype(int)
for i in range(len(points)):
cv2.line(image, tuple(points[i][0]),
tuple(points[(i+1) % len(points)][0]),
(0, 255, 0), 3)
else:
print("QR Code not detected")
```
***
## QRCodeEncoder
QR code encoder for generating QR codes.
### Constructor
Use the static `create()` method.
```cpp theme={null}
static Ptr create(
const QRCodeEncoder::Params& parameters = QRCodeEncoder::Params()
)
```
### Enums
#### EncodeMode
```cpp theme={null}
enum EncodeMode {
MODE_AUTO = -1,
MODE_NUMERIC = 1,
MODE_ALPHANUMERIC = 2,
MODE_BYTE = 4,
MODE_ECI = 7,
MODE_KANJI = 8,
MODE_STRUCTURED_APPEND = 3
}
```
#### CorrectionLevel
```cpp theme={null}
enum CorrectionLevel {
CORRECT_LEVEL_L = 0, // ~7% error correction
CORRECT_LEVEL_M = 1, // ~15% error correction
CORRECT_LEVEL_Q = 2, // ~25% error correction
CORRECT_LEVEL_H = 3 // ~30% error correction
}
```
#### ECIEncodings
```cpp theme={null}
enum ECIEncodings {
ECI_SHIFT_JIS = 20,
ECI_UTF8 = 26
}
```
### Params Structure
```cpp theme={null}
struct Params {
int version; // QR code version
CorrectionLevel correction_level; // Error correction level
EncodeMode mode; // Encoding mode
int structure_number; // Number of QR codes in Structured Append
}
```
### Methods
#### encode
Generates QR code from input string.
```cpp theme={null}
void encode(const String& encoded_info, OutputArray qrcode)
```
Input string to encode
Generated QR code image
#### encodeStructuredAppend
Generates QR code in Structured Append mode, splitting the message over multiple QR codes.
```cpp theme={null}
void encodeStructuredAppend(
const String& encoded_info,
OutputArrayOfArrays qrcodes
)
```
Input string to encode
Vector of generated QR code images
### Example Usage
```cpp theme={null}
#include
#include
// Create encoder with parameters
cv::QRCodeEncoder::Params params;
params.version = 5; // or -1 for automatic
params.correction_level = cv::QRCodeEncoder::CORRECT_LEVEL_M;
params.mode = cv::QRCodeEncoder::MODE_BYTE;
auto encoder = cv::QRCodeEncoder::create(params);
// Generate QR code
cv::Mat qrcode;
encoder->encode("https://opencv.org", qrcode);
// Save or display
cv::imwrite("qrcode.png", qrcode);
```
```python theme={null}
import cv2
# Create encoder with parameters
params = cv2.QRCodeEncoder_Params()
params.version = 5 # or -1 for automatic
params.correction_level = cv2.QRCodeEncoder_CORRECT_LEVEL_M
params.mode = cv2.QRCodeEncoder_MODE_BYTE
encoder = cv2.QRCodeEncoder.create(params)
# Generate QR code
qrcode = encoder.encode("https://opencv.org")
# Save or display
cv2.imwrite("qrcode.png", qrcode)
```
***
## BarcodeDetector
Barcode detector and decoder. Inherits from GraphicalCodeDetector.
### Constructor
```cpp theme={null}
cv::barcode::BarcodeDetector::BarcodeDetector()
cv::barcode::BarcodeDetector::BarcodeDetector(
const std::string& prototxt_path,
const std::string& model_path
)
```
Prototxt file path for the super resolution model (optional)
Model file path for the super resolution model (optional)
### Methods
#### decodeWithType
Decodes barcode in image once found by detect().
```cpp theme={null}
bool decodeWithType(
InputArray img,
InputArray points,
std::vector& decoded_info,
std::vector& decoded_type
) const
```
Grayscale or color (BGR) image containing barcode
Vector of rotated rectangle vertices found by detect(). Order: bottomLeft, topLeft, topRight, bottomRight.
UTF8-encoded output vector of strings or empty if codes cannot be decoded
Vector of strings specifying the type of barcodes (e.g., "EAN\_13", "CODE\_128")
**Returns:** `true` if at least one valid barcode is found
#### detectAndDecodeWithType
Both detects and decodes barcode.
```cpp theme={null}
bool detectAndDecodeWithType(
InputArray img,
std::vector& decoded_info,
std::vector& decoded_type,
OutputArray points = noArray()
) const
```
Grayscale or color (BGR) image containing barcode
UTF8-encoded output vector of strings
Vector of strings specifying the barcode types
Optional output vector of vertices of the found barcode rectangle
**Returns:** `true` if at least one valid barcode is found
#### setDownsamplingThreshold
Sets detector downsampling threshold.
```cpp theme={null}
BarcodeDetector& setDownsamplingThreshold(double thresh)
```
Downsampling limit to apply (default 512). The detect method resizes the input image to this limit if the smallest dimension is greater than the threshold.
**Returns:** Reference to this BarcodeDetector
#### getDownsamplingThreshold
Gets detector downsampling threshold.
```cpp theme={null}
double getDownsamplingThreshold() const
```
**Returns:** Current downsampling threshold
#### setDetectorScales
Sets detector box filter sizes.
```cpp theme={null}
BarcodeDetector& setDetectorScales(const std::vector& sizes)
```
Box filter sizes relative to minimum dimension of the image (default \[0.01, 0.03, 0.06, 0.08])
Filter sizes directly correlate with the expected line widths for a barcode. If the downsampling limit is increased, filter sizes need to be adjusted inversely.
**Returns:** Reference to this BarcodeDetector
#### getDetectorScales
Gets detector box filter sizes.
```cpp theme={null}
void getDetectorScales(std::vector& sizes) const
```
Output parameter for returning the sizes
#### setGradientThreshold
Sets detector gradient magnitude threshold.
```cpp theme={null}
BarcodeDetector& setGradientThreshold(double thresh)
```
Gradient magnitude threshold (default 64). Values between 16 and 1024 generally work.
**Returns:** Reference to this BarcodeDetector
#### getGradientThreshold
Gets detector gradient magnitude threshold.
```cpp theme={null}
double getGradientThreshold() const
```
**Returns:** Current gradient threshold
### Example Usage
```cpp theme={null}
#include
#include
#include
// Create barcode detector
cv::barcode::BarcodeDetector detector;
// Optionally adjust parameters
detector.setDownsamplingThreshold(800);
detector.setGradientThreshold(64);
// Detect and decode barcodes
std::vector decoded_info;
std::vector decoded_type;
std::vector points;
bool found = detector.detectAndDecodeWithType(
image, decoded_info, decoded_type, points
);
if (found) {
for (size_t i = 0; i < decoded_info.size(); i++) {
std::cout << "Barcode " << i << ": "
<< decoded_info[i] << " (Type: "
<< decoded_type[i] << ")" << std::endl;
}
} else {
std::cout << "No barcodes detected" << std::endl;
}
```
```python theme={null}
import cv2
# Create barcode detector
detector = cv2.barcode.BarcodeDetector()
# Optionally adjust parameters
detector.setDownsamplingThreshold(800)
detector.setGradientThreshold(64)
# Detect and decode barcodes
retval, decoded_info, decoded_type, points = \
detector.detectAndDecodeWithType(image)
if retval:
for i, (info, type_) in enumerate(zip(decoded_info, decoded_type)):
print(f"Barcode {i}: {info} (Type: {type_})")
else:
print("No barcodes detected")
```
## Supported Barcode Types
The BarcodeDetector supports various 1D and 2D barcode formats:
* EAN-8, EAN-13
* UPC-A, UPC-E
* Code 39, Code 93, Code 128
* ITF (Interleaved 2 of 5)
* Codabar
* QR Code
* DataMatrix
* PDF417
## See Also
* [Cascade Classifier](/api/objdetect/cascade)
* [Face Detection](/api/objdetect/face)
* [ArUco Detection](/api/objdetect/aruco)
# Motion Analysis Functions
Source: https://opencv-opencv.mintlify.app/api/video/motion
Core motion analysis algorithms including CamShift, MeanShift, and ECC image alignment
The motion analysis module provides fundamental algorithms for tracking object motion, estimating transformations between images, and computing similarity measures.
## CamShift
Finds an object center, size, and orientation using the CAMSHIFT algorithm.
```cpp theme={null}
RotatedRect CamShift(
InputArray probImage,
Rect& window,
TermCriteria criteria
);
```
Back projection of the object histogram. See `calcBackProject` for details.
Initial search window. The function updates this parameter with the new window position.
Stop criteria for the underlying meanShift algorithm.
**Returns:** `RotatedRect` structure that includes the object position, size, and orientation.
The function implements the CAMSHIFT object tracking algorithm. It first finds an object center using `meanShift`, then adjusts the window size and finds the optimal rotation. The next position of the search window can be obtained with `RotatedRect::boundingRect()`.
### Example
```cpp theme={null}
Mat hsv, backproj;
cvtColor(frame, hsv, COLOR_BGR2HSV);
calcBackProject(&hsv, 1, channels, hist, backproj, ranges);
Rect trackWindow = Rect(x, y, w, h);
TermCriteria criteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1);
RotatedRect trackBox = CamShift(backproj, trackWindow, criteria);
```
## meanShift
Finds an object on a back projection image using iterative search.
```cpp theme={null}
int meanShift(
InputArray probImage,
Rect& window,
TermCriteria criteria
);
```
Back projection of the object histogram. See `calcBackProject` for details.
Initial search window. Updated with the final window position.
Stop criteria for the iterative search algorithm.
**Returns:** Number of iterations the algorithm took to converge.
The function implements the iterative object search algorithm. It computes the mass center in the window of the back projection image and shifts the search window center to the mass center. The procedure repeats until the specified number of iterations is reached or the window center shifts by less than the epsilon threshold.
Unlike `CamShift`, the search window size and orientation do not change during the search. For better results, pre-filter the back projection to remove noise using techniques like morphological operations or connected components analysis.
### Example
```cpp theme={null}
Mat hsv, backproj;
cvtColor(frame, hsv, COLOR_BGR2HSV);
calcBackProject(&hsv, 1, channels, hist, backproj, ranges);
Rect trackWindow = Rect(x, y, w, h);
TermCriteria criteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1);
int iterations = meanShift(backproj, trackWindow, criteria);
```
## computeECC
Computes the Enhanced Correlation Coefficient (ECC) value between two images.
```cpp theme={null}
double computeECC(
InputArray templateImage,
InputArray inputImage,
InputArray inputMask = noArray()
);
```
Input template image; must have 1 or 3 channels and be of type CV\_8U, CV\_16U, CV\_32F, or CV\_64F.
Input image to be compared with the template; must have the same type and number of channels as templateImage.
Optional single-channel mask to specify the valid region of interest.
**Returns:** The ECC similarity coefficient in the range \[-1, 1], where 1 indicates perfect similarity, 0 indicates no correlation, and -1 indicates perfect negative correlation.
The Enhanced Correlation Coefficient (ECC) is a normalized measure of similarity between two images. For single-channel images:
$$
\mathrm{ECC}(I, T) = \frac{\sum_{x} (I(x) - \mu_I)(T(x) - \mu_T)}
{\sqrt{\sum_{x} (I(x) - \mu_I)^2} \cdot \sqrt{\sum_{x} (T(x) - \mu_T)^2}}
$$
## findTransformECC
Finds the geometric transform (warp) between two images in terms of the ECC criterion.
```cpp theme={null}
double findTransformECC(
InputArray templateImage,
InputArray inputImage,
InputOutputArray warpMatrix,
int motionType = MOTION_AFFINE,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 50, 0.001),
InputArray inputMask = noArray()
);
```
Template image; 1 or 3 channels, CV\_8U, CV\_16U, CV\_32F, or CV\_64F type.
Input image to be warped; same type as templateImage.
Floating-point 2×3 or 3×3 mapping matrix (warp). Should be initialized with a rough alignment estimate.
Type of motion model. Default: `MOTION_AFFINE`
Termination criteria of the ECC algorithm.
Optional mask indicating valid values of inputImage.
**Returns:** The final enhanced correlation coefficient.
### Motion Type Constants
Translational motion model. The warpMatrix is 2×3 with the first 2×2 part being the identity matrix.
```cpp theme={null}
// 2 parameters estimated
[1 0 tx]
[0 1 ty]
```
Euclidean (rigid) transformation. Rotation and translation only.
```cpp theme={null}
// 3 parameters estimated (rotation angle, tx, ty)
[cos(θ) -sin(θ) tx]
[sin(θ) cos(θ) ty]
```
Affine motion model (default). 6 parameters estimated.
```cpp theme={null}
[a11 a12 tx]
[a21 a22 ty]
```
Homography as motion model. 8 parameters estimated. The warpMatrix is 3×3.
```cpp theme={null}
[h11 h12 h13]
[h21 h22 h23]
[h31 h32 h33]
```
The function implements an area-based alignment that builds on intensity similarities. If images undergo strong displacements or rotations, provide a rough initial transformation. Use the identity matrix if no prior information is available.
### Example
```cpp theme={null}
Mat warpMatrix = Mat::eye(2, 3, CV_32F);
TermCriteria criteria(TermCriteria::COUNT+TermCriteria::EPS, 50, 0.001);
double ecc = findTransformECC(
templateImage,
inputImage,
warpMatrix,
MOTION_AFFINE,
criteria
);
Mat aligned;
warpAffine(inputImage, aligned, warpMatrix, templateImage.size(),
INTER_LINEAR + WARP_INVERSE_MAP);
```
## findTransformECCWithMask
Extended version of `findTransformECC` that supports validity masks for both template and input images.
```cpp theme={null}
double findTransformECCWithMask(
InputArray templateImage,
InputArray inputImage,
InputArray templateMask,
InputArray inputMask,
InputOutputArray warpMatrix,
int motionType = MOTION_AFFINE,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 50, 1e-6),
int gaussFiltSize = 5
);
```
Single-channel 8-bit mask for templateImage indicating valid pixels. Must have the same size as templateImage.
Single-channel 8-bit mask for inputImage indicating valid pixels before warping. Must have the same size as inputImage.
Size of the Gaussian blur filter used for smoothing images and masks before computing alignment. Default: 5
The ECC is evaluated only over pixels that are valid in both images. On each iteration, inputMask is warped into the template frame and combined with templateMask.
## estimateRigidTransform (Deprecated)
Computes an optimal affine transformation between two 2D point sets.
```cpp theme={null}
Mat estimateRigidTransform(
InputArray src,
InputArray dst,
bool fullAffine
);
```
This function is deprecated. Use `cv::estimateAffine2D` or `cv::estimateAffinePartial2D` instead. If using with images, extract points using `cv::calcOpticalFlowPyrLK` first, then use the estimation functions.
First input 2D point set stored in std::vector or Mat, or an image stored in Mat.
Second input 2D point set of the same size and type as src, or another image.
If true, finds an optimal affine transformation with no restrictions (6 DOF). If false, limits transformations to translation, rotation, and uniform scaling (4 DOF).
**Returns:** 2×3 floating-point matrix representing the affine transform \[A|b].
# Optical Flow
Source: https://opencv-opencv.mintlify.app/api/video/optical-flow
Dense and sparse optical flow algorithms including Lucas-Kanade, Farneback, DIS, and variational refinement methods
Optical flow algorithms estimate motion between two consecutive frames by analyzing pixel displacement patterns. OpenCV provides both sparse (feature-based) and dense (per-pixel) optical flow methods.
## calcOpticalFlowPyrLK
Calculates sparse optical flow using the iterative Lucas-Kanade method with pyramids.
```cpp theme={null}
void calcOpticalFlowPyrLK(
InputArray prevImg,
InputArray nextImg,
InputArray prevPts,
InputOutputArray nextPts,
OutputArray status,
OutputArray err,
Size winSize = Size(21, 21),
int maxLevel = 3,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
int flags = 0,
double minEigThreshold = 1e-4
);
```
First 8-bit input image or pyramid constructed by `buildOpticalFlowPyramid`.
Second input image or pyramid of the same size and type as prevImg.
Vector of 2D points for which the flow needs to be found. Point coordinates must be single-precision floating-point.
Output vector of 2D points containing the calculated new positions of input features in the second image.
Output status vector (unsigned chars). Each element is set to 1 if flow was found for the corresponding feature, otherwise 0.
Output vector of errors for each feature. The error type depends on the flags parameter.
Size of the search window at each pyramid level. Default: Size(21, 21)
0-based maximal pyramid level number. 0 means no pyramid (single level), 1 means two levels, etc. Default: 3
Termination criteria for the iterative search algorithm. Default: 30 iterations or epsilon of 0.01
Operation flags:
* `OPTFLOW_USE_INITIAL_FLOW`: Use initial estimations stored in nextPts
* `OPTFLOW_LK_GET_MIN_EIGENVALS`: Use minimum eigen values as error measure
Default: 0
Minimum eigen value threshold. Features with smaller values are filtered out. Default: 1e-4
The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. It is parallelized with TBB for better performance. The algorithm calculates the minimum eigen value of a 2×2 spatial gradient matrix; if this value is less than minEigThreshold, the feature is filtered out.
### Example
```cpp theme={null}
vector prevPts, nextPts;
vector status;
vector err;
// Detect features in first frame
goodFeaturesToTrack(prevGray, prevPts, 100, 0.3, 7);
// Calculate optical flow
calcOpticalFlowPyrLK(prevGray, nextGray, prevPts, nextPts, status, err);
// Draw tracked points
for (size_t i = 0; i < prevPts.size(); i++) {
if (status[i]) {
line(frame, prevPts[i], nextPts[i], Scalar(0, 255, 0), 2);
circle(frame, nextPts[i], 3, Scalar(0, 255, 0), -1);
}
}
```
## buildOpticalFlowPyramid
Constructs an image pyramid for use with calcOpticalFlowPyrLK.
```cpp theme={null}
int buildOpticalFlowPyramid(
InputArray img,
OutputArrayOfArrays pyramid,
Size winSize,
int maxLevel,
bool withDerivatives = true,
int pyrBorder = BORDER_REFLECT_101,
int derivBorder = BORDER_CONSTANT,
bool tryReuseInputImage = true
);
```
8-bit input image.
Output pyramid.
Window size of optical flow algorithm. Must be at least as large as the winSize argument of calcOpticalFlowPyrLK.
0-based maximal pyramid level number.
Set to precompute gradients for every pyramid level. If false, calcOpticalFlowPyrLK will compute them internally. Default: true
Border mode for pyramid layers. Default: BORDER\_REFLECT\_101
Border mode for gradients. Default: BORDER\_CONSTANT
Put ROI of input image into the pyramid if possible. Set to false to force data copying. Default: true
**Returns:** Number of levels in the constructed pyramid (can be less than maxLevel).
## calcOpticalFlowFarneback
Computes dense optical flow using the Gunnar Farneback algorithm.
```cpp theme={null}
void calcOpticalFlowFarneback(
InputArray prev,
InputArray next,
InputOutputArray flow,
double pyr_scale,
int levels,
int winsize,
int iterations,
int poly_n,
double poly_sigma,
int flags
);
```
First 8-bit single-channel input image.
Second input image of the same size and type as prev.
Computed flow image with the same size as prev and type CV\_32FC2.
Image scale (\<1) to build pyramids. 0.5 means a classical pyramid where each next layer is twice smaller.
Number of pyramid layers including the initial image. levels=1 means no extra layers.
Averaging window size. Larger values increase robustness to noise and detect fast motion better, but yield more blurred motion fields.
Number of iterations the algorithm does at each pyramid level.
Size of pixel neighborhood used to find polynomial expansion. Larger values mean smoother surfaces. Typically 5 or 7.
Standard deviation of the Gaussian used to smooth derivatives. For poly\_n=5, use poly\_sigma=1.1; for poly\_n=7, use poly\_sigma=1.5.
Operation flags:
* `OPTFLOW_USE_INITIAL_FLOW`: Use input flow as initial approximation
* `OPTFLOW_FARNEBACK_GAUSSIAN`: Use Gaussian filter instead of box filter (more accurate but slower)
The function finds optical flow for each pixel using the Farneback algorithm:
$$
\texttt{prev}(y,x) \sim \texttt{next}(y + \texttt{flow}(y,x)[1], x + \texttt{flow}(y,x)[0])
$$
### Example
```cpp theme={null}
Mat flow;
calcOpticalFlowFarneback(
prevGray, nextGray, flow,
0.5, // pyr_scale
3, // levels
15, // winsize
3, // iterations
5, // poly_n
1.2, // poly_sigma
0 // flags
);
// Visualize flow
for (int y = 0; y < flow.rows; y += 10) {
for (int x = 0; x < flow.cols; x += 10) {
Point2f f = flow.at(y, x);
line(frame, Point(x, y), Point(x + f.x, y + f.y), Scalar(0, 255, 0));
}
}
```
## readOpticalFlow / writeOpticalFlow
Read and write optical flow files in .flo format.
```cpp theme={null}
Mat readOpticalFlow(const String& path);
bool writeOpticalFlow(const String& path, InputArray flow);
```
Path to the .flo file.
Flow field to be stored. Must be 2-channel, floating-point (CV\_32FC2). First channel is horizontal (u), second is vertical (v).
## DenseOpticalFlow Interface
Base class for dense optical flow algorithms.
```cpp theme={null}
class DenseOpticalFlow : public Algorithm {
public:
virtual void calc(InputArray I0, InputArray I1, InputOutputArray flow) = 0;
virtual void collectGarbage() = 0;
};
```
### calc
Calculates optical flow between two frames.
First 8-bit single-channel input image.
Second input image of the same size and type.
Computed flow image that has the same size as I0 and type CV\_32FC2.
### collectGarbage
Releases all inner buffers to free memory.
## SparseOpticalFlow Interface
Base interface for sparse optical flow algorithms.
```cpp theme={null}
class SparseOpticalFlow : public Algorithm {
public:
virtual void calc(
InputArray prevImg,
InputArray nextImg,
InputArray prevPts,
InputOutputArray nextPts,
OutputArray status,
OutputArray err = cv::noArray()
) = 0;
};
```
## FarnebackOpticalFlow
Class computing dense optical flow using the Gunnar Farneback algorithm.
```cpp theme={null}
class FarnebackOpticalFlow : public DenseOpticalFlow {
public:
static Ptr create(
int numLevels = 5,
double pyrScale = 0.5,
bool fastPyramids = false,
int winSize = 13,
int numIters = 10,
int polyN = 5,
double polySigma = 1.1,
int flags = 0
);
virtual int getNumLevels() const = 0;
virtual void setNumLevels(int numLevels) = 0;
virtual double getPyrScale() const = 0;
virtual void setPyrScale(double pyrScale) = 0;
// ... additional getters/setters for all parameters
};
```
### Example
```cpp theme={null}
Ptr farneback = FarnebackOpticalFlow::create();
farneback->setNumLevels(3);
farneback->setPyrScale(0.5);
farneback->setWinSize(15);
Mat flow;
farneback->calc(prevGray, nextGray, flow);
```
## SparsePyrLKOpticalFlow
Class for calculating sparse optical flow using the iterative Lucas-Kanade method with pyramids.
```cpp theme={null}
class SparsePyrLKOpticalFlow : public SparseOpticalFlow {
public:
static Ptr create(
Size winSize = Size(21, 21),
int maxLevel = 3,
TermCriteria crit = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
int flags = 0,
double minEigThreshold = 1e-4
);
virtual Size getWinSize() const = 0;
virtual void setWinSize(Size winSize) = 0;
virtual int getMaxLevel() const = 0;
virtual void setMaxLevel(int maxLevel) = 0;
// ... additional getters/setters
};
```
### Example
```cpp theme={null}
Ptr lk = SparsePyrLKOpticalFlow::create();
lk->setWinSize(Size(21, 21));
lk->setMaxLevel(3);
vector prevPts, nextPts;
vector status;
vector err;
goodFeaturesToTrack(prevGray, prevPts, 100, 0.3, 7);
lk->calc(prevGray, nextGray, prevPts, nextPts, status, err);
```
## DISOpticalFlow
Dense Inverse Search (DIS) optical flow algorithm with configurable speed/quality presets.
```cpp theme={null}
class DISOpticalFlow : public DenseOpticalFlow {
public:
enum {
PRESET_ULTRAFAST = 0,
PRESET_FAST = 1,
PRESET_MEDIUM = 2
};
static Ptr create(int preset = PRESET_FAST);
virtual int getFinestScale() const = 0;
virtual void setFinestScale(int val) = 0;
virtual int getPatchSize() const = 0;
virtual void setPatchSize(int val) = 0;
virtual int getPatchStride() const = 0;
virtual void setPatchStride(int val) = 0;
virtual bool getUseSpatialPropagation() const = 0;
virtual void setUseSpatialPropagation(bool val) = 0;
// ... additional parameters
};
```
DIS includes several enhancements over the paper implementation, including spatial propagation of flow vectors and support for initial flow approximation. Even the slowest preset is relatively fast; use DeepFlow if you need better quality and don't care about speed.
### Presets
Fastest preset with basic quality. Suitable for real-time applications where speed is critical.
Default preset offering good balance between speed and quality. Recommended for most applications.
Higher quality at the cost of some speed. Still relatively fast compared to other dense methods.
### Example
```cpp theme={null}
Ptr dis = DISOpticalFlow::create(DISOpticalFlow::PRESET_FAST);
dis->setFinestScale(2);
dis->setPatchStride(4);
Mat flow;
dis->calc(prevGray, nextGray, flow);
```
## VariationalRefinement
Variational optical flow refinement for improving existing flow fields.
```cpp theme={null}
class VariationalRefinement : public DenseOpticalFlow {
public:
static Ptr create();
virtual void calcUV(InputArray I0, InputArray I1,
InputOutputArray flow_u, InputOutputArray flow_v) = 0;
virtual int getFixedPointIterations() const = 0;
virtual void setFixedPointIterations(int val) = 0;
virtual int getSorIterations() const = 0;
virtual void setSorIterations(int val) = 0;
virtual float getAlpha() const = 0; // Smoothness weight
virtual void setAlpha(float val) = 0;
virtual float getDelta() const = 0; // Color constancy weight
virtual void setDelta(float val) = 0;
virtual float getGamma() const = 0; // Gradient constancy weight
virtual void setGamma(float val) = 0;
};
```
This class implements variational refinement of input flow fields. It uses the input flow to initialize minimization of the following functional:
$$
E(U) = \int_{\Omega} \delta \Psi(E_I) + \gamma \Psi(E_G) + \alpha \Psi(E_S)
$$
where $E_I$, $E_G$, $E_S$ are color constancy, gradient constancy, and smoothness terms respectively.
### Example
```cpp theme={null}
// First compute initial flow with DIS
Ptr dis = DISOpticalFlow::create();
Mat flow;
dis->calc(prevGray, nextGray, flow);
// Refine the flow
Ptr variational = VariationalRefinement::create();
variational->setAlpha(20.0f);
variational->setDelta(5.0f);
variational->setGamma(10.0f);
variational->calc(prevGray, nextGray, flow);
```
## Algorithm Comparison
**Lucas-Kanade (calcOpticalFlowPyrLK)**
* Type: Sparse (feature points)
* Speed: Very fast
* Accuracy: Good for well-textured features
* Use case: Feature tracking, structure from motion
**Farneback (calcOpticalFlowFarneback)**
* Type: Dense
* Speed: Medium
* Accuracy: Good
* Use case: General dense flow estimation
**DIS (Dense Inverse Search)**
* Type: Dense
* Speed: Fast (with presets)
* Accuracy: Good to excellent (preset-dependent)
* Use case: Real-time dense flow with quality/speed tradeoff
**VariationalRefinement**
* Type: Post-processing
* Speed: Medium
* Accuracy: Improves existing flow
* Use case: Refining flow from other algorithms
# Object Tracking
Source: https://opencv-opencv.mintlify.app/api/video/tracking
Object tracking algorithms including Tracker classes, KalmanFilter, and modern deep learning-based trackers
The tracking module provides various algorithms for tracking objects across video frames, from classical methods like Kalman filtering to modern deep learning-based approaches.
## Tracker Base Class
Base abstract class for long-term object trackers.
```cpp theme={null}
class Tracker {
public:
virtual void init(InputArray image, const Rect& boundingBox) = 0;
virtual bool update(InputArray image, Rect& boundingBox) = 0;
};
```
### init
Initialize the tracker with a known bounding box that surrounds the target.
```cpp theme={null}
virtual void init(
InputArray image,
const Rect& boundingBox
);
```
The initial frame containing the object to track.
The initial bounding box surrounding the target object.
### update
Update the tracker and find the new most likely bounding box for the target.
```cpp theme={null}
virtual bool update(
InputArray image,
Rect& boundingBox
);
```
The current frame to process.
Output parameter for the new target location. Updated only if the function returns true.
**Returns:** `true` if the target was located, `false` if the tracker cannot locate the target. Note that `false` does not necessarily mean the tracker has failed—the target may be temporarily out of view.
## KalmanFilter
Implements a standard Kalman filter for state estimation.
```cpp theme={null}
class KalmanFilter {
public:
KalmanFilter();
KalmanFilter(int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F);
void init(int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F);
const Mat& predict(const Mat& control = Mat());
const Mat& correct(const Mat& measurement);
// State vectors and matrices
Mat statePre; // Predicted state (x'(k))
Mat statePost; // Corrected state (x(k))
Mat transitionMatrix; // State transition matrix (A)
Mat controlMatrix; // Control matrix (B)
Mat measurementMatrix; // Measurement matrix (H)
Mat processNoiseCov; // Process noise covariance (Q)
Mat measurementNoiseCov;// Measurement noise covariance (R)
Mat errorCovPre; // Priori error covariance (P'(k))
Mat gain; // Kalman gain (K(k))
Mat errorCovPost; // Posteriori error covariance (P(k))
};
```
### Constructor
```cpp theme={null}
KalmanFilter(
int dynamParams,
int measureParams,
int controlParams = 0,
int type = CV_32F
);
```
Dimensionality of the state vector.
Dimensionality of the measurement vector.
Dimensionality of the control vector. Default: 0 (no control).
Type of the created matrices. Should be CV\_32F or CV\_64F. Default: CV\_32F.
### predict
Computes a predicted state.
```cpp theme={null}
const Mat& predict(const Mat& control = Mat());
```
Optional input control vector.
**Returns:** Reference to the predicted state vector.
### correct
Updates the predicted state from the measurement.
```cpp theme={null}
const Mat& correct(const Mat& measurement);
```
The measured system parameters.
**Returns:** Reference to the corrected state vector.
The Kalman filter operates in two steps: prediction (using the system model) and correction (using measurements). The filter maintains estimates of the state and its uncertainty through covariance matrices.
### Example
```cpp theme={null}
// Create Kalman filter: 4D state (x, y, dx, dy), 2D measurement (x, y)
KalmanFilter kf(4, 2, 0);
// Initialize state transition matrix (constant velocity model)
kf.transitionMatrix = (Mat_(4, 4) <<
1, 0, 1, 0,
0, 1, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1);
// Initialize measurement matrix
kf.measurementMatrix = (Mat_(2, 4) <<
1, 0, 0, 0,
0, 1, 0, 0);
// Set process and measurement noise
setIdentity(kf.processNoiseCov, Scalar::all(1e-5));
setIdentity(kf.measurementNoiseCov, Scalar::all(1e-1));
// Tracking loop
while (true) {
Mat prediction = kf.predict();
Mat measurement = getMeasurement(); // Your measurement function
Mat estimated = kf.correct(measurement);
}
```
## TrackerMIL
Multiple Instance Learning (MIL) tracker that trains a classifier online to separate object from background.
```cpp theme={null}
class TrackerMIL : public Tracker {
public:
struct Params {
float samplerInitInRadius; // Radius for positive samples during init
int samplerInitMaxNegNum; // # negative samples during init
float samplerSearchWinSize; // Search window size
float samplerTrackInRadius; // Radius for positive samples during tracking
int samplerTrackMaxPosNum; // # positive samples during tracking
int samplerTrackMaxNegNum; // # negative samples during tracking
int featureSetNumFeatures; // # features
};
static Ptr create(const Params& parameters = Params());
};
```
MIL avoids the drift problem for robust tracking. The implementation is based on "Visual Tracking with Online Multiple Instance Learning" by Babenko et al.
### Example
```cpp theme={null}
Ptr tracker = TrackerMIL::create();
Rect bbox = selectROI(frame); // User selects initial bounding box
tracker->init(frame, bbox);
while (true) {
cap >> frame;
if (tracker->update(frame, bbox)) {
rectangle(frame, bbox, Scalar(0, 255, 0), 2);
}
imshow("Tracking", frame);
}
```
## TrackerGOTURN
Generic Object Tracking Using Regression Networks - a CNN-based tracker trained offline.
```cpp theme={null}
class TrackerGOTURN : public Tracker {
public:
struct Params {
std::string modelTxt; // Path to .prototxt file
std::string modelBin; // Path to .caffemodel file
};
static Ptr create(const Params& parameters = Params());
};
```
GOTURN is much faster than online-training CNN trackers due to its offline training approach. It handles viewpoint changes, lighting changes, and deformations well, but does not handle occlusions. Requires pre-trained models (goturn.prototxt and goturn.caffemodel).
### Example
```cpp theme={null}
TrackerGOTURN::Params params;
params.modelTxt = "goturn.prototxt";
params.modelBin = "goturn.caffemodel";
Ptr tracker = TrackerGOTURN::create(params);
Rect bbox = selectROI(frame);
tracker->init(frame, bbox);
while (true) {
cap >> frame;
if (tracker->update(frame, bbox)) {
rectangle(frame, bbox, Scalar(255, 0, 0), 2);
}
imshow("GOTURN Tracking", frame);
}
```
## TrackerDaSiamRPN
Deep learning-based tracker using Siamese Region Proposal Networks.
```cpp theme={null}
class TrackerDaSiamRPN : public Tracker {
public:
struct Params {
std::string model; // SiamRPN model path
std::string kernel_cls1; // CLS kernel path
std::string kernel_r1; // R1 kernel path
int backend; // DNN backend
int target; // DNN target device
};
static Ptr create(const Params& parameters = Params());
virtual float getTrackingScore() = 0;
};
```
Returns the tracking confidence score for the current frame.
## TrackerNano
Super lightweight DNN-based tracker with model size of only 1.9 MB.
```cpp theme={null}
class TrackerNano : public Tracker {
public:
struct Params {
std::string backbone; // Backbone model for feature extraction
std::string neckhead; // Neckhead model for localization
int backend; // DNN backend
int target; // DNN target device
};
static Ptr create(const Params& parameters = Params());
virtual float getTrackingScore() = 0;
};
```
Nano tracker is extremely lightweight and fast due to its special model structure. Requires two models: one for feature extraction (backbone) and another for localization (neckhead).
## TrackerVit
Vision Transformer (ViT) based tracker, extremely lightweight at approximately 767KB.
```cpp theme={null}
class TrackerVit : public Tracker {
public:
struct Params {
std::string net; // Model path
int backend; // DNN backend
int target; // DNN target device
Scalar meanvalue; // Mean for preprocessing
Scalar stdvalue; // Std for preprocessing
float tracking_score_threshold; // Score threshold
};
static Ptr create(const Params& parameters = Params());
virtual float getTrackingScore() = 0;
};
```
Mean values for image preprocessing. Default: (0.485, 0.456, 0.406)
Standard deviation values for image preprocessing. Default: (0.229, 0.224, 0.225)
Minimum confidence threshold for tracking. Default: 0.20
## Comparison of Trackers
**MIL (Multiple Instance Learning)**
* Pros: Robust, handles appearance changes
* Cons: Slower than modern methods
* Use case: General purpose tracking
**GOTURN**
* Pros: Fast, no online training
* Cons: Doesn't handle occlusions
* Model size: \~500MB
* Use case: Real-time tracking without occlusions
**Nano, Vit**
* Pros: Extremely lightweight, very fast
* Model size: 1-2MB
* Use case: Embedded systems, mobile devices
**DaSiamRPN**
* Pros: High accuracy, robust
* Cons: Larger model size
* Use case: High-accuracy tracking
# C++ API
Source: https://opencv-opencv.mintlify.app/bindings/cpp
Learn how to use OpenCV's native C++ API, build from source, and write high-performance computer vision applications
## Overview
The C++ API is OpenCV's native interface, providing direct access to all functionality with optimal performance. All OpenCV modules are written in C++ and offer the most complete feature set.
## Installation
### Building from Source
OpenCV uses CMake as its build system. Here's how to build and install OpenCV from source:
```bash theme={null}
# Install dependencies
sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config \
libavcodec-dev libavformat-dev libswscale-dev
# Clone the repository
git clone https://github.com/opencv/opencv.git
cd opencv
mkdir build && cd build
# Configure with CMake
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local ..
# Build (use -j flag for parallel compilation)
make -j$(nproc)
# Install
sudo make install
```
```bash theme={null}
# Install dependencies using Homebrew
brew install cmake pkg-config
# Clone the repository
git clone https://github.com/opencv/opencv.git
cd opencv
mkdir build && cd build
# Configure with CMake
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local ..
# Build
make -j$(sysctl -n hw.ncpu)
# Install
sudo make install
```
```bash theme={null}
# Clone the repository
git clone https://github.com/opencv/opencv.git
cd opencv
mkdir build
cd build
# Configure with CMake (adjust paths as needed)
cmake -G "Visual Studio 17 2022" -A x64 \
-DCMAKE_BUILD_TYPE=Release ..
# Build using CMake or Visual Studio
cmake --build . --config Release
# Install
cmake --install .
```
### Key CMake Options
Customize your build with these important CMake flags:
* `BUILD_EXAMPLES=ON` - Build example applications
* `BUILD_opencv_world=ON` - Build single combined library (Windows)
* `WITH_CUDA=ON` - Enable CUDA support for GPU acceleration
* `WITH_TBB=ON` - Enable Intel TBB for parallel processing
* `OPENCV_EXTRA_MODULES_PATH=` - Add opencv\_contrib modules
## Including OpenCV in Your Project
### Using CMake
Create a `CMakeLists.txt` file:
```cmake theme={null}
cmake_minimum_required(VERSION 3.5)
project(MyOpenCVApp)
# Find OpenCV
find_package(OpenCV REQUIRED)
# Add your executable
add_executable(myapp main.cpp)
# Link OpenCV libraries
target_link_libraries(myapp ${OpenCV_LIBS})
```
Build your project:
```bash theme={null}
mkdir build && cd build
cmake ..
make
```
### Manual Compilation
```bash theme={null}
g++ main.cpp -o myapp `pkg-config --cflags --libs opencv4`
```
## Core Concepts
### Including Headers
The main header includes all modules:
```cpp theme={null}
#include
```
Or include specific modules for faster compilation:
```cpp theme={null}
#include
#include
#include
#include
```
### Namespace
All OpenCV C++ functions and classes are in the `cv` namespace:
```cpp theme={null}
using namespace cv;
// Or use explicit namespace
cv::Mat image;
```
## Code Examples
### Reading and Displaying an Image
```cpp theme={null}
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
// Read an image
Mat image = imread("image.jpg", IMREAD_COLOR);
if (image.empty()) {
cout << "Could not open or find the image" << endl;
return -1;
}
// Display the image
namedWindow("Display Image", WINDOW_AUTOSIZE);
imshow("Display Image", image);
// Wait for a keystroke
waitKey(0);
return 0;
}
```
### Face Detection with Cascade Classifier
```cpp theme={null}
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
void detectAndDraw(Mat& img, CascadeClassifier& cascade, double scale) {
vector faces;
Mat gray, smallImg;
// Convert to grayscale
cvtColor(img, gray, COLOR_BGR2GRAY);
// Resize for faster detection
double fx = 1 / scale;
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT);
equalizeHist(smallImg, smallImg);
// Detect faces
cascade.detectMultiScale(smallImg, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE,
Size(30, 30));
// Draw rectangles around detected faces
for (size_t i = 0; i < faces.size(); i++) {
Rect r = faces[i];
Point center(cvRound((r.x + r.width*0.5)*scale),
cvRound((r.y + r.height*0.5)*scale));
int radius = cvRound((r.width + r.height)*0.25*scale);
circle(img, center, radius, Scalar(255, 0, 0), 3, 8, 0);
}
imshow("Detection", img);
}
int main(int argc, const char** argv) {
VideoCapture capture;
Mat frame;
CascadeClassifier cascade;
double scale = 1.3;
// Load the cascade classifier
if (!cascade.load("haarcascade_frontalface_alt.xml")) {
cerr << "ERROR: Could not load classifier cascade" << endl;
return -1;
}
// Open camera
if (!capture.open(0)) {
cout << "Capture from camera failed" << endl;
return 1;
}
cout << "Video capturing has been started..." << endl;
for (;;) {
capture >> frame;
if (frame.empty())
break;
detectAndDraw(frame, cascade, scale);
char c = (char)waitKey(10);
if (c == 27 || c == 'q')
break;
}
return 0;
}
```
### Image Processing Pipeline
```cpp theme={null}
#include
using namespace cv;
int main() {
// Read image
Mat src = imread("input.jpg");
// Convert to grayscale
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
// Apply Gaussian blur
Mat blurred;
GaussianBlur(gray, blurred, Size(5, 5), 0);
// Edge detection
Mat edges;
Canny(blurred, edges, 50, 150);
// Find contours
vector> contours;
findContours(edges, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// Draw contours on original image
Mat result = src.clone();
drawContours(result, contours, -1, Scalar(0, 255, 0), 2);
// Save result
imwrite("output.jpg", result);
return 0;
}
```
### Working with Matrices
```cpp theme={null}
#include
#include
using namespace cv;
using namespace std;
int main() {
// Create a 3x3 matrix
Mat M = (Mat_(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cout << "M = " << endl << M << endl;
// Create identity matrix
Mat I = Mat::eye(4, 4, CV_64F);
cout << "I = " << endl << I << endl;
// Create matrix filled with zeros
Mat Z = Mat::zeros(2, 3, CV_8UC1);
cout << "Z = " << endl << Z << endl;
// Matrix operations
Mat A = Mat::eye(3, 3, CV_64F);
Mat B = Mat::ones(3, 3, CV_64F);
Mat C = A + B; // Addition
Mat D = A * B; // Multiplication
Mat E = A.t(); // Transpose
// Element access
double value = M.at(1, 2);
M.at(0, 0) = 10;
return 0;
}
```
## Best Practices
**Memory Management**: OpenCV uses reference counting for Mat objects. No need for manual memory management in most cases.
### Performance Tips
1. **Use appropriate data types**: Choose the smallest data type that fits your needs
2. **Avoid unnecessary copies**: Use references and ROI (Region of Interest) operations
3. **Enable parallel processing**: Build with TBB or OpenMP support
4. **Use GPU acceleration**: Enable CUDA modules for compute-intensive operations
### Mat Operations
```cpp theme={null}
// Efficient: No data copy, just header copy
Mat A = imread("image.jpg");
Mat B = A; // Shares data with A
// Deep copy when needed
Mat C = A.clone();
// Region of Interest (ROI) - no data copy
Rect roi(10, 10, 100, 100);
Mat imageROI = A(roi);
```
Modifying `B` will also modify `A` since they share the same data. Use `.clone()` or `.copyTo()` for independent copies.
## Module Organization
OpenCV is organized into several modules:
* **core**: Basic data structures and operations
* **imgproc**: Image processing functions
* **imgcodecs**: Image file reading and writing
* **videoio**: Video I/O operations
* **highgui**: GUI functionality
* **video**: Video analysis
* **calib3d**: Camera calibration and 3D reconstruction
* **features2d**: 2D feature detection and description
* **objdetect**: Object detection
* **dnn**: Deep neural network module
* **ml**: Machine learning
## Resources
* [OpenCV C++ API Reference](https://docs.opencv.org/4.x/)
* [OpenCV Tutorials](https://docs.opencv.org/4.x/d9/df8/tutorial_root.html)
* [OpenCV GitHub Repository](https://github.com/opencv/opencv)
* [Sample Code](https://github.com/opencv/opencv/tree/4.x/samples/cpp)
## Next Steps
* Explore the [Image Processing](/modules/imgproc) module
* Learn about [Video Analysis](/modules/video)
* Try [Object Detection](/modules/objdetect) features
# Java Bindings
Source: https://opencv-opencv.mintlify.app/bindings/java
Use OpenCV in Java applications and Android apps with automatically generated Java bindings
## Overview
OpenCV provides Java bindings through an automatic code generation system. The bindings include both the Java API (JAR file) and native JNI libraries, enabling OpenCV functionality in standard Java applications and Android apps.
## Installation
### Desktop Java Applications
Add OpenCV to your `pom.xml`:
```xml theme={null}
org.openpnpopencv4.9.0-0
```
Add to your `build.gradle`:
```groovy theme={null}
dependencies {
implementation 'org.openpnp:opencv:4.9.0-0'
}
```
1. Download OpenCV from [opencv.org](https://opencv.org/releases/)
2. Extract the archive
3. Find the Java bindings:
* JAR file: `build/bin/opencv-4xx.jar`
* Native library: `build/lib/libopencv_java4xx.so` (Linux), `.dylib` (macOS), or `.dll` (Windows)
4. Add JAR to your classpath
5. Load native library at runtime
### Android Applications
Add to your app's `build.gradle`:
```groovy theme={null}
android {
defaultConfig {
// ...
}
}
dependencies {
implementation 'org.opencv:opencv:4.9.0'
}
```
1. Download [OpenCV Android SDK](https://opencv.org/releases/)
2. Extract the SDK
3. Import as module in Android Studio:
* File → New → Import Module
* Select `sdk/java` directory
4. Add module dependency in `build.gradle`:
```groovy theme={null}
dependencies {
implementation project(':opencv')
}
```
### Building from Source
For custom builds:
```bash theme={null}
# Clone repository
git clone https://github.com/opencv/opencv.git
cd opencv
mkdir build && cd build
# Configure for Java
cmake -DBUILD_SHARED_LIBS=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_PERF_TESTS=OFF \
-DBUILD_opencv_java=ON \
..
# Build
make -j$(nproc)
# Find outputs in build/bin/
```
## Quick Start
### Loading the Native Library
Before using OpenCV in Java, load the native library:
```java theme={null}
import org.opencv.core.Core;
public class OpenCVExample {
static {
// Load native library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
System.out.println("OpenCV version: " + Core.getVersionString());
}
}
```
On Android, use `OpenCVLoader` to load the library asynchronously or through the OpenCV Manager.
### Android Initialization
```java theme={null}
import org.opencv.android.OpenCVLoader;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (OpenCVLoader.initLocal()) {
// OpenCV loaded successfully
System.out.println("OpenCV loaded");
} else {
// Handle initialization error
System.out.println("OpenCV not loaded");
}
}
}
```
## Core Concepts
### Mat Class
The `Mat` class represents images and matrices:
```java theme={null}
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;
// Create a 3x3 matrix
Mat mat = new Mat(3, 3, CvType.CV_8UC1);
// Create identity matrix
Mat identity = Mat.eye(3, 3, CvType.CV_64FC1);
// Create matrix filled with zeros
Mat zeros = Mat.zeros(480, 640, CvType.CV_8UC3);
// Create matrix filled with ones
Mat ones = Mat.ones(100, 100, CvType.CV_32FC1);
// Set all elements to a value
mat.setTo(new Scalar(255));
// Remember to release Mat objects
mat.release();
```
**Memory Management**: Unlike Python, Java OpenCV requires manual memory management. Always call `mat.release()` when done with Mat objects to prevent memory leaks.
## Code Examples
### Reading and Writing Images
```java theme={null}
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.core.Core;
public class ImageIO {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
// Read image
Mat image = Imgcodecs.imread("input.jpg");
if (image.empty()) {
System.out.println("Could not open or find the image");
return;
}
System.out.println("Image loaded: " + image.rows() + "x" + image.cols());
// Read in grayscale
Mat gray = Imgcodecs.imread("input.jpg", Imgcodecs.IMREAD_GRAYSCALE);
// Write image
Imgcodecs.imwrite("output.jpg", image);
// Clean up
image.release();
gray.release();
}
}
```
### Image Processing
```java theme={null}
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;
public class ImageProcessing {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
// Load image
Mat src = Imgcodecs.imread("input.jpg");
// Convert to grayscale
Mat gray = new Mat();
Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
// Apply Gaussian blur
Mat blurred = new Mat();
Imgproc.GaussianBlur(gray, blurred, new Size(5, 5), 0);
// Edge detection
Mat edges = new Mat();
Imgproc.Canny(blurred, edges, 50, 150);
// Find contours
java.util.List contours = new java.util.ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(edges, contours, hierarchy,
Imgproc.RETR_EXTERNAL,
Imgproc.CHAIN_APPROX_SIMPLE);
// Draw contours
Mat result = src.clone();
Imgproc.drawContours(result, contours, -1, new Scalar(0, 255, 0), 2);
// Save result
Imgcodecs.imwrite("output.jpg", result);
// Clean up
src.release();
gray.release();
blurred.release();
edges.release();
hierarchy.release();
result.release();
}
}
```
### Android Camera Processing
```java theme={null}
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.core.Core;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import android.app.Activity;
import android.os.Bundle;
public class Puzzle15Processor {
private static final int GRID_SIZE = 4;
private Mat mRgba15;
private Mat[] mCells15;
public void prepareGameSize(int width, int height) {
mRgba15 = new Mat(height, width, CvType.CV_8UC4);
mCells15 = new Mat[GRID_SIZE * GRID_SIZE];
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
int k = i * GRID_SIZE + j;
mCells15[k] = mRgba15.submat(
i * height / GRID_SIZE,
(i + 1) * height / GRID_SIZE,
j * width / GRID_SIZE,
(j + 1) * width / GRID_SIZE
);
}
}
}
public synchronized Mat puzzleFrame(Mat inputPicture) {
int rows = inputPicture.rows();
int cols = inputPicture.cols();
rows = rows - rows % 4;
cols = cols - cols % 4;
Mat[] cells = new Mat[GRID_SIZE * GRID_SIZE];
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
int k = i * GRID_SIZE + j;
cells[k] = inputPicture.submat(
i * inputPicture.rows() / GRID_SIZE,
(i + 1) * inputPicture.rows() / GRID_SIZE,
j * inputPicture.cols() / GRID_SIZE,
(j + 1) * inputPicture.cols() / GRID_SIZE
);
}
}
// Copy cells to output
for (int i = 0; i < GRID_SIZE * GRID_SIZE; i++) {
cells[i].copyTo(mCells15[i]);
}
// Draw grid lines
drawGrid(cols, rows, mRgba15);
// Release temporary cells
for (Mat cell : cells) {
cell.release();
}
return mRgba15;
}
private void drawGrid(int cols, int rows, Mat drawMat) {
for (int i = 1; i < GRID_SIZE; i++) {
Imgproc.line(drawMat,
new Point(0, i * rows / GRID_SIZE),
new Point(cols, i * rows / GRID_SIZE),
new Scalar(0, 255, 0, 255), 3);
Imgproc.line(drawMat,
new Point(i * cols / GRID_SIZE, 0),
new Point(i * cols / GRID_SIZE, rows),
new Scalar(0, 255, 0, 255), 3);
}
}
}
```
### Face Detection
```java theme={null}
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.imgcodecs.Imgcodecs;
public class FaceDetection {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
// Load cascade classifier
CascadeClassifier faceCascade = new CascadeClassifier();
faceCascade.load("haarcascade_frontalface_alt.xml");
// Load image
Mat image = Imgcodecs.imread("faces.jpg");
Mat gray = new Mat();
// Convert to grayscale
Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);
Imgproc.equalizeHist(gray, gray);
// Detect faces
MatOfRect faces = new MatOfRect();
faceCascade.detectMultiScale(gray, faces, 1.1, 2, 0,
new Size(30, 30), new Size());
// Draw rectangles around faces
for (Rect rect : faces.toArray()) {
Imgproc.rectangle(image,
new Point(rect.x, rect.y),
new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0), 2);
}
System.out.println("Detected " + faces.toArray().length + " faces");
// Save result
Imgcodecs.imwrite("output.jpg", image);
// Clean up
image.release();
gray.release();
faces.release();
}
}
```
### Working with Matrices
```java theme={null}
import org.opencv.core.*;
public class MatrixOperations {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
// Create matrices
Mat A = new Mat(3, 3, CvType.CV_64FC1);
Mat B = new Mat(3, 3, CvType.CV_64FC1);
// Fill with random values
Core.randu(A, 0, 10);
Core.randu(B, 0, 10);
System.out.println("Matrix A:\n" + A.dump());
// Matrix operations
Mat C = new Mat();
Core.add(A, B, C); // Addition
Core.subtract(A, B, C); // Subtraction
Core.gemm(A, B, 1, new Mat(), 0, C); // Multiplication
Core.transpose(A, C); // Transpose
// Element access
double[] data = new double[1];
A.get(0, 0, data);
System.out.println("Element [0,0]: " + data[0]);
// Set element
A.put(0, 0, 42.0);
// Clean up
A.release();
B.release();
C.release();
}
}
```
## Android Best Practices
### Using CameraBridgeViewBase
```java theme={null}
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
public class MainActivity extends Activity implements CvCameraViewListener2 {
private CameraBridgeViewBase mOpenCvCameraView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mOpenCvCameraView = findViewById(R.id.camera_view);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onCameraViewStarted(int width, int height) {
// Initialize processing
}
@Override
public void onCameraViewStopped() {
// Clean up
}
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
// Process frame here
// Return the Mat to be displayed
return rgba;
}
@Override
protected void onResume() {
super.onResume();
if (OpenCVLoader.initLocal()) {
mOpenCvCameraView.enableView();
}
}
@Override
protected void onPause() {
super.onPause();
if (mOpenCvCameraView != null) {
mOpenCvCameraView.disableView();
}
}
}
```
Always enable and disable the camera view in `onResume()` and `onPause()` to properly manage resources.
## Common Patterns
### Resource Management
```java theme={null}
// Use try-finally for cleanup
Mat mat = new Mat();
try {
// Use mat
Imgcodecs.imread("image.jpg", mat);
// Process...
} finally {
mat.release();
}
// Or create a helper method
public void processImage(String path) {
Mat image = Imgcodecs.imread(path);
if (image.empty()) return;
try {
// Processing logic
} finally {
image.release();
}
}
```
## Resources
* [OpenCV Java API Reference](https://docs.opencv.org/4.x/javadoc/)
* [Android Tutorials](https://docs.opencv.org/4.x/d9/d52/tutorial_android_dev_intro.html)
* [Sample Code](https://github.com/opencv/opencv/tree/4.x/samples/android)
* [OpenCV Android SDK](https://opencv.org/releases/)
## Next Steps
* Learn about [Image Processing](/modules/imgproc) in Java
* Explore [Object Detection](/modules/objdetect) features
* Build Android apps with OpenCV camera integration
# JavaScript Bindings (opencv.js)
Source: https://opencv-opencv.mintlify.app/bindings/javascript
Use OpenCV directly in web browsers with opencv.js compiled via Emscripten
## Overview
OpenCV.js brings OpenCV functionality to web browsers through WebAssembly (WASM). It's compiled from C++ using Emscripten and provides a JavaScript API that closely mirrors the C++ interface.
## Installation
### Using Pre-built opencv.js
The easiest way to get started:
```html CDN theme={null}
```
```html Local File theme={null}
```
The `async` attribute allows the page to load while opencv.js downloads. Use the `onRuntimeInitialized` callback to run code after OpenCV is ready.
### Waiting for OpenCV to Load
```html theme={null}
```
Or use the runtime callback:
```html theme={null}
```
### Building from Source
For custom builds with specific modules:
```bash theme={null}
# Install Emscripten
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
# Clone OpenCV
git clone https://github.com/opencv/opencv.git
cd opencv
# Build opencv.js
emcmake python ./platforms/js/build_js.py build_js \
--build_wasm \
--cmake_option="-DCMAKE_CXX_STANDARD=17"
# Output: build_js/bin/opencv.js
```
Emscripten 4.0.20+ requires C++17 or newer. The build process typically takes 5-10 minutes.
## Quick Start
### Basic HTML Template
```html theme={null}
OpenCV.js Example
OpenCV.js Demo
```
## Core Concepts
### Mat Objects
All images in OpenCV.js are represented by `cv.Mat`:
```javascript theme={null}
// Create Mat from canvas or image element
let img = cv.imread('imageId');
// Create empty Mat
let mat = new cv.Mat(rows, cols, cv.CV_8UC3);
// Create with specific values
let zeros = cv.Mat.zeros(480, 640, cv.CV_8UC1);
let ones = cv.Mat.ones(100, 100, cv.CV_8UC3);
let eye = cv.Mat.eye(3, 3, cv.CV_64FC1);
// IMPORTANT: Always delete Mat objects when done
mat.delete();
```
**Memory Management**: JavaScript garbage collection doesn't handle WebAssembly memory. Always call `.delete()` on Mat objects to prevent memory leaks.
### Reading Images
```javascript theme={null}
// From img element
let img = document.getElementById('myImage');
let mat = cv.imread(img);
// From canvas
let canvas = document.getElementById('myCanvas');
let mat = cv.imread(canvas);
// From video element (current frame)
let video = document.getElementById('myVideo');
let mat = cv.imread(video);
```
### Displaying Images
```javascript theme={null}
// Display Mat on canvas
cv.imshow('canvasOutputId', mat);
// Or get canvas element first
let canvas = document.getElementById('canvasOutput');
cv.imshow(canvas, mat);
```
## Code Examples
### Image Processing Pipeline
```html theme={null}
```
### Face Detection in Browser
```html theme={null}
Face Detection Demo
```
### Real-time Webcam Processing
```javascript theme={null}
let video = document.getElementById('videoInput');
let src = new cv.Mat(video.height, video.width, cv.CV_8UC4);
let dst = new cv.Mat(video.height, video.width, cv.CV_8UC1);
let cap = new cv.VideoCapture(video);
const FPS = 30;
function processVideo() {
let begin = Date.now();
// Capture frame
cap.read(src);
// Convert to grayscale
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
// Display
cv.imshow('canvasOutput', dst);
// Schedule next frame
let delay = 1000/FPS - (Date.now() - begin);
setTimeout(processVideo, delay);
}
// Start camera
navigator.mediaDevices.getUserMedia({video: true, audio: false})
.then(stream => {
video.srcObject = stream;
video.onloadedmetadata = () => {
video.play();
processVideo();
};
})
.catch(err => {
console.error('Camera error:', err);
});
```
### Working with Data
```javascript theme={null}
// Access pixel values
let mat = cv.imread('imageId');
let row = 10, col = 20;
let pixel = mat.ucharPtr(row, col);
// pixel is Uint8Array with [R, G, B, A] values
// Modify pixels
pixel[0] = 255; // Red
pixel[1] = 0; // Green
pixel[2] = 0; // Blue
pixel[3] = 255; // Alpha
// Get Mat data as typed array
let data = mat.data; // Uint8Array
// Create Mat from array
let dataArray = new Uint8Array([255, 0, 0, 255, 0, 255, 0, 255]);
let mat2 = new cv.Mat(2, 1, cv.CV_8UC4);
mat2.data.set(dataArray);
```
### Image Transformations
```javascript theme={null}
function transformImage() {
let src = cv.imread('inputImage');
let dst = new cv.Mat();
// Resize
let dsize = new cv.Size(320, 240);
cv.resize(src, dst, dsize, 0, 0, cv.INTER_LINEAR);
// Rotate
let center = new cv.Point(src.cols/2, src.rows/2);
let M = cv.getRotationMatrix2D(center, 45, 1.0);
cv.warpAffine(src, dst, M, new cv.Size(src.cols, src.rows));
// Flip
cv.flip(src, dst, 1); // 1 = horizontal, 0 = vertical, -1 = both
// Crop (using ROI)
let rect = new cv.Rect(10, 10, 100, 100);
let cropped = src.roi(rect);
cv.imshow('canvasOutput', dst);
// Clean up
src.delete();
dst.delete();
M.delete();
cropped.delete();
}
```
## Advanced Features
### Using DNN Module
```javascript theme={null}
// Load ONNX model
let net = cv.readNet('model.onnx');
// Prepare input
let img = cv.imread('imageId');
let blob = cv.blobFromImage(
img,
1.0, // scale factor
new cv.Size(224, 224), // size
new cv.Scalar(0, 0, 0, 0), // mean
true, // swapRB
false // crop
);
// Set input and run inference
net.setInput(blob);
let output = net.forward();
console.log('Output shape:', output.size());
// Clean up
img.delete();
blob.delete();
output.delete();
net.delete();
```
### Performance Optimization
```javascript theme={null}
// Good: Clean up immediately
function process() {
let mat = cv.imread('img');
let result = new cv.Mat();
try {
cv.cvtColor(mat, result, cv.COLOR_RGBA2GRAY);
cv.imshow('output', result);
} finally {
mat.delete();
result.delete();
}
}
// Bad: Memory leak
function processLeaky() {
let mat = cv.imread('img');
let result = new cv.Mat();
cv.cvtColor(mat, result, cv.COLOR_RGBA2GRAY);
// Forgot to delete!
}
```
```javascript theme={null}
// Good: Reuse Mat objects
let src = new cv.Mat();
let dst = new cv.Mat();
function processFrame() {
cap.read(src);
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
cv.imshow('output', dst);
}
// Call many times without recreating
setInterval(processFrame, 33);
// Clean up when done
// src.delete();
// dst.delete();
```
**Performance Tip**: Reuse Mat objects in loops instead of creating new ones. Only delete when completely done.
## Common Issues
### Memory Usage
```javascript theme={null}
// Check memory usage (Emscripten specific)
console.log('Memory:', cv.getBuildInformation());
// Force garbage collection (if available)
if (typeof gc === 'function') {
gc();
}
```
### Loading Files
OpenCV.js uses Emscripten's virtual filesystem:
```javascript theme={null}
// Create file in virtual FS
let utils = new Utils('');
utils.createFileFromUrl('model.xml', 'path/to/model.xml', () => {
// File loaded, can use it now
let cascade = new cv.CascadeClassifier();
cascade.load('model.xml');
});
```
## Build Configuration
Customize which modules to include:
```bash theme={null}
python ./platforms/js/build_js.py build_js \
--build_wasm \
--disable_single_file \
--cmake_option="-DBUILD_LIST=core,imgproc,objdetect,dnn"
```
Common build flags:
* `--build_wasm`: Build WebAssembly version
* `--disable_single_file`: Separate .wasm file
* `--enable_exception`: Enable C++ exceptions
* `--build_test`: Include test utilities
## Resources
* [OpenCV.js Tutorials](https://docs.opencv.org/4.x/d5/d10/tutorial_js_root.html)
* [OpenCV.js API Reference](https://docs.opencv.org/4.x/d5/d10/tutorial_js_root.html)
* [Building opencv.js](https://docs.opencv.org/4.x/d4/da1/tutorial_js_setup.html)
* [Sample Code](https://github.com/opencv/opencv/tree/4.x/samples/dnn)
* [Emscripten Documentation](https://emscripten.org/docs/)
## Next Steps
* Learn about [DNN Module](/modules/dnn) for deep learning
* Explore [Image Processing](/modules/imgproc) functions
* Try [Video Analysis](/modules/video) in the browser
# Python Bindings
Source: https://opencv-opencv.mintlify.app/bindings/python
Install and use OpenCV with Python, including NumPy integration and idiomatic Python examples
## Overview
The OpenCV Python bindings provide a Pythonic interface to OpenCV's C++ API. The bindings are automatically generated and offer excellent performance while maintaining ease of use. All functions work seamlessly with NumPy arrays.
## Installation
### Using pip (Recommended)
The easiest way to install OpenCV for Python:
```bash Standard Package theme={null}
pip install opencv-python
```
```bash Full Package (with contrib modules) theme={null}
pip install opencv-contrib-python
```
```bash Headless (no GUI) theme={null}
pip install opencv-python-headless
```
The `opencv-python` package includes prebuilt binaries for Windows, macOS, and Linux. No compilation required.
### Version Requirements
* Python 3.6 or higher
* NumPy (automatically installed as a dependency)
### Building from Source
For custom builds or the latest development version:
```bash theme={null}
# Clone the repository
git clone https://github.com/opencv/opencv.git
cd opencv
# Create build directory
mkdir build && cd build
# Configure with Python support
cmake -DBUILD_opencv_python3=ON \
-DPYTHON3_EXECUTABLE=$(which python3) \
-DPYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())") \
..
# Build
make -j$(nproc)
# Install
sudo make install
```
## Quick Start
### Importing OpenCV
```python theme={null}
import cv2 as cv
import numpy as np
```
The module is imported as `cv2` for historical reasons. This naming convention is standard across all OpenCV Python code.
### Verify Installation
```python theme={null}
import cv2 as cv
print(f"OpenCV version: {cv.__version__}")
print(f"NumPy version: {np.__version__}")
# Check available modules
print(cv.getBuildInformation())
```
## Core Concepts
### NumPy Integration
OpenCV images are represented as NumPy arrays:
```python theme={null}
import cv2 as cv
import numpy as np
# Load image as NumPy array
img = cv.imread('image.jpg')
print(f"Image shape: {img.shape}") # (height, width, channels)
print(f"Data type: {img.dtype}") # uint8
print(f"Image size: {img.size}") # total pixels
# Create blank image
blank = np.zeros((480, 640, 3), dtype=np.uint8)
# All NumPy operations work on images
img_float = img.astype(np.float32) / 255.0
mean_color = np.mean(img, axis=(0, 1))
```
### Image Format: BGR vs RGB
OpenCV uses BGR color order by default, not RGB. Convert when working with other libraries like Matplotlib or PIL.
```python theme={null}
import cv2 as cv
import matplotlib.pyplot as plt
# Read image (BGR format)
img_bgr = cv.imread('image.jpg')
# Convert to RGB for matplotlib
img_rgb = cv.cvtColor(img_bgr, cv.COLOR_BGR2RGB)
plt.imshow(img_rgb)
plt.show()
```
## Code Examples
### Reading and Writing Images
```python theme={null}
import cv2 as cv
# Read image
img = cv.imread('input.jpg')
if img is None:
print('Could not open or find the image')
exit(0)
# Read in grayscale
gray = cv.imread('input.jpg', cv.IMREAD_GRAYSCALE)
# Save image
cv.imwrite('output.jpg', img)
# Save with quality settings (JPEG)
cv.imwrite('output.jpg', img, [cv.IMWRITE_JPEG_QUALITY, 90])
```
### Video Capture and Display
```python theme={null}
import cv2 as cv
# Open webcam
cap = cv.VideoCapture(0)
# Or open video file
# cap = cv.VideoCapture('video.mp4')
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
if not ret:
print("Can't receive frame. Exiting...")
break
# Convert to grayscale
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# Display the frame
cv.imshow('frame', gray)
# Press 'q' to quit
if cv.waitKey(1) == ord('q'):
break
# Release resources
cap.release()
cv.destroyAllWindows()
```
### Face Detection
```python theme={null}
import cv2 as cv
import numpy as np
def detect_faces(img, cascade):
"""Detect faces in an image using Haar Cascade."""
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray = cv.equalizeHist(gray)
faces = cascade.detectMultiScale(
gray,
scaleFactor=1.3,
minNeighbors=4,
minSize=(30, 30),
flags=cv.CASCADE_SCALE_IMAGE
)
return faces
def draw_faces(img, faces):
"""Draw rectangles around detected faces."""
for (x, y, w, h) in faces:
cv.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# Load cascade classifier
cascade = cv.CascadeClassifier(
cv.samples.findFile('haarcascades/haarcascade_frontalface_alt.xml')
)
# Open camera
cam = cv.VideoCapture(0)
while True:
ret, img = cam.read()
if not ret:
break
faces = detect_faces(img, cascade)
draw_faces(img, faces)
cv.imshow('facedetect', img)
if cv.waitKey(5) == 27: # ESC key
break
cam.release()
cv.destroyAllWindows()
```
### Image Processing Pipeline
```python theme={null}
import cv2 as cv
import numpy as np
# Read image
src = cv.imread('input.jpg')
# Convert to grayscale
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# Apply Gaussian blur
blurred = cv.GaussianBlur(gray, (5, 5), 0)
# Edge detection
edges = cv.Canny(blurred, 50, 150)
# Find contours
contours, hierarchy = cv.findContours(
edges,
cv.RETR_EXTERNAL,
cv.CHAIN_APPROX_SIMPLE
)
# Draw contours on original image
result = src.copy()
cv.drawContours(result, contours, -1, (0, 255, 0), 2)
# Save result
cv.imwrite('output.jpg', result)
```
### Histogram Calculation and Visualization
```python theme={null}
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# Load image
src = cv.imread('image.jpg')
# Split into color channels
bgr_planes = cv.split(src)
# Calculate histograms
histSize = 256
histRange = (0, 256)
b_hist = cv.calcHist(bgr_planes, [0], None, [histSize], histRange)
g_hist = cv.calcHist(bgr_planes, [1], None, [histSize], histRange)
r_hist = cv.calcHist(bgr_planes, [2], None, [histSize], histRange)
# Plot histograms
plt.figure(figsize=(10, 6))
plt.plot(b_hist, color='b', label='Blue')
plt.plot(g_hist, color='g', label='Green')
plt.plot(r_hist, color='r', label='Red')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.legend()
plt.show()
```
### Working with ROI (Region of Interest)
```python theme={null}
import cv2 as cv
import numpy as np
# Load image
img = cv.imread('image.jpg')
# Define ROI using NumPy slicing
height, width = img.shape[:2]
roi = img[100:300, 200:400] # [y1:y2, x1:x2]
# Modify ROI
roi[:] = (0, 255, 0) # Fill with green
# Copy ROI to another location
img[50:250, 450:650] = roi
# Create ROI mask
mask = np.zeros(img.shape[:2], dtype=np.uint8)
cv.circle(mask, (width//2, height//2), 100, 255, -1)
# Apply mask
masked_img = cv.bitwise_and(img, img, mask=mask)
cv.imshow('Result', masked_img)
cv.waitKey(0)
```
### Image Transformations
```python theme={null}
import cv2 as cv
import numpy as np
img = cv.imread('image.jpg')
# Resize
resized = cv.resize(img, (640, 480))
# Or scale by factor
scaled = cv.resize(img, None, fx=0.5, fy=0.5)
# Rotate
height, width = img.shape[:2]
center = (width // 2, height // 2)
angle = 45
scale = 1.0
rotation_matrix = cv.getRotationMatrix2D(center, angle, scale)
rotated = cv.warpAffine(img, rotation_matrix, (width, height))
# Flip
flipped_horizontal = cv.flip(img, 1)
flipped_vertical = cv.flip(img, 0)
flipped_both = cv.flip(img, -1)
# Crop using NumPy slicing
cropped = img[100:400, 200:500]
```
## Advanced Features
### Working with Multiple Images
```python theme={null}
import cv2 as cv
import glob
# Process all images in a directory
image_paths = glob.glob('images/*.jpg')
for path in image_paths:
img = cv.imread(path)
# Apply processing
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blurred = cv.GaussianBlur(gray, (5, 5), 0)
# Save result
output_path = path.replace('images/', 'output/')
cv.imwrite(output_path, blurred)
```
```python theme={null}
import cv2 as cv
import numpy as np
# Read multiple images
img1 = cv.imread('image1.jpg')
img2 = cv.imread('image2.jpg')
img3 = cv.imread('image3.jpg')
# Horizontal stack
h_stack = np.hstack([img1, img2, img3])
# Vertical stack
v_stack = np.vstack([img1, img2, img3])
# Grid layout
row1 = np.hstack([img1, img2])
row2 = np.hstack([img3, img1])
grid = np.vstack([row1, row2])
cv.imshow('Grid', grid)
cv.waitKey(0)
```
### Performance Tips
```python theme={null}
import cv2 as cv
import numpy as np
import time
# Use optimized NumPy operations
img = cv.imread('large_image.jpg')
# Efficient: Vectorized operation
start = time.time()
result = img * 0.5
print(f"Vectorized: {time.time() - start:.4f}s")
# Inefficient: Loop over pixels (avoid this!)
start = time.time()
result = img.copy()
for i in range(img.shape[0]):
for j in range(img.shape[1]):
result[i, j] = img[i, j] * 0.5
print(f"Loop: {time.time() - start:.4f}s")
# Use in-place operations when possible
img *= 0.5 # Modifies img directly, no new array
# Pre-allocate arrays
output = np.empty_like(img)
cv.cvtColor(img, cv.COLOR_BGR2GRAY, dst=output[:,:,0])
```
## Package Structure
The Python bindings are organized to mirror the C++ API:
```python theme={null}
import cv2 as cv
# Core functionality
mat = cv.Mat()
version = cv.__version__
# Image processing
blurred = cv.GaussianBlur(img, (5, 5), 0)
# Video I/O
cap = cv.VideoCapture(0)
# Feature detection
orb = cv.ORB_create()
# DNN module
net = cv.dnn.readNet('model.onnx')
# Find sample data files
path = cv.samples.findFile('lena.jpg')
```
## Common Issues
**AttributeError**: If you get "module 'cv2' has no attribute", make sure you're using the correct module name and that the feature is included in your OpenCV build.
### Virtual Environments
```bash theme={null}
# Create virtual environment
python -m venv opencv_env
# Activate
source opencv_env/bin/activate # Linux/macOS
# or
opencv_env\Scripts\activate # Windows
# Install OpenCV
pip install opencv-python
```
## Resources
* [OpenCV-Python Tutorials](https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html)
* [PyPI Package](https://pypi.org/project/opencv-python/)
* [Python API Reference](https://docs.opencv.org/4.x/d6/d00/tutorial_py_root.html)
* [Sample Code](https://github.com/opencv/opencv/tree/4.x/samples/python)
## Next Steps
* Learn about [Image Processing](/modules/imgproc) with Python
* Explore [Deep Learning with DNN](/modules/dnn) module
* Try [Video Analysis](/modules/video) examples
# Color Spaces
Source: https://opencv-opencv.mintlify.app/concepts/color-spaces
Understanding and converting between different color representations in OpenCV
## Overview
Color spaces are different ways of representing colors numerically. OpenCV supports numerous color space conversions through the `cvtColor()` function.
## BGR Color Space
### Default in OpenCV
OpenCV uses **BGR** (Blue-Green-Red) as its default color format:
```cpp theme={null}
Mat img = imread("image.jpg"); // Loaded as BGR
// Access pixel
Vec3b pixel = img.at(y, x);
uchar blue = pixel[0];
uchar green = pixel[1];
uchar red = pixel[2];
```
Most other libraries (including matplotlib, PIL) use RGB order. Always convert when needed.
## Common Color Spaces
### RGB/BGR
**Use case**: Display, most common representation
```cpp theme={null}
// BGR to RGB
Mat rgb;
cvtColor(bgr, rgb, COLOR_BGR2RGB);
// RGB to BGR
cvtColor(rgb, bgr, COLOR_RGB2BGR);
```
### Grayscale
**Use case**: Simplify processing, reduce computation
```cpp theme={null}
// Color to grayscale
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
// Grayscale to color (creates 3 identical channels)
cvtColor(gray, img, COLOR_GRAY2BGR);
```
### HSV (Hue-Saturation-Value)
**Use case**: Color-based segmentation, lighting-independent processing
* **Hue**: Color type (0-179 in OpenCV)
* **Saturation**: Color intensity (0-255)
* **Value**: Brightness (0-255)
```cpp theme={null}
Mat hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
// Color range detection
Mat mask;
inRange(hsv, Scalar(0, 100, 100), Scalar(10, 255, 255), mask);
```
### LAB (L*a*b\*)
**Use case**: Perceptually uniform, skin detection
* **L**: Lightness (0-100)
* **a**: Green-Red axis
* **b**: Blue-Yellow axis
```cpp theme={null}
Mat lab;
cvtColor(img, lab, COLOR_BGR2Lab);
// Useful for color-based operations
vector channels;
split(lab, channels);
Mat L = channels[0]; // Lightness only
```
### YCrCb
**Use case**: Video compression, skin detection
* **Y**: Luminance
* **Cr**: Red-difference
* **Cb**: Blue-difference
```cpp theme={null}
Mat ycrcb;
cvtColor(img, ycrcb, COLOR_BGR2YCrCb);
```
## Color Conversion
### Basic Conversion
```cpp theme={null}
// Function signature
void cvtColor(InputArray src, OutputArray dst, int code);
// Examples
cvtColor(bgr, gray, COLOR_BGR2GRAY);
cvtColor(bgr, hsv, COLOR_BGR2HSV);
cvtColor(hsv, bgr, COLOR_HSV2BGR);
```
### Common Conversion Codes
| From | To | Code |
| ---- | ----- | ----------------- |
| BGR | Gray | `COLOR_BGR2GRAY` |
| BGR | RGB | `COLOR_BGR2RGB` |
| BGR | HSV | `COLOR_BGR2HSV` |
| BGR | LAB | `COLOR_BGR2Lab` |
| BGR | YCrCb | `COLOR_BGR2YCrCb` |
| HSV | BGR | `COLOR_HSV2BGR` |
| Gray | BGR | `COLOR_GRAY2BGR` |
## Practical Examples
### Color Detection
```cpp theme={null}
// Detect red objects
Mat hsv, mask;
cvtColor(img, hsv, COLOR_BGR2HSV);
// Red is at both ends of hue range
Mat mask1, mask2;
inRange(hsv, Scalar(0, 100, 100), Scalar(10, 255, 255), mask1);
inRange(hsv, Scalar(170, 100, 100), Scalar(180, 255, 255), mask2);
mask = mask1 | mask2;
```
### Lighting Normalization
```cpp theme={null}
// Separate intensity from color
Mat lab;
cvtColor(img, lab, COLOR_BGR2Lab);
vector channels;
split(lab, channels);
// Normalize L channel
equalizeHist(channels[0], channels[0]);
merge(channels, lab);
cvtColor(lab, img, COLOR_Lab2BGR);
```
### Skin Detection
```cpp theme={null}
Mat ycrcb;
cvtColor(img, ycrcb, COLOR_BGR2YCrCb);
// Skin color range in YCrCb
Mat skinMask;
inRange(ycrcb,
Scalar(0, 133, 77),
Scalar(255, 173, 127),
skinMask);
```
## Color Space Selection
* Color-based segmentation
* Lighting-independent tracking
* Hue provides rotation invariance
* Perceptually uniform
* Separate luminance from color
* Better for color difference calculations
* Video compression
* Skin detection
* Chroma subsampling
* Simplest representation
* Fastest processing
* Use when color not needed
## Best Practices
### Conversion Tips
1. **Minimize conversions**: Convert once, cache result
2. **Choose appropriate space**: Match algorithm requirements
3. **Remember value ranges**: HSV hue is 0-179, not 0-255
4. **Consider precision**: Use CV\_32F for sensitive operations
### Performance
```cpp theme={null}
// Avoid repeated conversion in loops
Mat hsv;
cvtColor(img, hsv, COLOR_BGR2HSV); // Convert once
for(int i = 0; i < 1000; i++) {
// Use hsv directly
processImage(hsv);
}
```
## See Also
* [Image Basics](/concepts/image-basics) - Working with images
* [ImgProc Module](/modules/imgproc) - Image processing functions
* [cvtColor Reference](https://docs.opencv.org/master/d8/d01/group__imgproc__color__conversions.html)
# Image Basics
Source: https://opencv-opencv.mintlify.app/concepts/image-basics
Understanding image representation and manipulation in OpenCV
## Image as Matrix
In OpenCV, images are represented as `Mat` objects - multi-dimensional arrays where:
* **Grayscale images**: Single-channel 2D arrays (CV\_8UC1)
* **Color images**: Multi-channel 2D arrays (typically CV\_8UC3 for BGR)
* **Pixel values**: Usually 8-bit unsigned integers (0-255)
## Image Properties
### Dimensions
```cpp theme={null}
Mat img = imread("image.jpg");
int height = img.rows; // Image height
int width = img.cols; // Image width
int channels = img.channels(); // Number of channels
Size size = img.size(); // Size(width, height)
```
### Data Type
```cpp theme={null}
int type = img.type(); // e.g., CV_8UC3
int depth = img.depth(); // e.g., CV_8U
bool empty = img.empty(); // Check if image is empty
```
## Color Spaces
OpenCV uses **BGR** (not RGB) as the default color order:
```cpp theme={null}
// Load color image (BGR by default)
Mat bgr = imread("image.jpg");
// Access BGR values
Vec3b pixel = bgr.at(y, x);
uchar blue = pixel[0];
uchar green = pixel[1];
uchar red = pixel[2];
```
Most other libraries use RGB order. Always convert when interfacing with external systems.
See [Color Spaces](/concepts/color-spaces) for conversion details.
## Pixel Access
### Single Pixel
```cpp theme={null}
// Grayscale image
uchar intensity = grayImg.at(y, x);
// Color image
Vec3b color = colorImg.at(y, x);
color[0] = 255; // Modify blue channel
colorImg.at(y, x) = color;
```
### Efficient Row Access
```cpp theme={null}
for(int i = 0; i < img.rows; i++) {
uchar* row = img.ptr(i);
for(int j = 0; j < img.cols; j++) {
row[j] = /* process pixel */;
}
}
```
### Multi-Channel Access
```cpp theme={null}
for(int i = 0; i < img.rows; i++) {
Vec3b* row = img.ptr(i);
for(int j = 0; j < img.cols; j++) {
row[j][0] = /* blue */;
row[j][1] = /* green */;
row[j][2] = /* red */;
}
}
```
## Image Operations
### Creating Images
```cpp theme={null}
// Create blank image
Mat img(480, 640, CV_8UC3, Scalar(0, 0, 0)); // Black
// Create from size
Mat img = Mat::zeros(Size(640, 480), CV_8UC3);
Mat img = Mat::ones(Size(640, 480), CV_8UC1);
```
### Copying Images
```cpp theme={null}
// Shallow copy (shares data)
Mat img2 = img1;
// Deep copy
Mat img2 = img1.clone();
img1.copyTo(img2);
// Copy with mask
img1.copyTo(img2, mask);
```
### Image ROI
```cpp theme={null}
// Select rectangular region
Rect roi(x, y, width, height);
Mat region = img(roi);
// Modify ROI (affects original)
region = Scalar(0, 255, 0); // Fill with green
```
## Channel Operations
### Split and Merge
```cpp theme={null}
// Split into channels
vector channels;
split(img, channels); // channels[0]=B, channels[1]=G, channels[2]=R
// Merge channels
Mat merged;
merge(channels, merged);
```
### Extract Single Channel
```cpp theme={null}
// Extract blue channel
Mat blueChannel;
extractChannel(img, blueChannel, 0);
// Set channel to zero
Mat channels[3];
split(img, channels);
channels[0] = Mat::zeros(img.size(), CV_8UC1);
merge(channels, 3, img); // Blue channel now zero
```
## Image I/O
### Reading Images
```cpp theme={null}
// Read color image
Mat img = imread("image.jpg");
// Read grayscale
Mat gray = imread("image.jpg", IMREAD_GRAYSCALE);
// Read with alpha channel
Mat rgba = imread("image.png", IMREAD_UNCHANGED);
```
### Writing Images
```cpp theme={null}
// Save image
imwrite("output.jpg", img);
// Save with parameters
vector params = {IMWRITE_JPEG_QUALITY, 95};
imwrite("output.jpg", img, params);
```
## Common Patterns
### Convert to Grayscale
```cpp theme={null}
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
```
### Resize Image
```cpp theme={null}
Mat resized;
resize(img, resized, Size(320, 240));
// Scale by factor
resize(img, resized, Size(), 0.5, 0.5);
```
### Crop Image
```cpp theme={null}
Rect cropRegion(x, y, width, height);
Mat cropped = img(cropRegion).clone();
```
## Performance Tips
Prefer ptr\() over at\() for pixel-level operations
Continuous matrices enable faster processing
Use references and ROI instead of cloning
Use OpenCV functions instead of pixel loops
## See Also
* [Matrices](/concepts/matrices) - Understanding Mat class
* [Color Spaces](/concepts/color-spaces) - Color conversion
* [ImgProc Module](/modules/imgproc) - Image processing functions
# Matrices (Mat)
Source: https://opencv-opencv.mintlify.app/concepts/matrices
Understanding OpenCV's Mat class for n-dimensional dense array representation
## Overview
The `Mat` class is the fundamental data structure in OpenCV, representing an n-dimensional dense numerical array. It can store images, matrices, vectors, histograms, point clouds, and other multi-dimensional data.
## Mat Structure
### Key Properties
A Mat object consists of:
* **Header**: Contains metadata (dimensions, type, reference counter)
* **Data pointer**: Points to the actual pixel/element data
* **Step array**: Defines memory layout for multi-dimensional indexing
### Memory Layout
For a 2D matrix, element `M(i,j)` is located at:
```
addr(M[i,j]) = M.data + M.step[0]*i + M.step[1]*j
```
Matrices are stored **row-by-row** (row-major order), making row access more efficient than column access.
## Creating Matrices
### Basic Creation
```cpp theme={null}
// Create 7x7 complex matrix filled with 1+3j
Mat M(7, 7, CV_32FC2, Scalar(1, 3));
// Create and initialize later
Mat img(Size(320, 240), CV_8UC3);
// Multi-dimensional array
int sz[] = {100, 100, 100};
Mat bigCube(3, sz, CV_8U, Scalar::all(0));
```
### From Existing Data
```cpp theme={null}
// Wrap user-allocated data (no copy)
unsigned char* pixels = /* your data */;
Mat img(height, width, CV_8UC3, pixels, step);
```
## Data Types
OpenCV supports various data types:
* `CV_8U`: 8-bit unsigned integer
* `CV_8S`: 8-bit signed integer
* `CV_16U`, `CV_16S`: 16-bit integers
* `CV_32S`: 32-bit signed integer
* `CV_32F`: 32-bit floating point
* `CV_64F`: 64-bit floating point
Channel specification: `CV_8UC1` (1 channel), `CV_8UC3` (3 channels), `CV_8UC(n)` (n channels, max 512)
## Reference Counting
Mat uses **shallow copying** by default:
```cpp theme={null}
Mat A = Mat::eye(10, 10, CV_32S);
Mat B = A; // B points to same data as A
```
For a deep copy:
```cpp theme={null}
Mat C = A.clone();
```
## Element Access
### Direct Access
```cpp theme={null}
// Single element access
M.at(i, j) += 1.0;
// Row pointer access (faster)
for(int i = 0; i < M.rows; i++) {
const double* Mi = M.ptr(i);
for(int j = 0; j < M.cols; j++)
sum += std::max(Mi[j], 0.);
}
```
### Iterator Access
```cpp theme={null}
MatConstIterator_ it = M.begin();
MatConstIterator_ it_end = M.end();
for(; it != it_end; ++it)
sum += std::max(*it, 0.);
```
## ROI (Region of Interest)
```cpp theme={null}
// Select rectangular region
Mat roi(img, Rect(10, 10, 100, 100));
// Row/column selection
Mat row3 = M.row(3);
Mat col7 = M.col(7);
// Range selection
Mat B = A(Range::all(), Range(1, 3)); // All rows, columns 1-2
```
ROI operations are O(1) as they only create a new header pointing to the same data.
## Continuous Matrices
Check if matrix data is continuous (no gaps between rows):
```cpp theme={null}
if(M.isContinuous()) {
// Process as single row for better performance
cols *= rows;
rows = 1;
}
```
## Best Practices
Work with sub-matrices using ROI instead of copying data
Access rows sequentially for better cache performance
Optimize processing for continuous matrices
Use clone() when you need independent data
## See Also
* [Image Basics](/concepts/image-basics) - Working with images as matrices
* [Memory Management](/concepts/memory-management) - Understanding Mat memory model
* [Core Module](/modules/core) - Basic Mat operations
# Memory Management
Source: https://opencv-opencv.mintlify.app/concepts/memory-management
Understanding OpenCV's automatic memory management and reference counting
## Overview
OpenCV uses **automatic memory management** with reference counting for Mat objects. This eliminates most manual memory management while providing efficiency through shallow copying.
## Reference Counting
### How It Works
Each Mat object has:
* **Header**: Small, cheap to copy (\~100 bytes)
* **Data block**: Large, expensive to copy
* **Reference counter**: Tracks how many Mat objects share the data
```cpp theme={null}
Mat A(100, 100, CV_8UC1); // Allocates data, refcount = 1
Mat B = A; // Shares data, refcount = 2
Mat C = A; // Shares data, refcount = 3
// When C goes out of scope, refcount = 2
// When B goes out of scope, refcount = 1
// When A goes out of scope, refcount = 0, data freed
```
### Shallow vs Deep Copy
**Shallow Copy** (default):
```cpp theme={null}
Mat A = imread("image.jpg");
Mat B = A; // Only header copied
B.at(0,0) = 0; // Modifies A too!
```
**Deep Copy**:
```cpp theme={null}
Mat A = imread("image.jpg");
Mat B = A.clone(); // Data copied
B.at(0,0) = 0; // A unchanged
// Alternative
Mat C;
A.copyTo(C);
```
## Memory Allocation
### Automatic Allocation
```cpp theme={null}
// create() allocates only if needed
Mat A;
A.create(100, 100, CV_8UC3); // Allocates
A.create(100, 100, CV_8UC3); // No reallocation (same size/type)
A.create(200, 200, CV_8UC3); // Reallocates (different size)
```
### Constructor Allocation
```cpp theme={null}
// Allocates on construction
Mat A(480, 640, CV_8UC3);
Mat B(Size(640, 480), CV_8UC3, Scalar(0));
// No allocation
Mat C; // Empty matrix
```
## UMat and Memory Allocators
### MatAllocator
Custom memory allocation through `MatAllocator` class:
```cpp theme={null}
class CV_EXPORTS MatAllocator {
public:
virtual UMatData* allocate(int dims, const int* sizes,
int type, void* data,
size_t* step, AccessFlag flags,
UMatUsageFlags usageFlags) const = 0;
virtual bool allocate(UMatData* data, AccessFlag accessflags,
UMatUsageFlags usageFlags) const = 0;
virtual void deallocate(UMatData* data) const = 0;
};
```
### Memory Pools
OpenCV supports buffer pooling for frequent allocations:
```cpp theme={null}
// Get buffer pool controller
BufferPoolController* pool =
allocator->getBufferPoolController();
```
## Best Practices
### Avoid Unnecessary Copies
```cpp Good theme={null}
void processImage(const Mat& img) {
// Use reference, no copy
Mat result;
filter2D(img, result, -1, kernel);
return result;
}
```
```cpp Bad theme={null}
void processImage(Mat img) { // Copies header
// Process...
}
```
### Return Values
```cpp theme={null}
// Efficient: No copy due to return value optimization
Mat createImage() {
Mat img(480, 640, CV_8UC3);
// ... initialize
return img; // No actual copy
}
Mat result = createImage(); // Moves or shallow copy
```
### Pre-allocation
```cpp theme={null}
// Pre-allocate output
Mat dst;
dst.create(src.size(), src.type());
// OpenCV functions allocate if needed
cvtColor(src, dst, COLOR_BGR2GRAY); // Will allocate dst if needed
```
## Manual Memory Management
### External Data
Wrap user-allocated memory:
```cpp theme={null}
// User manages memory
unsigned char* data = new unsigned char[640*480*3];
// OpenCV wraps it (no copy, no ownership)
Mat img(480, 640, CV_8UC3, data);
// Process with OpenCV
cvtColor(img, gray, COLOR_BGR2GRAY);
// User must free
delete[] data;
```
### Release Memory
```cpp theme={null}
Mat A(1000, 1000, CV_8UC3);
// Manually release (rarely needed)
A.release(); // Decrements refcount, frees if zero
// Check if empty
if(A.empty()) {
// A has no data
}
```
## Memory Continuity
### Continuous Storage
```cpp theme={null}
// Check if continuous (no padding between rows)
if(img.isContinuous()) {
// Can treat as 1D array
size_t total = img.total() * img.elemSize();
processData(img.ptr(), total);
}
```
### ROI and Continuity
```cpp theme={null}
Mat img = imread("image.jpg"); // Continuous
Mat roi = img(Rect(10, 10, 100, 100)); // NOT continuous
// Make continuous
Mat roiCopy = roi.clone(); // Now continuous
```
## Common Pitfalls
**Dangling Pointers**
```cpp theme={null}
Mat getROI() {
Mat img(480, 640, CV_8UC3);
return img(Rect(0, 0, 100, 100)); // Dangerous!
} // img destroyed, ROI points to freed memory
Mat roi = getROI(); // roi is invalid!
```
Fix: Return a clone or the full image.
**Shared Data Modification**
```cpp theme={null}
Mat A = imread("img.jpg");
Mat B = A; // Shares data
GaussianBlur(B, B, Size(5,5), 0); // Modifies A too!
```
Fix: Use `B = A.clone()` if independent data needed.
## Performance Considerations
Always pass Mat as const reference to avoid header copies
ROI creates header only, no data copy
Use shallow copies when possible
Reuse matrices in loops to avoid reallocation
## Memory Debugging
```cpp theme={null}
// Check properties
std::cout << "Size: " << img.total() * img.elemSize() << " bytes\n";
std::cout << "Continuous: " << img.isContinuous() << "\n";
std::cout << "Submatrix: " << img.isSubmatrix() << "\n";
// Check reference count (internal)
// Mat doesn't expose refcount directly
```
## See Also
* [Matrices](/concepts/matrices) - Understanding Mat class
* [Image Basics](/concepts/image-basics) - Working with images
* [Core Module](/modules/core) - Core data structures
# Color Space Conversions
Source: https://opencv-opencv.mintlify.app/examples/color-spaces
Learn how to convert between different color spaces and apply thresholding techniques
This guide covers color space conversions between BGR, RGB, HSV, grayscale, and other formats, along with thresholding techniques for image segmentation.
## Overview
Color spaces represent colors in different ways for various purposes:
* **BGR/RGB**: Standard color representation for displays
* **HSV**: Hue, Saturation, Value - intuitive for color filtering
* **Grayscale**: Single channel intensity values
* **LAB**: Perceptually uniform color space
* **YCrCb**: Luminance and chrominance separation
## BGR to RGB Conversion
OpenCV reads images in BGR format by default, but many libraries expect RGB.
```python theme={null}
import cv2 as cv
import matplotlib.pyplot as plt
# Read image (loaded in BGR format)
img_bgr = cv.imread("image.jpg")
# Convert BGR to RGB
img_rgb = cv.cvtColor(img_bgr, cv.COLOR_BGR2RGB)
# Display using matplotlib (expects RGB)
plt.imshow(img_rgb)
plt.title("RGB Image")
plt.axis('off')
plt.show()
# Display using OpenCV (expects BGR)
cv.imshow("BGR Image", img_bgr)
cv.waitKey(0)
```
```cpp theme={null}
#include
using namespace cv;
// Read image (loaded in BGR format)
Mat img_bgr = imread("image.jpg");
// Convert BGR to RGB
Mat img_rgb;
cvtColor(img_bgr, img_rgb, COLOR_BGR2RGB);
// Display (OpenCV expects BGR)
imshow("BGR Image", img_bgr);
waitKey(0);
```
OpenCV uses BGR format by default for historical reasons related to early camera standards. Always convert to RGB when interfacing with other libraries like Matplotlib, PIL, or TensorFlow.
## BGR to Grayscale Conversion
Convert color images to grayscale for simplified processing.
```python theme={null}
import cv2 as cv
# Read color image
img = cv.imread("image.jpg")
# Convert to grayscale
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow("Original", img)
cv.imshow("Grayscale", gray)
cv.waitKey(0)
cv.destroyAllWindows()
```
```cpp theme={null}
#include
using namespace cv;
// Read color image
Mat img = imread("image.jpg");
// Convert to grayscale
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
imshow("Original", img);
imshow("Grayscale", gray);
waitKey(0);
```
You can also load images directly in grayscale using `imread("image.jpg", IMREAD_GRAYSCALE)` to skip the conversion step.
## BGR to HSV Conversion
HSV (Hue, Saturation, Value) is ideal for color-based object detection and filtering.
```python theme={null}
import cv2 as cv
import numpy as np
# Read image
img = cv.imread("image.jpg")
# Convert BGR to HSV
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# Split into channels
h, s, v = cv.split(hsv)
cv.imshow("Original", img)
cv.imshow("Hue", h)
cv.imshow("Saturation", s)
cv.imshow("Value", v)
cv.waitKey(0)
```
```cpp theme={null}
#include
using namespace cv;
using namespace std;
// Read image
Mat img = imread("image.jpg");
// Convert BGR to HSV
Mat hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
// Split into channels
vector channels;
split(hsv, channels);
imshow("Original", img);
imshow("Hue", channels[0]);
imshow("Saturation", channels[1]);
imshow("Value", channels[2]);
waitKey(0);
```
## Color Range Detection with HSV
Detect specific colors by defining HSV ranges.
```python theme={null}
import cv2 as cv
import numpy as np
# Read image
frame = cv.imread("image.jpg")
# Convert to HSV
frame_HSV = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
# Define range for blue color in HSV
low_H = 100
low_S = 50
low_V = 50
high_H = 130
high_S = 255
high_V = 255
# Create mask for blue color
mask = cv.inRange(frame_HSV, (low_H, low_S, low_V), (high_H, high_S, high_V))
# Apply mask to original image
result = cv.bitwise_and(frame, frame, mask=mask)
cv.imshow("Original", frame)
cv.imshow("Mask", mask)
cv.imshow("Result", result)
cv.waitKey(0)
```
```cpp theme={null}
#include
using namespace cv;
// Read image
Mat frame = imread("image.jpg");
// Convert to HSV
Mat frame_HSV;
cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
// Define range for blue color in HSV
int low_H = 100, low_S = 50, low_V = 50;
int high_H = 130, high_S = 255, high_V = 255;
// Create mask for blue color
Mat mask;
inRange(frame_HSV, Scalar(low_H, low_S, low_V),
Scalar(high_H, high_S, high_V), mask);
// Apply mask to original image
Mat result;
bitwise_and(frame, frame, result, mask);
imshow("Original", frame);
imshow("Mask", mask);
imshow("Result", result);
waitKey(0);
```
### Common HSV Color Ranges
| Color | Hue Range (H) | Saturation (S) | Value (V) |
| ------ | ------------- | -------------- | --------- |
| Red | 0-10, 170-180 | 50-255 | 50-255 |
| Orange | 10-25 | 50-255 | 50-255 |
| Yellow | 25-35 | 50-255 | 50-255 |
| Green | 35-85 | 50-255 | 50-255 |
| Blue | 100-130 | 50-255 | 50-255 |
| Purple | 130-160 | 50-255 | 50-255 |
In OpenCV, Hue values range from 0-179 (not 0-359) to fit in a single byte. Adjust your ranges accordingly.
## Thresholding
Thresholding converts grayscale images to binary images by applying a threshold value.
### Basic Thresholding
```python theme={null}
import cv2 as cv
# Read image in grayscale
src = cv.imread("image.jpg")
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# Apply different threshold types
threshold_value = 127
max_value = 255
# Binary threshold
_, binary = cv.threshold(src_gray, threshold_value, max_value, cv.THRESH_BINARY)
# Binary inverted threshold
_, binary_inv = cv.threshold(src_gray, threshold_value, max_value, cv.THRESH_BINARY_INV)
# Truncate threshold
_, truncate = cv.threshold(src_gray, threshold_value, max_value, cv.THRESH_TRUNC)
# To zero threshold
_, to_zero = cv.threshold(src_gray, threshold_value, max_value, cv.THRESH_TOZERO)
# To zero inverted threshold
_, to_zero_inv = cv.threshold(src_gray, threshold_value, max_value, cv.THRESH_TOZERO_INV)
cv.imshow("Original", src_gray)
cv.imshow("Binary", binary)
cv.imshow("Binary Inverted", binary_inv)
cv.imshow("Truncate", truncate)
cv.imshow("To Zero", to_zero)
cv.waitKey(0)
```
```cpp theme={null}
#include
using namespace cv;
// Read image in grayscale
Mat src = imread("image.jpg");
Mat src_gray;
cvtColor(src, src_gray, COLOR_BGR2GRAY);
// Apply different threshold types
int threshold_value = 127;
int max_value = 255;
Mat binary, binary_inv, truncate, to_zero, to_zero_inv;
// Binary threshold
threshold(src_gray, binary, threshold_value, max_value, THRESH_BINARY);
// Binary inverted threshold
threshold(src_gray, binary_inv, threshold_value, max_value, THRESH_BINARY_INV);
// Truncate threshold
threshold(src_gray, truncate, threshold_value, max_value, THRESH_TRUNC);
// To zero threshold
threshold(src_gray, to_zero, threshold_value, max_value, THRESH_TOZERO);
// To zero inverted threshold
threshold(src_gray, to_zero_inv, threshold_value, max_value, THRESH_TOZERO_INV);
imshow("Original", src_gray);
imshow("Binary", binary);
imshow("Binary Inverted", binary_inv);
waitKey(0);
```
### Adaptive Thresholding
Adaptive thresholding calculates different thresholds for different regions, useful for varying lighting conditions.
```python theme={null}
import cv2 as cv
# Read image in grayscale
img = cv.imread("image.jpg")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# Global threshold
_, global_thresh = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
# Adaptive threshold (mean)
adaptive_mean = cv.adaptiveThreshold(gray, 255,
cv.ADAPTIVE_THRESH_MEAN_C,
cv.THRESH_BINARY, 11, 2)
# Adaptive threshold (gaussian)
adaptive_gaussian = cv.adaptiveThreshold(gray, 255,
cv.ADAPTIVE_THRESH_GAUSSIAN_C,
cv.THRESH_BINARY, 11, 2)
cv.imshow("Original", gray)
cv.imshow("Global Threshold", global_thresh)
cv.imshow("Adaptive Mean", adaptive_mean)
cv.imshow("Adaptive Gaussian", adaptive_gaussian)
cv.waitKey(0)
```
```cpp theme={null}
#include
using namespace cv;
// Read image in grayscale
Mat img = imread("image.jpg");
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
Mat global_thresh, adaptive_mean, adaptive_gaussian;
// Global threshold
threshold(gray, global_thresh, 127, 255, THRESH_BINARY);
// Adaptive threshold (mean)
adaptiveThreshold(gray, adaptive_mean, 255,
ADAPTIVE_THRESH_MEAN_C,
THRESH_BINARY, 11, 2);
// Adaptive threshold (gaussian)
adaptiveThreshold(gray, adaptive_gaussian, 255,
ADAPTIVE_THRESH_GAUSSIAN_C,
THRESH_BINARY, 11, 2);
imshow("Original", gray);
imshow("Global Threshold", global_thresh);
imshow("Adaptive Mean", adaptive_mean);
imshow("Adaptive Gaussian", adaptive_gaussian);
waitKey(0);
```
## Other Color Space Conversions
```python theme={null}
import cv2 as cv
img = cv.imread("image.jpg")
# BGR to LAB
lab = cv.cvtColor(img, cv.COLOR_BGR2LAB)
# BGR to YCrCb
ycrcb = cv.cvtColor(img, cv.COLOR_BGR2YCrCb)
# BGR to XYZ
xyz = cv.cvtColor(img, cv.COLOR_BGR2XYZ)
# BGR to HLS
hls = cv.cvtColor(img, cv.COLOR_BGR2HLS)
# HSV back to BGR
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
bgr_from_hsv = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
```
```cpp theme={null}
#include
using namespace cv;
Mat img = imread("image.jpg");
Mat lab, ycrcb, xyz, hls, hsv, bgr_from_hsv;
// BGR to LAB
cvtColor(img, lab, COLOR_BGR2LAB);
// BGR to YCrCb
cvtColor(img, ycrcb, COLOR_BGR2YCrCb);
// BGR to XYZ
cvtColor(img, xyz, COLOR_BGR2XYZ);
// BGR to HLS
cvtColor(img, hls, COLOR_BGR2HLS);
// HSV back to BGR
cvtColor(img, hsv, COLOR_BGR2HSV);
cvtColor(hsv, bgr_from_hsv, COLOR_HSV2BGR);
```
## Key Functions
| Function | Description |
| --------------------- | ---------------------------------------------------- |
| `cvtColor()` | Convert image between color spaces |
| `split()` | Split multi-channel image into separate channels |
| `merge()` | Merge separate channels into multi-channel image |
| `inRange()` | Create binary mask for pixels within specified range |
| `threshold()` | Apply global threshold to grayscale image |
| `adaptiveThreshold()` | Apply adaptive threshold for varying lighting |
## Common Color Space Codes
| Conversion | Code |
| ----------- | ---------------- |
| BGR to RGB | `COLOR_BGR2RGB` |
| BGR to Gray | `COLOR_BGR2GRAY` |
| BGR to HSV | `COLOR_BGR2HSV` |
| BGR to LAB | `COLOR_BGR2LAB` |
| HSV to BGR | `COLOR_HSV2BGR` |
| Gray to BGR | `COLOR_GRAY2BGR` |
For color-based object detection, HSV color space is generally more robust than BGR/RGB because it separates color information (Hue) from lighting conditions (Value).
# Face Detection and Recognition
Source: https://opencv-opencv.mintlify.app/examples/face-recognition
Complete guide to face detection using Haar Cascades and deep learning models with facial landmark detection and recognition
## Overview
OpenCV provides multiple approaches for face detection and recognition:
* **Haar Cascade Classifiers**: Fast, CPU-friendly classical method
* **DNN-based Detection**: Modern deep learning approach with YuNet
* **Face Recognition**: Feature extraction and matching with SFace
* **Facial Landmarks**: Detect eyes, nose, and mouth positions
## Haar Cascade Face Detection
```python theme={null}
import cv2 as cv
import numpy as np
from video import create_capture
from common import clock, draw_str
def detect(img, cascade):
"""Detect faces in image using cascade classifier"""
rects = cascade.detectMultiScale(img,
scaleFactor=1.3,
minNeighbors=4,
minSize=(30, 30),
flags=cv.CASCADE_SCALE_IMAGE)
if len(rects) == 0:
return []
rects[:,2:] += rects[:,:2]
return rects
def draw_rects(img, rects, color):
"""Draw rectangles around detected faces"""
for x1, y1, x2, y2 in rects:
cv.rectangle(img, (x1, y1), (x2, y2), color, 2)
# Load cascade classifiers
cascade_fn = "haarcascades/haarcascade_frontalface_alt.xml"
nested_fn = "haarcascades/haarcascade_eye.xml"
cascade = cv.CascadeClassifier(cv.samples.findFile(cascade_fn))
nested = cv.CascadeClassifier(cv.samples.findFile(nested_fn))
# Initialize video capture
cam = create_capture(0, fallback='synth:bg={}:noise=0.05'.format(
cv.samples.findFile('lena.jpg')))
while True:
_ret, img = cam.read()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
gray = cv.equalizeHist(gray)
t = clock()
rects = detect(gray, cascade)
vis = img.copy()
draw_rects(vis, rects, (0, 255, 0))
# Detect eyes within face regions
if not nested.empty():
for x1, y1, x2, y2 in rects:
roi = gray[y1:y2, x1:x2]
vis_roi = vis[y1:y2, x1:x2]
subrects = detect(roi.copy(), nested)
draw_rects(vis_roi, subrects, (255, 0, 0))
dt = clock() - t
draw_str(vis, (20, 20), 'time: %.1f ms' % (dt*1000))
cv.imshow('facedetect', vis)
if cv.waitKey(5) == 27:
break
cv.destroyAllWindows()
```
```cpp theme={null}
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include
using namespace std;
using namespace cv;
void detectAndDraw(Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip)
{
vector faces, faces2;
const static Scalar colors[] = {
Scalar(255,0,0), Scalar(255,128,0),
Scalar(255,255,0), Scalar(0,255,0),
Scalar(0,128,255), Scalar(0,255,255),
Scalar(0,0,255), Scalar(255,0,255)
};
Mat gray, smallImg;
cvtColor(img, gray, COLOR_BGR2GRAY);
double fx = 1 / scale;
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR_EXACT);
equalizeHist(smallImg, smallImg);
double t = (double)getTickCount();
cascade.detectMultiScale(smallImg, faces,
1.1, 2, 0 | CASCADE_SCALE_IMAGE,
Size(30, 30));
if(tryflip) {
flip(smallImg, smallImg, 1);
cascade.detectMultiScale(smallImg, faces2,
1.1, 2, 0 | CASCADE_SCALE_IMAGE,
Size(30, 30));
for(vector::const_iterator r = faces2.begin();
r != faces2.end(); ++r) {
faces.push_back(Rect(smallImg.cols - r->x - r->width,
r->y, r->width, r->height));
}
}
t = (double)getTickCount() - t;
printf("detection time = %g ms\n", t*1000/getTickFrequency());
for(size_t i = 0; i < faces.size(); i++) {
Rect r = faces[i];
Mat smallImgROI;
vector nestedObjects;
Point center;
Scalar color = colors[i%8];
int radius;
double aspect_ratio = (double)r.width/r.height;
if(0.75 < aspect_ratio && aspect_ratio < 1.3) {
center.x = cvRound((r.x + r.width*0.5)*scale);
center.y = cvRound((r.y + r.height*0.5)*scale);
radius = cvRound((r.width + r.height)*0.25*scale);
circle(img, center, radius, color, 3, 8, 0);
} else {
rectangle(img, Point(cvRound(r.x*scale), cvRound(r.y*scale)),
Point(cvRound((r.x + r.width-1)*scale),
cvRound((r.y + r.height-1)*scale)),
color, 3, 8, 0);
}
if(nestedCascade.empty())
continue;
smallImgROI = smallImg(r);
nestedCascade.detectMultiScale(smallImgROI, nestedObjects,
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
for(size_t j = 0; j < nestedObjects.size(); j++) {
Rect nr = nestedObjects[j];
center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
radius = cvRound((nr.width + nr.height)*0.25*scale);
circle(img, center, radius, color, 3, 8, 0);
}
}
imshow("result", img);
}
int main(int argc, const char** argv)
{
VideoCapture capture;
Mat frame;
CascadeClassifier cascade, nestedCascade;
double scale = 1.0;
string cascadeName = "data/haarcascades/haarcascade_frontalface_alt.xml";
string nestedCascadeName = "data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
if(!cascade.load(samples::findFile(cascadeName))) {
cerr << "ERROR: Could not load classifier cascade" << endl;
return -1;
}
if(!nestedCascade.load(samples::findFileOrKeep(nestedCascadeName)))
cerr << "WARNING: Could not load nested cascade" << endl;
if(!capture.open(0)) {
cout << "Capture from camera didn't work" << endl;
return 1;
}
cout << "Video capturing has been started ..." << endl;
for(;;) {
capture >> frame;
if(frame.empty())
break;
Mat frame1 = frame.clone();
detectAndDraw(frame1, cascade, nestedCascade, scale, false);
char c = (char)waitKey(10);
if(c == 27 || c == 'q' || c == 'Q')
break;
}
return 0;
}
```
## DNN-based Face Detection with YuNet
Modern deep learning approach using the YuNet model for accurate face detection with facial landmarks.
```python theme={null}
import cv2 as cv
import numpy as np
# Initialize YuNet face detector
detector = cv.FaceDetectorYN.create(
'face_detection_yunet_2021dec.onnx',
"",
(320, 320),
score_threshold=0.9,
nms_threshold=0.3,
top_k=5000
)
def visualize(input, faces, fps, thickness=2):
"""Draw detected faces with landmarks"""
if faces[1] is not None:
for idx, face in enumerate(faces[1]):
coords = face[:-1].astype(np.int32)
# Draw bounding box
cv.rectangle(input,
(coords[0], coords[1]),
(coords[0]+coords[2], coords[1]+coords[3]),
(0, 255, 0), thickness)
# Draw facial landmarks
cv.circle(input, (coords[4], coords[5]), 2, (255, 0, 0), thickness) # right eye
cv.circle(input, (coords[6], coords[7]), 2, (0, 0, 255), thickness) # left eye
cv.circle(input, (coords[8], coords[9]), 2, (0, 255, 0), thickness) # nose
cv.circle(input, (coords[10], coords[11]), 2, (255, 0, 255), thickness) # right mouth
cv.circle(input, (coords[12], coords[13]), 2, (0, 255, 255), thickness) # left mouth
cv.putText(input, f'FPS: {fps:.2f}', (1, 16),
cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# Video capture
cap = cv.VideoCapture(0)
frameWidth = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
frameHeight = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
detector.setInputSize([frameWidth, frameHeight])
tm = cv.TickMeter()
while True:
hasFrame, frame = cap.read()
if not hasFrame:
break
# Detect faces
tm.start()
faces = detector.detect(frame)
tm.stop()
# Draw results
visualize(frame, faces, tm.getFPS())
cv.imshow('Face Detection', frame)
if cv.waitKey(1) == 27:
break
cap.release()
cv.destroyAllWindows()
```
## Face Recognition with SFace
Compare faces and determine if they belong to the same person.
```python theme={null}
import cv2 as cv
# Initialize detector and recognizer
detector = cv.FaceDetectorYN.create(
'face_detection_yunet_2021dec.onnx',
"", (320, 320), 0.9, 0.3, 5000
)
recognizer = cv.FaceRecognizerSF.create(
'face_recognition_sface_2021dec.onnx', ""
)
# Load two images
img1 = cv.imread('person1.jpg')
img2 = cv.imread('person2.jpg')
# Detect faces
detector.setInputSize((img1.shape[1], img1.shape[0]))
faces1 = detector.detect(img1)
detector.setInputSize((img2.shape[1], img2.shape[0]))
faces2 = detector.detect(img2)
if faces1[1] is None or faces2[1] is None:
print("No face detected")
else:
# Align and extract features
face1_align = recognizer.alignCrop(img1, faces1[1][0])
face2_align = recognizer.alignCrop(img2, faces2[1][0])
face1_feature = recognizer.feature(face1_align)
face2_feature = recognizer.feature(face2_align)
# Compare faces
cosine_score = recognizer.match(
face1_feature, face2_feature,
cv.FaceRecognizerSF_FR_COSINE
)
l2_score = recognizer.match(
face1_feature, face2_feature,
cv.FaceRecognizerSF_FR_NORM_L2
)
# Thresholds
cosine_threshold = 0.363
l2_threshold = 1.128
if cosine_score >= cosine_threshold:
print(f"Same person (Cosine: {cosine_score:.3f})")
else:
print(f"Different person (Cosine: {cosine_score:.3f})")
if l2_score <= l2_threshold:
print(f"Same person (L2: {l2_score:.3f})")
else:
print(f"Different person (L2: {l2_score:.3f})")
```
## Key Parameters
### Haar Cascade Detection
| Parameter | Description | Typical Value |
| -------------- | ----------------------------------- | ------------- |
| `scaleFactor` | Image scale reduction between scans | 1.1 - 1.3 |
| `minNeighbors` | Minimum neighbors for detection | 3 - 6 |
| `minSize` | Minimum object size | (30, 30) |
| `maxSize` | Maximum object size | Image size |
### YuNet Detection
| Parameter | Description | Typical Value |
| ----------------- | ------------------------- | ------------- |
| `score_threshold` | Confidence threshold | 0.6 - 0.9 |
| `nms_threshold` | Non-maximum suppression | 0.3 - 0.5 |
| `top_k` | Max detections before NMS | 5000 |
**Model Downloads**: YuNet and SFace models can be downloaded from the [OpenCV Zoo](https://github.com/opencv/opencv_zoo):
* [YuNet Face Detection](https://github.com/opencv/opencv_zoo/tree/master/models/face_detection_yunet)
* [SFace Recognition](https://github.com/opencv/opencv_zoo/tree/master/models/face_recognition_sface)
## Performance Tips
Reduce input image size for faster processing:
```python theme={null}
fx = 0.5 # 50% scale
small = cv.resize(gray, None, fx=fx, fy=fx)
```
Improve detection under varying lighting:
```python theme={null}
gray = cv.equalizeHist(gray)
```
Tune `minNeighbors` to balance speed vs accuracy:
* Lower values = faster, more false positives
* Higher values = slower, fewer false positives
Detect nested features only within face regions to improve performance
**Privacy Considerations**: Face recognition technology should be used responsibly. Always obtain consent when processing personal biometric data and comply with relevant privacy regulations.
## Next Steps
* Explore [Object Detection](/modules/objdetect) for other detection methods
* Learn about [DNN Module](/modules/dnn) for deep learning models
* Check [Video I/O](/api/videoio) for camera handling
* See [Image Processing](/modules/imgproc) for preprocessing techniques
# Image Classification with DNN
Source: https://opencv-opencv.mintlify.app/examples/image-classification
Learn how to perform image classification using OpenCV DNN module with popular models like ResNet, MobileNet, and GoogLeNet
Image classification is the task of assigning a label or category to an entire image. OpenCV's DNN module provides support for running pre-trained classification models from various frameworks.
## Supported Models
The following classification models are commonly used:
* **ResNet** - Deep residual networks with skip connections
* **MobileNet** - Lightweight models optimized for mobile devices
* **GoogLeNet** - Inception architecture from Google
* **SqueezeNet** - Compact model with high accuracy
* **VGG** - Very deep convolutional networks
## Python Implementation
```python theme={null}
import cv2 as cv
import numpy as np
```
```python theme={null}
# Load the pre-trained model
model = 'bvlc_googlenet.caffemodel'
config = 'bvlc_googlenet.prototxt'
net = cv.dnn.readNet(model, config)
# Set computation backend and target
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
```
You can use `DNN_BACKEND_CUDA` and `DNN_TARGET_CUDA` for GPU acceleration if available.
```python theme={null}
# Load class labels
classes = None
with open('classification_classes_ILSVRC2012.txt', 'rt') as f:
classes = f.read().rstrip('\n').split('\n')
```
```python theme={null}
# Read the input image
frame = cv.imread('image.jpg')
# Create a 4D blob from the image
# GoogLeNet uses 224x224 input with mean [104, 117, 123]
blob = cv.dnn.blobFromImage(frame, 1.0, (224, 224), [104, 117, 123], False, crop=False)
```
The `blobFromImage` function performs:
* Mean subtraction
* Scaling
* Optional channel swapping (BGR to RGB)
* Resizing to target dimensions
```python theme={null}
# Set the input blob
net.setInput(blob)
# Forward pass to get predictions
out = net.forward()
# Get the class with highest score
out = out.flatten()
classId = np.argmax(out)
confidence = out[classId]
# Print the result
label = f'{classes[classId]}: {confidence:.4f}'
print(label)
```
```python theme={null}
# Get inference time
t, _ = net.getPerfProfile()
inference_time = t * 1000.0 / cv.getTickFrequency()
# Put text on image
label = f'Inference time: {inference_time:.2f} ms'
cv.putText(frame, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))
label = f'{classes[classId]}: {confidence:.4f}'
cv.putText(frame, label, (0, 40), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))
# Display the result
cv.imshow('Classification', frame)
cv.waitKey(0)
```
## C++ Implementation
```cpp theme={null}
#include
#include
#include
#include
#include