opencv之Mat各种操作

1 Mat 相加: 红色和绿色相加, 结果是黄色。

Mat red(SIZE, SIZE, CV_8UC3, Scalar(0, 0, 255));
	Mat blue(SIZE, SIZE, CV_8UC3, Scalar(0, 255, 0));
	Mat img3 = red + blue;

2 减: 黄色减绿色是红色。

Mat yellow(SIZE, SIZE, CV_8UC3, Scalar(0, 255, 255));
	Mat blue(SIZE, SIZE, CV_8UC3, Scalar(0, 255, 0));
	Mat img3 = yellow - blue;

3 裁剪一部分区域:

image = imread("a.jpg", IMREAD_UNCHANGED);
	if (!image.data) {
		printf("No image data \n");
		return -1;
	}
Mat imageD(image, Rect(10, 10, 300, 300)); // a rectangle

4 先初始化再赋值:

Size size(200, 100);
Mat img3(size, CV_8UC3);
img3 = Scalar(0, 255, 255);

5 使用外部像素数据构造Mat

以下构造一个4X4的纯红色图片.

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4
/**
 * https://docs.opencv.org/4.6.0/df/d61/tutorial_random_generator_and_text.html
 * https://www.bogotobogo.com/OpenCV/opencv_3_tutorial_creating_mat_objects.php
 * https://docs.opencv.org/4.x/examples.html
 *
 * https://docs.opencv.org/3.4/d1/d10/classcv_1_1MatExpr.html
 * https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html
 *
 * cmake  .
 * make
 * ./a
 */

int main(int argc, char **argv) {
	Mat red(SIZE, SIZE, CV_8UC3);
	unsigned char c[] = { 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
			0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0,
			0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255 };
	red.data = c;
/**
或者
 unsigned char c[] = { 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
				              102, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
							  0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
							  0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255};
	Mat red(SIZE, SIZE, CV_8UC3,c);
	*/
	imwrite("out.jpg", red);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", red);
	int k = waitKey(0);
	return 0;
}

6 Mat对象之 == 操作符判断2个Mat对象数据是否一样。

以下是一个黄色图片减去一个红色图片应该是一个绿色图片,然后拿这个结果和一个绿色图片,对比是否一致。

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4
/**
 * https://docs.opencv.org/4.6.0/df/d61/tutorial_random_generator_and_text.html
 * https://www.bogotobogo.com/OpenCV/opencv_3_tutorial_creating_mat_objects.php
 * https://docs.opencv.org/4.x/examples.html
 *
 * https://docs.opencv.org/3.4/d1/d10/classcv_1_1MatExpr.html
 * https://docs.opencv.org/4.x/d3/d63/classcv_1_1Mat.html
 *
 * cmake  .
 * make
 * ./a
 */

int main(int argc, char **argv) {
	Size size(SIZE, SIZE);
	Mat yellow(size, CV_8UC3, Scalar(0, 255, 255));
	Mat red(size, CV_8UC3, Scalar(0, 0, 255));
	Mat result = yellow - red;
	Mat blue(size, CV_8UC3, Scalar(0, 255, 0));
	Mat isequal = result == blue;
	cout << isequal << endl;
	assert(isequal.at<unsigned char>(0, 0) == 255);
	imwrite("out.jpg", blue);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", blue);
	int k = waitKey(0);
	return 0;
}


7 Mat 之 行范围操作。

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 200

int main(int argc, char **argv) {
	Size size(SIZE, SIZE);
	Mat yellow(size, CV_8UC3, Scalar(0, 255, 255));
	yellow.rowRange(0, 100) = Scalar(0, 0, 255);
	imwrite("out.jpg", yellow);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", yellow);
	int k = waitKey(0);
	return 0;
}


Mat 列范围操作

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 200

