【图像处理】OpenCV中操作像素的三种方式。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/deliberate_cha/article/details/102779397

为了加深对各个像素点的理解,以及增强对内存空间操作的使用技巧,举例两个Mat类对象的卷积和。用到的方法有三种:
1.指针访问
2.动态地址计算
3.迭代器的使用

算法的基本思想是,Mat类变量中的矩阵f(x1,y1)(需要求卷积的矩阵)与Mat类变量中的矩阵g(x2,y2)(核矩阵),各相同位置相乘求和。本算法是求卷积中必不可少的一部分。

#include<opencv2\core\core.hpp>
#include<iostream>

using namespace cv;
using namespace std;

//四种算法

//第一种 利用.ptr 和 []
double rectReduce1(Mat &mat1,Mat &mat2)
{
	int nl = mat1.rows;
	int nc = mat2.cols;
	double sum = 0;
	for (int i = 0; i < nl; i++)
	{
		//获取每一行的首地址
		double* data1 = mat1.ptr<double>(i);
		double* data2 = mat2.ptr<double>(i);
		for (int j = 0; j < nc; j++)
		{
			//利用每一行的首地址,操作矩阵中每个元素
			sum = sum + data1[j] * data2[j];
		}
	}
	return sum;
}

//第二种方法 利用.ptr 和 *++
double rectReduce2(Mat &mat1, Mat &mat2)
{
	int nl = mat1.rows;
	int nc = mat2.cols;
	double sum = 0;
	
	for (int i = 0; i < nl; i++)
	{
		//与上面同理
		double* data1 = mat1.ptr<double>(i);
		double* data2 = mat2.ptr<double>(i);
		for (int j = 0; j < nc; j++)
		{
			//这里没用数组的形式,而使用的操作地址的形式。
			sum = sum + *data1*(*data2);
			data1++;
			data2++;
		}
	}

	return sum;
}

//第三种 利用动态地址计算配合at
double rectReduce3(Mat &mat1, Mat &mat2)
{
	int nl = mat1.rows;
	int nc = mat2.cols;
	double sum = 0;


	for (int i = 0; i < nl; i++)
	{
		for (int j = 0; j < nc; j++)
		{
			//动态地址操作,因为矩阵是double类型的单通道矩阵,所以用 Mat.at<double>(i,j)
			//若矩阵式uchar三通道类型 ,则使用Mat.at<Vec3b>(i,j)[x].   (i,j)元素的第【x】通道元素
			sum = sum + mat1.at<double>(i, j)*mat2.at<double>(i, j);
		}
	}

	return sum;
}

//第四种 迭代器iterate以及位运算
double rectReduce4(Mat &mat1, Mat &mat2)
{
	double sum = 0;
	//获取迭代器
	Mat_<double>::iterator start1 = mat1.begin<double>();//迭代器开始标志
	Mat_<double>::iterator end1 = mat1.end<double>();//迭代器结束标志
	Mat_<double>::iterator start2 = mat2.begin<double>();
	Mat_<double>::iterator end2 = mat2.end<double>();

	for (; start1 != end1; ++start1,++start2)//两个迭代器同时运行
	{
		sum = sum + *start2*(*start1);
	}

	return sum;
}



void main()
{
	Mat f = (Mat_<double>(3, 3) << 49, 53, 68, 50, 50, 58, 50, 50, 52);
	Mat g = (Mat_<double>(3, 3) << 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.1, 0.1);
	
	cout << "第一种方法:"<<  rectReduce1(f, g) << endl;
	cout << "第二种方法:" << rectReduce2(f, g) << endl;
	cout << "第三种方法:" << rectReduce3(f, g) << endl;
	cout << "第四种方法:" << rectReduce4(f, g) << endl;
}

输出结果都应为53.

猜你喜欢

转载自blog.csdn.net/deliberate_cha/article/details/102779397