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
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
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:
// Load color image (BGR by default)
Mat bgr = imread ( "image.jpg" );
// Access BGR values
Vec3b pixel = bgr . at < Vec3b > (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 for conversion details.
Pixel Access
Single Pixel
// Grayscale image
uchar intensity = grayImg . at < uchar > (y, x);
// Color image
Vec3b color = colorImg . at < Vec3b > (y, x);
color [ 0 ] = 255 ; // Modify blue channel
colorImg . at < Vec3b > (y, x) = color;
Efficient Row Access
for ( int i = 0 ; i < img . rows ; i ++ ) {
uchar * row = img . ptr < uchar > (i);
for ( int j = 0 ; j < img . cols ; j ++ ) {
row [j] = /* process pixel */ ;
}
}
Multi-Channel Access
for ( int i = 0 ; i < img . rows ; i ++ ) {
Vec3b * row = img . ptr < Vec3b > (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
// 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
// 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
// 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
// Split into channels
vector < Mat > channels;
split (img, channels); // channels[0]=B, channels[1]=G, channels[2]=R
// Merge channels
Mat merged;
merge (channels, merged);
// 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
// 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
// Save image
imwrite ( "output.jpg" , img);
// Save with parameters
vector < int > params = {IMWRITE_JPEG_QUALITY, 95 };
imwrite ( "output.jpg" , img, params);
Common Patterns
Convert to Grayscale
Mat gray;
cvtColor (img, gray, COLOR_BGR2GRAY);
Resize Image
Mat resized;
resize (img, resized, Size ( 320 , 240 ));
// Scale by factor
resize (img, resized, Size (), 0.5 , 0.5 );
Crop Image
Rect cropRegion ( x , y , width , height );
Mat cropped = img (cropRegion). clone ();
Use Pointer Access Prefer ptr<T>() over at<T>() for pixel-level operations
Check Continuity Continuous matrices enable faster processing
Avoid Copies Use references and ROI instead of cloning
Batch Operations Use OpenCV functions instead of pixel loops
See Also