int main(int argc, char **argv) {
	Size size(SIZE, SIZE);
	Mat yellow(size, CV_8UC3, Scalar(0, 255, 255));
//	yellow.colRange(0, 100) = Scalar(0, 0, 255);
	yellow.rowRange(0, 100) = Scalar(0, 0, 255);
	imwrite("out.jpg", yellow);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", yellow);
	int k = waitKey(0);
	return 0;
}


8 Mat 获取对角线元素

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 200

int main(int argc, char **argv) {
	Mat m = (Mat_<int>(3, 3) << 1, 2, 3,
			                    4, 5, 6,
								7, 8, 9);
	Mat d0 = m.diag(0);
	cout << d0 << endl;
	Mat d1 = m.diag(1);
	cout << d1 << endl;
	Mat d2 = m.diag(2);
	cout << d2 << endl;
	Mat d3 = m.diag(-1);
	cout << d3 << endl;
	return 0;
}


9 生成对角线矩阵:

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 200

int main(int argc, char **argv) {
	Mat m= Mat::eye(4,4, CV_8UC1)*5;
	cout << m  << endl;
	return 0;
}


10 Scalar::all 函数

Scalar::all(20) 表示每个元素都设置为20,
不然如果是3通道的话, 就得这样写: Scalar(20,20,20)。

 #include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	Mat yellow(SIZE,SIZE, CV_8UC3, Scalar::all(20));
	cout<<yellow<<endl;
	cout << yellow.elemSize() << endl;
	return 0;
}

11 Mat.elemSize()函数

返回矩阵的每一个元素占有多少个字节。
比如type是 CV_8UC3,表示每一个元素有3个通道,每一个通道是8位的 unsigned char即一个byte,,3个通道就是 3个byte,所以下面代码是正确的:

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	Mat yellow(SIZE, SIZE, CV_8UC3, Scalar::all(20));
	cout << yellow.elemSize() << endl;
	assert(yellow.elemSize() == 3);
	return 0;
}


12 Mat.elemSize1()函数

返回通道占用的字节数。

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	{
		Mat mat1(SIZE, SIZE, CV_16UC1, Scalar::all(20));
		assert(mat1.elemSize1() == 2);
	}
	{
		Mat mat1(SIZE, SIZE, CV_16UC4, Scalar::all(20));
		assert(mat1.elemSize1() == 2);
	}
	{
		Mat mat1(SIZE, SIZE, CV_8UC1, Scalar::all(20));
		assert(mat1.elemSize1() == 1);
	}
	{
		Mat mat1(SIZE, SIZE, CV_8UC3, Scalar::all(20));
		assert(mat1.elemSize1() == 1);
	}

	return 0;
}


12 depth()函数

返回矩阵的数据的类型。

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	{
		Mat mat1(SIZE, SIZE, CV_8UC1, Scalar::all(20));
		assert(mat1.depth() == 0);
	}
	{
		Mat mat1(SIZE, SIZE, CV_8SC1, Scalar::all(20));
		assert(mat1.depth() == 1);
	}
	{
		Mat mat1(SIZE, SIZE, CV_16UC1, Scalar::all(20));
		assert(mat1.depth() == 2);
	}
	{
		Mat mat1(SIZE, SIZE, CV_16SC1, Scalar::all(20));
		assert(mat1.depth() == 3);
	}
	return 0;
}


13 channels()返回通道数

也是类型常量最后一个数字.

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	{
		Mat mat1(SIZE, SIZE, CV_8UC3, Scalar::all(20));
		assert(mat1.channels() == 3);
	}
	{
		Mat mat1(SIZE, SIZE, CV_8UC1, Scalar::all(20));
		assert(mat1.channels() == 1);
	}
	{
		Mat mat1(SIZE, SIZE, CV_8SC1, Scalar::all(20));
		assert(mat1.channels() == 1);
	}
	{
		Mat mat1(SIZE, SIZE, CV_16UC1, Scalar::all(20));
		assert(mat1.channels() == 1);
	}
	{
		Mat mat1(SIZE, SIZE, CV_16SC1, Scalar::all(20));
		assert(mat1.channels() == 1);
	}
	{
		Mat mat1(SIZE, SIZE, CV_16SC4, Scalar::all(20));
		assert(mat1.channels() == 4);
	}
	return 0;
}


