圖像處理通常是對圖像像素進行算法分析,所以瞭解像素的存儲方式是尤爲重要的。
(1)、圖像在內存中的存儲方式
圖像矩陣的大小取決於所用的顏色模型(或者說通道數),灰度圖像矩陣每行每列對應一個元素也就是灰度值,而彩色圖像矩陣每行每列對應BGR三種元素的值。
(2)、訪問圖像像素的方法
a. 動態地址計算訪問
eg:
///動態地址訪問
Mat img = imread("1.jpg");
imshow("src", img);
Mat dst = img.clone();
int rowNumber = img.rows; //獲取行數
int colNumber = img.cols; //獲取列數
for(int i = 0; i<rowNumber; i++)
{
for(int j = 0; j<colNumber; j++)
{
dst.at<Vec3b>(i, j)[0] = 255; //藍色通道
dst.at<Vec3b>(i, j)[1] = 0; //綠色通道
dst.at<Vec3b>(i, j)[2] = 0; //紅色通道
}
}
imshow("dst", dst);
waitKey(0);
成員函數at用來讀取像素,<Vec3b>表示一個uchar[3]類型的數組,如果是灰度圖像用at<uchar>(i,j)=255的形式訪問。
b. 指針訪問
eg:
///指針訪問
Mat img = imread("1.jpg");
imshow("src", img);
Mat dst = img.clone();
int rowNumber = img.rows; //獲取行數
int colNumber = img.cols * img.channels(); //獲取每一行的元素
for(int i = 0; i<rowNumber; i++)
{
uchar* data = dst.ptr<uchar>(i); //獲取每一行首地址
for(int j = 0; j<colNumber; j++)
{
switch(j % 3)
{
case 0: //藍色通道
data[j] = 255;
break;
case 1: //綠色通道
data[j] = 0;
break;
case 2: //紅色通道
data[j] = 255;
break;
}
}
}
imshow("dst", dst);
waitKey(0);
Mat類提供了ptr函數可以得到圖像任意行的首地址
eg:
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
void main()
{
///減色算法
//Mat img = imread("1.jpg");
//imshow("src", img);
//Mat dst = img.clone();
//int rowNumber = img.rows; //獲取行數
//int colNumber = img.cols * img.channels(); //獲取每一行的元素
//for(int i = 0; i<rowNumber; i++)
//{
// uchar* data = dst.ptr<uchar>(i); //獲取每一行首地址
// for(int j = 0; j<colNumber; j++)
// {
// switch(j % 3)
// {
// case 0: //藍色通道
// data[j] = 64 * 64 + 64/2; //一個減色算法
// break;
// case 1: //綠色通道
// data[j] = 64 * 64 + 64/2;
// break;
// case 2: //紅色通道
// data[j] = 64 * 64 + 64/2;
// break;
// }
// }
//}
//imshow("dst", dst);
//waitKey(0);
///雪花效果
Mat img = imread("1.jpg");
imshow("src", img);
Mat dst = img.clone();
int rowNumber = img.rows; //獲取行數
int colNumber = img.cols; //獲取列數
int i, j;
for(int k = 0; k< 2000; k++)
{
i = rand() % rowNumber;
j = rand() % colNumber;
dst.at<Vec3b>(i, j)[0] = 255; //藍色通道
dst.at<Vec3b>(i, j)[1] = 255; //綠色通道
dst.at<Vec3b>(i, j)[2] = 255; //紅色通道
}
imshow("dst", dst);
waitKey(0);
}