OpenCv004-高效遍历图像

今天学习所谓的高效连续遍历图像,搞笑了一下 哈哈 按照课本的程序敲代码,我发现并没有高效啊?基本没有什么变化啊?问题我写在程序的注释里面了,希望前辈可以给出指点。 

#include <opencv.hpp>
#include <iostream>
#include <windows.h>
using namespace cv;
using namespace std;
/*C::Mat的一个成员函数 isContinuous 是否进行填补  如果没有进行填补  可以将图像看成一个一维数组 
  我们也可以使用reshape这个方法来重置矩阵的维度;
  if(image.isContinuous())
  {
	image.reshape(1,image.rows * image.cols)  //其中 参数1  代表通道数 参数二代表行数
  }
  int nl = image.rows;
  int nc = image.cols * image.channels();

  reshape 不需要内存拷贝或者重新分配就能改变矩阵的维度,两个参数分别为新的通道数和新的hangshu
*/
void colorReduce(Mat & image, int div )
{
	int nl = image.rows;
	int nc = image.cols * image.channels();
	if (image.isContinuous())
	{
		nc = nc * nl;
		nl = 1;
	}
	for (int j = 0; j < nl; j++)
	{  
		/*uchar * data = image.ptr<uchar>(j);  是为了获取j行的指针,
		  在cv::Mat中,图像数据以unsigned  char 的形式保存在一块内存当中。这块内存的首地址可以通过mat的成员变量data找到   data是一个unsigned char类型的指针  所以循环可以这样开始: uchar * data = image.data  
	  这个指针还有一个用处 就是可以检测是否成功读取了一张图片  如果顺利读取了  指针的值不为0 (NULL) 否则指针的值为NULL  这样就可以用if语句来判断是否成功读取了图片  从当前行到下一行可以采取 :data+ = image.step*/

		uchar * data = image.ptr<uchar>(j);
		for (int i = 0; i < nc; i++)
		{
			data[i] = data[i] / div *div + div / 2;
		}
	}
}
int main()
{
	Mat image;
	image = imread("C:\\Users\\Administrator\\Pictures\\Test1.jpg",IMREAD_GRAYSCALE);
	/*一个非常奇怪的问题,也不知道咋回事  我改变图片的通道,就是换成灰色图像 时间也是  16就没有变过 
	这是咋回事呢 遍历的像素点少了 时间不应该短吗*/
	DWORD Start_time = GetTickCount();
	colorReduce(image,64);
	DWORD End_time = GetTickCount();
	cout << "执行时间:" <<  End_time - Start_time << endl;
	namedWindow("高效遍历");
	imshow("高效遍历", image);
	waitKey(0);
	return 0;

}
#include<opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
	Mat image;
	image = imread("C:\\Users\\Administrator\\Pictures\\Test2.jpg", IMREAD_UNCHANGED);
	int nl = image.rows;
	int nc = image.cols;
	int k = 0;
	k = image.elemSize();
	cout << "行宽:" << k << endl;
	cout << nl << '\t' << nc << endl;
	cout << "地址测试" << endl;
	//一开始按照课本上写的 image.at(1,1)  死活编译不成功,后来加上了类型声明就对了 <uchar> 输出乱码 
	//再后来 百度 加上了强制类型转换。
	cout << int(image.at<uchar>(0, 4) )<< endl;

	/*按照测试的结果来看,一个768&1366的图片  一共有768行  1366列   其中每行包括1366个像素  每个像素由RGB三个分量合并而成   
	  所以一行应该有  1366 * 3个 usigned char 类型的数据。经测试  准确无误 ,不巧的是测试过程中发现 执行串口 显示不了这么多的数据
	  窗口的属性中 默认显示 300行 每行80个  这样多余的就被覆盖了,自己修改一下窗体的属性即可。
	  */
	for (int j = 0; j < 1; j++)
	{
		for (int i = 0; i < nc*image.channels(); i++)
		{
			cout << int(image.at<uchar>(j, i)) <<
				'\t'  ;
			k++;
		}
		cout <<"一行有" << endl;
		cout << k;
	}
	return 0;
}
/* image.at<uchar>(i, j) 这样代表 这个坐标位置下的像素 ,对于灰色图像只有一个 
   对于彩色图像 举个例子吧  768 *1366  这个 i 依旧表示第几行  j的取值范围是0-1366 *3 -1  
   那么此时上述语句就代表 是一个像素点的某一分量。  

    &image.at<uchar>(i, j)就是得到这个数据的地址 ,通常我们使用这个方法,但是书本上还介绍了另一种 这里了解一下吧;
	
	data = image.data + i*image,step +j*image.elemSzie
	解释一下  image.data 代表图像第一个元素的指针地址  i代表行数  step代表图像的行宽  奶奶的 行宽什么意思呢  意思就是一行有多少个数据
	比如彩色图形 766 *1366  一行就是有 1366 * 3 数据 行宽就是4098  
	elemSize代表了 一个像素点由几个分量组成 比如彩色就是三个,这样解释应该比较明白了。
*/

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值