14 total()函数:

返回数组元素的个数,也就是行乘以列。对图片来说,就是有多少个像素。

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	{
		Mat mat1(4, 4, CV_8UC3, Scalar::all(20));
		assert(mat1.total() == 16);
	}
	{
		Mat mat1(100, 20, CV_8UC3, Scalar::all(20));
		assert(mat1.total() == 2000);
	}
	return 0;
}


15 ptr(int row)

返回一个指向第几行开头的数据的指针,指针的类型就是数据的类型。
以下返回的是指向第二行开头的指针
指针的第一个数据是4,第二个是5.

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 200

int main(int argc, char **argv) {
	Mat m = (Mat_<unsigned char>(3, 3) << 1, 2, 3,
			                              4, 5, 6,
										  7, 8, 9);
	unsigned char *row1 = m.ptr(1);
	assert(*row1 == 4);
	assert(*(row1 + 1) == 5);
	assert(*(row1 + 2) == 6);
	return 0;
}


16 ptr(int row, int col);

返回指向第几行第几列的一个指针,指针的类型是数据的类型。

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 200

int main(int argc, char **argv) {
	Mat m = (Mat_<unsigned char>(4, 4) << 1, 2, 3,4,
			                              5, 6,7, 8,
										  9,10,11,12,
										  13,14,15,16);
	unsigned char *row1 = m.ptr(1,1);
	assert(*row1 == 6);
	assert(*(row1 + 1) == 7);
	assert(*(row1 + 2) == 8);
	return 0;
}


17 at(row,col) :获取或者设置某一个点的数据

以下使用at 来生成一张灰度图.

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 100

int main(int argc, char **argv) {
	Mat red = Mat::zeros( SIZE, SIZE, CV_8UC3);
	for (int i = 0; i < SIZE; i++) {
		for (int j = 0; j < SIZE * red.channels(); j++) {
			red.at<uchar>(i, j) = 100;
		}
	}
	imwrite("out.jpg", red);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", red);
	int k = waitKey(0);
	return 0;
}

下面是另外一个示例:

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4

int main(int argc, char **argv) {
	Mat red(SIZE, SIZE, CV_8UC3);
	unsigned char c[] = { 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
			              102, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
						  0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
						  0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255};
	red.data = c;
	assert((int) red.at<uchar>(0)==0);
	assert((int) red.at<uchar>(12)==102);
	imwrite("out.jpg", red);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", red);
	int k = waitKey(0);
	return 0;
}

18 直接获取一个图片某一点的GBR值。

通过 Pixel *dd = red.ptr(1,1); 获取指向第二行第二列的指针, 然后就可以得到GBR的值.

#include <stdio.h>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
#define SIZE 4
typedef cv::Point3_<uchar> Pixel;

int main(int argc, char **argv) {
	Mat red(SIZE, SIZE, CV_8UC3);
	unsigned char c[] = { 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255,
			              0, 103,255, 0, 10, 210, 0, 0, 245, 0, 0, 255,
						  0, 0, 255,  0, 0, 255, 0, 0,255,  0, 0, 255,
						  0,  0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 255 };

	red.data = c;
	{
		Pixel *dd = red.ptr<Pixel>(1,1);
		assert((int)dd->x == 0);
		assert((int)dd->y == 10);
		assert((int)dd->z == 210);

	dd++;

	assert((int)dd->x == 0);
	assert((int)dd->y == 0);
	assert((int)dd->z == 245);
	}
	imwrite("out.jpg", red);
	namedWindow("opencv", WINDOW_FREERATIO);
	imshow("111", red);
	int k = waitKey(0);
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值