Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

OpenCV Data Structures

Tech 1

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::Range
  • cv::Ptr
  • cv::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.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.