OpenCV Data Structures
1. Classification
- Basic Data Types
- Helper Objects
- Large Array Objects: Mat
- STL Data Structures: vector, pair
2. Basic Data Structures: Point, Scalar, Size, cv::Rect, RotatedRect, Matx
3. Point
3.1 Point Construction
cv::Point2i p; // 2D integer point, e.g., (x, y)
cv::Point3f p; // 3D float point, e.g., (a, b, c)
cv::Point3f p2(p1); // copy constructor
cv::Point2i p(x0, x1); // assignment constructor (int)
cv::Point3d p(x0, x1, x2); // assignment constructor (double)
3.2 Accessing Point Coordinates
int i = p.x; // x-coordinate of Point2i
float f = p.y; // y-coordinate of Point2f
3.3 Point Methods
p.inside(r); // check if point p is inside rectangle r
cv::Point2i p = Point2i(10, 10);
cv::Point2i p1 = Point2i(200, 200);
cv::Rect2i r = Rect2i(0, 0, 100, 100);
bool b = p.inside(r); // true
bool b1 = p1.inside(r); // false
4. Scalar
cv::Scalar is a four-element vector of doubles.
4.1 Scalar Construction
cv::Scalar s; // default constructor
cv::Scalar s2(s1); // copy constructor
cv::Scalar s(x0); // assignment constructor
cv::Scalar s(x0, x1, x2, x3); // assignment constructor
4.2 Scalar Methods
s1.mul(s2); // element-wise multiplication
Scalar s(255, 255, 255);
Scalar s2(10, 100, 255);
Scalar ss = s.mul(s2); // (2550, 25500, 65025)
5. Size
5.1 Size Construction
cv::Size sz; // default constructor
cv::Size2i sz; // 2D integer size
cv::Size2f sz; // 2D float size
cv::Size sz2(sz1); // copy constructor
cv::Size2f sz(w, h); // assignment constructor
5.2 Accessing Size Members
sz.width; // width
sz.height; // height
Note: Size does not support interconversion with old data structures.
6. Rect (Axis-Aligned Rectangle)
6.1 Rect Construction
cv::Rect r; // default constructor
cv::Rect r2(r1); // copy constructor
cv::Rect(x, y, w, h); // top-left corner (x,y), width w, height h
cv::Rect(p, sz); // p is top-left corner, sz contains width and height
cv::Rect(p1, p2); // p1 top-left, p2 bottom-right
Size size = Size(10, 10);
cv::Rect r1(0, 0, 100, 100);
cv::Rect r2(p, size);
cv::Rect r3(p, p2);
6.2 Rect Accessors
r.x; // left coordinate
r.y; // top coordinate
r.width; // width
r.height; // height
6.3 Rect Methods
r.area(); // area
r.tl(); // top-left point
r.br(); // bottom-right point
r.contains(p); // true if p is inside r
// equivalent to p.inside(r)
6.4 Rect Arithmetic
cv::Rect r3 = r1 & r2; // intersection
cv::Rect r3 = r1 | r2; // union
cv::Rect rs = r + s; // shift by a size
bool eq = (r1 == r2); // strict equality
7. RotatedRect
7.1 RotatedRect Construction
cv::RotatedRect rr(); // default constructor
cv::RotatedRect rr2(rr1); // copy constructor
cv::RotatedRect(p1, p2, p3); // three points defining the rectangle
cv::RotatedRect(p, sz, theta); // center p, size sz, angle theta (0-360°)
cv::RotatedRect rr1 = cv::RotatedRect(p, size, 45);
7.2 RotatedRect Accessors and Methods
rr.center; // center point
rr.size; // size
rr.angle; // rotation angle
rr.points(pts); // fills an array of 4 corner points
Point2i p_rr = rr.center;
Size p_size = rr.size;
float p_angle = rr.angle;
Point2f pts[4];
rr.points(pts); // now pts[0..3] contain the four corners
8. Matx (Fixed-size Matrix)
Mat is for arbitrary dimensions; Matx is for fixed-size matrices and is faster.
8.1 Matx Construction
cv::Matx33f m33f;
cv::Matx43d m43d; // default constructor
cv::Matx22d m22d(n22d); // copy constructor
Matx33f m(1, 2, 3,
4, 5, 6,
7, 8, 9); // assignment constructor
cv::Matx33f m33f = cv::Matx33f::all(x); // all elements = x
cv::Matx23d m23d = cv::Matx23d::zeros(); // all zeros
cv::Matx16f m16f = cv::Matx16f::ones(); // all ones
cv::Matx33f m33f = cv::Matx33f::eye(); // identity matrix
8.2 Accessing Matx Elements
m(i, j); // element at row i, column j
m(i); // for 1D: element at index i
double d23 = m23d(1, 2); // row 1, column 2 (0-based)
float f16 = m16f(0, 0); // first element
Matx13f m13f = m33f.row(2); // third row
Matx31f m31f = m33f.col(2); // third column
8.3 Basic Arithmetic
m1 = m0; // assignment
m0 * m1; // matrix multiplication
m0 + m1; // addition
m0 - m1; // subtraction
m * a; // matrix times scalar
a * m; // scalar times matrix
m / a; // matrix divided by scalar (a != 0)
8.4 Matrix Operations
n44f = m44f.t(); // transpose
// Dot product (element-wise multiplication) requires identical structure
m1.mul(m2); // element-wise multiplication
// Scalar (inner) product: (a1,a2,a3,a4) * (b1,b2,b3,b4) = a1*b1+a2*b2+a3*b3+a4*b4
// Vector (matrix) multiplication: use * operator
// e.g., 3x3 matrix multiplied by 3x1 vector
8.5 Example: Complete Code Snippet
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// Image data
Mat src = imread("F:/OpenCV/images/002.jpg");
imshow("src", src);
// Points
Point2i p = Point2i(10, 10);
Point2i p2 = Point2i(200, 200);
Point2f p1 = Point2f(0, 0);
Point2f p3 = Point2f(10, 10);
Point2f p4 = Point2f(200, 200);
Rect2i r = Rect2i(0, 0, 100, 100);
bool b = p.inside(r);
bool b2 = p2.inside(r);
// Scalar
Scalar s(255, 255, 255);
Scalar s2(10, 100, 255);
Scalar ss = s.mul(s2);
// Rect
Size size = Size(100, 100);
Rect r1(0, 0, 100, 100);
Rect r2(p, size);
Rect r3(p, p2);
Size sos(10, 10);
Rect r4 = r1 & r2;
bool eq = (r1 == r2);
// RotatedRect
Point2f pf1 = Point2f(0, 0);
Point2f pf2 = Point2f(10, 0);
Point2f pf3 = Point2f(6, 10);
RotatedRect rr1 = RotatedRect(p, size, 45);
Point2i p_rr = rr1.center;
Size p_size = rr1.size;
float p_angle = rr1.angle;
Point2f pts[4];
rr1.points(pts);
// Matx
Matx33f m(1, 2, 3,
4, 5, 6,
7, 8, 9);
Matx23d m23d = Matx23d::zeros();
Matx16f m16f = Matx16f::ones();
Matx33f m33f = Matx33f::eye();
Matx33f randu33f = Matx33f::randu(0, 1);
double d23 = m23d(1, 2);
float f16 = m16f(0, 0);
Matx13f m13f = m33f.row(2);
Matx31f m31f = m33f.col(2);
waitKey(0);
return 0;
}
9. Helper Data Structures
cv::Rangecv::Ptrcv::InputArray/cv::OutputArray- Standard library:
std::vector,std::pair
10. Range
10.1 Range Construction
cv::Range range(start, end); // from start (inclusive) to end (exclusive)
10.2 Range Methods
range.size(); // end - start
range.empty(); // true if size == 0
Mat src_half_down = src(Range(src.rows/2, src.rows), Range(0, src.cols));
// Equivalent using Rect:
// Mat src_half_down2 = src(Rect(0, src.rows/2, src.cols, src.cols/2));
11. Ptr (Smart Pointer)
cv::Ptr is a smart pointer that automatically deletes the pointed object when no longer needed.
11.1 Ptr Construction
cv::Ptr<Matx33f> p(new cv::Matx33f); // allocate a new object
cv::Ptr<Matx33f> p = makePtr<cv::Matx33f>(); // same as above
11.2 Ptr Methods
p.empty(); // true if pointer is null or has been released
p.release(); // release the object (deletes it)
cv::Ptr<Matx33f> p(new cv::Matx33f);
bool b = p.empty(); // false
p.release();
b = p.empty(); // true
12. InputArray and OutputArray
These are wrapper types that can accept cv::Scalar, cv::Vec, cv::Matx, etc. InputArray is treated as read-only.
13. Vector
std::vector is a dynamic array that can hold any type, including Mat, and can be nested.
13.1 Vector Declaration
std::vector<Mat> myVector;
std::vector<std::vector<cv::Point>> contours; // nested
13.2 Vector Operations
myVector.push_back(src); // append at end
Mat tmp = myVector[0]; // index access
vector<Mat>::iterator it;
for (it = myVector.begin(); it != myVector.end(); ++it)
imshow("it", *it);
myVector.insert(myVector.begin() + i, src); // insert before element i
myVector.erase(myVector.begin() + i); // remove element i
reverse(myVector.begin(), myVector.end()); // reverse order
sort(myVector.begin(), myVector.end(), comp); // sort with custom comparator
bool Comp(const Mat &a, const Mat &b) {
return a.rows < b.rows; // sort by height
}
myVector.clear(); // remove all elements
14. Pair
std::pair holds two values (of possibly different types).
14.1 Pair Construction
pair<string, string> a; // default
pair<string, string> a("James", "Joy"); // assignment
vector<pair<Mat, string>> myPairs;
14.2 Accessing Pair Members
pair<string, string> a("Lily", "Poly");
string name = a.first; // "Lily"
name = a.second; // "Poly"
14.3 Complete Example
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
bool Comp(const Mat &a, const Mat &b) {
return a.rows < b.rows;
}
int main()
{
Mat src = imread("F:/OpenCV/images/002.jpg");
imshow("src", src);
// Range
Range range = Range(0, 4);
Mat src_half_down = src(Range(src.rows/2, src.rows), Range(0, src.cols));
// Ptr
Ptr<Matx33f> p(new Matx33f);
bool b = p.empty(); // false
p.release();
b = p.empty(); // true
// Vector
vector<Mat> myVector;
vector<vector<Point>> contours;
myVector.push_back(src);
myVector.push_back(src_half_down);
Mat tmp = myVector[0];
vector<Mat>::iterator it;
for (it = myVector.begin(); it != myVector.end(); ++it)
imshow("it", *it);
myVector.insert(myVector.begin() + 0, src_half_down);
reverse(myVector.begin(), myVector.end());
sort(myVector.begin(), myVector.end(), Comp);
myVector.erase(myVector.begin() + 1);
myVector.clear();
// Pair
pair<string, string> a("Lily", "Poly");
string name = a.first;
name = a.second;
waitKey(0);
return 0;
}
15. Large Data Structures: Mat and SparseMat
- Mat: dense array (every position has data)
- SparseMat: sparse array (only non-zero positions are stored)
16. Mat – The Most Common OpenCV Data Structure
Mat is an N-dimensional dense array. It not only represents images but can hold any data. It includes garbage collection (automatic memory management). Key properties:
- Type (e.g.,
CV_8UC3) - Number of channels
- Width, height
- Data pointer
- Stride (step)
16.1 Mat Construction
cv::Mat; // default (empty)
cv::Mat(cv::Size sz, int type); // create with size and type
cv::Mat(cv::Size sz, int type, const Scalar& s); // plus initial color
cv::Mat mat = imread("path/to/image.jpg"); // common way from file
cv::Mat(const Mat& mat); // copy constructor
cv::Mat(const CvMat* old, bool copyData = false); // from old C-style
cv::Mat(const IplImage* old, bool copyData = false); // from old IPL
// Special constructors:
cv::Mat::zeros(rows, cols, type); // all zeros
cv::Mat::ones(rows, cols, type); // all ones
cv::Mat::eye(rows, cols, type); // identity matrix (if rows==cols)
Note: For 8-bit images, 0 is black, 255 is white. For 32-bit float, 0 is black, 1 is white.
17. Iterating Over Mat (Image Traversal)
17.1 Using at() (safe access)
for (int i = 0; i < src.rows; ++i) {
for (int j = 0; j < src.cols; ++j) {
Vec3b &pixel = src.at<Vec3b>(i, j);
pixel[0] /= 2; // blue channel
pixel[1] /= 2; // green channel
pixel[2] /= 2; // red channel
}
}
17.2 Using Pointer (faster)
Mat outImage;
outImage.create(src.size(), src.type());
int nr = src.rows;
int nl = src.cols * src.channels(); // total number of elements per row
for (int k = 0; k < nr; ++k) {
uchar* outData = outImage.ptr<uchar>(k);
const uchar* inData = src.ptr<uchar>(k);
for (int i = 0; i < nl; ++i) {
outData[i] = inData[i] * 2;
}
}
17.3 Using Continuous Pointer (even faster)
If the image is continuous (rows are stored consecutively in memory), treat it as one long row.
Mat outImage;
outImage.create(src.size(), src.type());
int nr = src.rows;
int nc = src.cols;
if (src.isContinuous() && outImage.isContinuous()) {
nr = 1;
nc = nc * src.rows * src.channels();
}
for (int i = 0; i < nr; ++i) {
const uchar* inData = src.ptr<uchar>(i);
uchar* outData = outImage.ptr<uchar>(i);
for (int j = 0; j < nc; ++j) {
*outData++ = *inData++ * 2;
}
}
17.4 Using Iterators (convenient)
Mat outImage;
outImage.create(src.size(), src.type());
MatConstIterator_<Vec3b> it_in = src.begin<Vec3b>();
MatConstIterator_<Vec3b> itend_in = src.end<Vec3b>();
MatIterator_<Vec3b> it_out = outImage.begin<Vec3b>();
MatIterator_<Vec3b> itend_out = outImage.end<Vec3b>();
while (it_in != itend_in) {
(*it_out)[0] = (*it_in)[0] * 2;
(*it_out)[1] = (*it_in)[1] * 2;
(*it_out)[2] = (*it_in)[2] * 2;
++it_in;
++it_out;
}
17.5 Block Operations (rows, columns, ROI)
Mat matRow = src.row(0); // first row
Mat matCols = src.col(0); // first column
Mat matRowRange = src.rowRange(0, 10); // rows 0-9
Mat matSrcRange = src.colRange(0, 10); // columns 0-9
Mat matDiag = src.diag(); // diagonal (only if square)
Mat roi = src(Rect(0, 0, 10, 10)); // region of interest
18. Mat Functions
m1 = m0.clone(); // deep copy
m0.copyTo(m1); // same as clone
m0.copyTo(m1, mask); // copy with mask
m0.convertTo(m1, type, scale, offset); // conversion with scaling
Mat src32f;
src.convertTo(src32f, CV_32F, 1.0/255.0); // 8U -> 32F (0..255 to 0..1)
src32f.convertTo(src, CV_8U, 255.0); // 32F -> 8U (0..1 to 0..255)
m0.setTo(s, mask); // set elements to scalar s where mask is non-zero
19. SparseMat (Sparse Matrix)
19.1 SparseMat Construction
cv::SparseMat sm; // empty
cv::SparseMat sm(ndims, sizes, type); // e.g., 3 dimensions, sizes array, type
SparseMat sm(sm0); // copy from another SparseMat or Mat
19.2 Accessing Elements
// Using pointer
uchar* ptr = sm.ptr(i0, createMissing, hashval);
// Using ref (non-const reference)
sm.ref<float>(idx) += 1.0f; // increment value at index
// Using value (const)
float val = sm.value<float>(idx);
// Using find
float* valPtr = sm.find<float>(idx);
19.3 Iterating Over Non-Zeros
int size[] = {10, 10};
cv::SparseMat sm(2, size, CV_32F);
for (int i = 0; i < 10; ++i) {
int idx[2];
idx[0] = size[0] * rand();
idx[1] = size[1] * rand();
sm.ref<float>(idx) += 1.0f;
}
cv::SparseMatConstIterator_<float> it = sm.begin<float>();
cv::SparseMatConstIterator_<float> it_end = sm.end<float>();
for (; it != it_end; ++it) {
const cv::SparseMat::Node* node = it.node();
printf(" (%3d,%3d) %f\n", node->idx[0], node->idx[1], *it);
}
20. Common Mat Operations
20.1 cv::abs() – Absolute value
cv::MatExpr abs(cv::InputArray src);
cv::MatExpr abs(const cv::MatExpr& src);
20.2 cv::absdiff() – Absolute difference
void cv::absdiff(InputArray src1, InputArray src2, OutputArray dst);
// dst = saturate( |src1 - src2| )
20.3 cv::add() – Addition
void cv::add(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray(), int dtype = -1);
// dst = saturate(src1 + src2)
20.4 cv::addWeighted() – Weighted addition
void cv::addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1);
// dst = saturate(src1 * alpha + src2 * beta + gamma)
20.5 cv::bitwise_and() – Bitwise AND
void cv::bitwise_and(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray());
// dst = src1 & src2
20.6 cv::bitwise_or() – Bitwise OR
void cv::bitwise_or(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray());
// dst = src1 | src2
20.7 cv::bitwise_xor() – Bitwise XOR
void cv::bitwise_xor(InputArray src1, InputArray src2, OutputArray dst,
InputArray mask = noArray());
// dst = src1 ^ src2
20.8 cv::bitwise_not() – Bitwise NOT
cv::bitwise_not(star, temp); // invert: black becomes white, etc.
20.9 cv::compare() – Comparison
void cv::compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop);
// Flags: CMP_EQ, CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE
20.10 cv::cartToPolar() – Cartesian to Polar
void cv::cartToPolar(InputArray x, InputArray y, OutputArray magnitude,
OutputArray angle, bool angleInDegrees = false);
20.11 cv::convertScaleAbs() – Scale and take absolute value
void cv::convertScaleAbs(InputArray src, OutputArray dst,
double alpha = 1.0, double beta = 0.0);
// dst = saturate | src * alpha + beta |
20.12 cv::countNonZero() – Count non-zero elements
int cv::countNonZero(InputArray mtx);
20.13 cv::cvtColor() – Color covnersion
void cv::cvtColor(InputArray src, OutputArray dst, int code, int dstCn = 0);
// code: e.g., COLOR_BGR2GRAY, COLOR_BGR2RGB
20.14 cv::flip() – Flip image
void cv::flip(InputArray src, OutputArray dst, int flipCode = 0);
// flipCode > 0: horizontal flip (y-axis)
// flipCode = 0: vertical flip (x-axis)
// flipCode < 0: both
20.15 cv::LUT() – Lookup table (fastest)
void cv::LUT(InputArray src, InputArray lut, OutputArray dst);
// dst = lut[src]
Lookup table operations are the fastest way to apply transformations.