opencv的at,iterator,z指针的用法


对于单通道图像,其元素类型一般为 对于单通道图像,其元素类型一般为 8U (即 8位无符号整数),当然也可以 是 16S 、32F32F 等;这些类型可以直接用 ucharucharucharuchar 、short short short、floatfloat float等 C/C++语言中的基本 数据类型表达。

 如果多通道图像,RGB 彩色图像,需要用三个通道来表示。在这种情况下,如果依然将图像视作一个二维矩阵,那么维矩阵的元素不再是基本数据类型。

OpenCV中有模板类 Vec,可以表示一个向量。 OpenCV 中使用 VecVec 类预定义了一 些小向量,可以用于矩阵元素的表达。

typedef Vec<uchar, 2> Vec2b;

typedef Vec<uchar,3> Vec3b;

typedef Vec<uchar, 4> Vec4b;

typedef Vec<short, 2> Vec2s;

typedef Vec<short,3> Vec3s;

typedef Vec<short, 4> Vec4s;

typedef Vec<int, 2> Vec2i;

typedef Vec<int,3> Vec3i;

typedef Vec<int, 4> Vec4i;

typedef Vec<float, 2> Vec2f;

typedef Vec<float,3> Vec3f;

typedef Vec<float, 4> Vec4f;

typedef Vec<float, 6> Vec6f;

typedef Vec<double, 2> Vec2d;

typedef Vec<double,3> Vec3d;

typedef Vec<double, 4> Vec4d;

typedef Vec<double, 6> Vec6d;

例如 8U 类型的 RGB 彩色图像可以使用  Vec3b ,3通道 float类型的矩阵可以使用 Vec3f 。

对于 VecVec 对象,可以使用 [] 符号如操作数组般读写其元素,如:

Vec3b color;  Vec3b color; // 用 color变量描述一种 RGB 颜色

color [0]=255;  //B分量

color【1】=0; //G

color【1】=0;//R

一: at用法

函数at()来实现读取矩阵中的某个像素,或者对某个像素进行赋值操作。下面两行的代码演示了at()函数的实用方法

uchar value = gray.at<uchar>(i,j); //读出第i行第j列像素值

grayim.at<uchar>(i,j)=128; //将读出第i行第j列像素值设置成128

以下函数对单通道的grayim 和3通道的colorim,然后对两个图像的所有像素值赋值。

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include   <iostream> 
using   namespace   std;
using namespace cv;
int main(int argc, char* argv[])  //等于int main(int argc, char** argv)

{
	Mat grayim(600, 800, CV_8UC1);
	Mat colorim(600, 800, CV_8UC3);
	//遍历所有的像素值,并设置像素值

	  for (int i = 0; i < grayim.rows; ++i)
	  for (int j = 0; j < grayim.cols; ++j)
		grayim.at<uchar>(i, j) = (i + j) % 255;

	  //遍历所有的像素值,并设置像素值
	  for (int i = 0; i < colorim.rows;++i)
	  for (int j = 0; j < colorim.cols; ++j)
	  {
		  Vec3b pixel;
		  pixel[0] = i % 255;
		  pixel[1] = j % 255;
		  pixel[2] = 0;
		  colorim.at<Vec3b>(i, j) = pixel;
	  }

	  //显示结果
	  imshow("grayim", grayim);
	  imshow("colorim", colorim);
	  waitKey(0);
	  return 0;
}

二: iterator用法

如果你熟悉 C++C++C++的 STLSTL 库,那一定了解迭代器(iterator )的使用。迭代器可 以方便地遍历所有元素。 Mat也增加了迭代器的支持,以便于矩阵元素遍历。 下面的例程功能跟上一节类似,但是由于使用了迭代器而不是实用行数和列数来遍历,所以这儿没有了i 和J变量,图像的像素值设置成一个随机数。

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include   <iostream> 
using   namespace   std;
using namespace cv;
int main(int argc, char** argv)

{
	Mat grayim(600, 800, CV_8UC1);
	Mat colorim(600, 800, CV_8UC3);
	//遍历所有的像素值,并设置像素值
	MatIterator_<uchar> grayit, grayend;
	for (grayit = grayim.begin<uchar>(), grayend = grayim.end<uchar>(); grayit != grayend; ++grayit)
		*grayit = rand() % 255;
	//遍历所有的像素值,并设置像素值
	MatIterator_<Vec3b> colorit,colorend;
	for (colorit = colorim.begin<Vec3b>(), colorend = colorim.end<Vec3b>(); colorit != colorend; ++colorit)
	{
		
		(*colorit)[0] = rand() % 255;  //Blue
		(*colorit)[1] = rand() % 255;   //Green
		(*colorit)[2] = rand() % 255;   //red
	
	}

	//显示结果
	imshow("grayim", grayim);
	imshow("colorim", colorim);
	waitKey(0);
	return 0;
}


三: 指针的用法

使用 IplImage 结构的时候,我们会经常使用数据指针来直接操作像素。通过 指针操作来访问像素是非常高效的,但你务必十分地小心。  C/C++中的指针操中的指针操 作是不进行类型以及越界检查的,作是不进行类型以及越界检查的,如果指针访问出错,程序运时有候可能看上去一切正常,但是有时候突然弹出“段错误”(segment fault)

当程序规模较大,且逻辑复杂时查找指针错误十分困难。 对于不熟悉指针的编程者来说,指针就如同噩梦。 如果你对指针使用没有自信,则不建议直接通过指针操作来访问像素。虽然 at()函数和迭代器也不能保证对像素访问进行充分 的检查;但是总比指针操作要可靠一些。

如果你非常注重程序的运行速度,那么遍历像素时建议使用指针。

下面的 例程 演示如何 演示如何 使用指针来遍历图像中的所有素。此例程实现操作跟第 使用指针来遍历图像中的所有素。

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include   <iostream> 
using   namespace   std;
using namespace cv;
int main(int argc, char** argv)

{
	Mat grayim(600, 800, CV_8UC1);
	Mat colorim(600, 800, CV_8UC3);

	//遍历所有的像素值,并设置像素值
	for (int i = 0; i < grayim.rows; ++i)
	{
		//获取滴i行首像素指针
		uchar *p = grayim.ptr<uchar>(i);

		//对滴i 行的每个像素操作

		for (int j = 0; j < colorim.cols; ++j)
		{
			p[j] = (i + j) % 255;
		}

	}
		//遍历所有的像素值,并设置像素值
		for (int i = 0; i < colorim.rows; ++i)
		{
			//获取滴i行首像素指针
			Vec3b *p = colorim.ptr<Vec3b>(i);

			//对滴i 行的每个像素操作

			for (int j = 0; j < colorim.cols; ++j)
			{
				p[j][0] = i % 255;
				p[j][1] = j % 255;
				p[j][2] = 0;
			}
		}
		//显示结果
		imshow("grayim", grayim);
		imshow("colorim", colorim);
		waitKey(0);
		return 0;
	}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值