opencv之cv::image遍历
访问cv::image元素的方法:
- 使用at成员函数
- 使用ptr指针访问
- 使用迭代器iterator
方式1: at(i, j)访问
这种方式在Debug模式下的访问速度是最慢的,但是在Release模式下的访问速度也是相当快的,和其他方式相近。
- 单通道遍历(灰度图像)
cv::Mat image(100 , 100 , CV_8UC1);
int rows = image.rows;
int cols = image.cols;
for (int i=0; i<rows ; i++)
{
for (int j=0; j<cols ; j++)
{
image.at<uchar>(i,j) = 20;
}
}
- 多通道遍历(彩色图像)
cv::Mat image(100 , 100 , CV_8UC3);
int rows = image.rows;
int cols = image.cols;
for (int i=0; i<rows ; i++)
{
for (int j=0; j<cols ; j++)
{
image.at<cv::Vec3b>(i,j)[0]= 20; // B 通道
image.at<cv::Vec3b>(i,j)[1]= 20; // G 通道
image.at<cv::Vec3b>(i,j)[2]= 20; // R 通道
}
}
注:灰度图像元素类型为<uchar>
, 彩色图像元素类型为<cv::Vec3b>
注:image.at<>(y, x)
注:这种方式会检查访问是否会溢出。
方式2: ptr(i) [j] 方式
这种方式是最有效的方式, 可以使用iscontinue()
函数来提高遍历的速度。
cv::image image = cv::imread("xx.png", cv::IMREAD_COLOR);
int channels = image.channels;
int rows = image.rows;
int cols = image.cols * channels;
if (image.isContinuous())
{
cols *= rows;
rows = 1;
}
int i, j;
uchar* p;
for (i = 0; i < rows; ++i)
{
p = image.ptr<uchar>(i);
for (j = 0; j < cols; ++j)
{
std::cout << int(p[j]) << " ";
}
}
注: image.ptr<>(i)返回第i行首元素的指针。
方式3:iterator方式
- 单通道遍历(灰度图像)
cv::Mat image(100 , 100 , CV_8UC1);
for (auto it = image.begin<uchar>(); it != image.end<uchar>(); ++it)
{
std::cout << int((*it)) << " ";
}
- 多通道遍历(彩色图像)
cv::Mat image(100 , 100 , CV_8UC3);
for (auto it = image.begin<cv::Vec3b>(); it != image.end<cv::Vec3b>(); ++it)
{
std::cout << int((*it)[0]) << " " << int((*it)[1]) << " " << int((*it)[2]) << std::endl;
}