Opencv 图片处理

目录

一,Mat类、图像核心信息

1,客观信息

(1)维数

(2)行列

2,主观信息

(1)通道数

(2)位深

3,Mat类坐标

4,Mat对象创建

5,Mat类型转换

二,基本操作

1,存储和读取

2,显示图像 imshow

3,显示信息

三,图片截取

1,Rect

2,Range

四,图片尺寸 resize

五,窗口控制 namedWindow


一,Mat类、图像核心信息

Mat类用一个对象对应一张图,除了数据域还有各种重要信息。

Opencv源码解析

1,Mat类坐标

Mat类中默认的坐标是以左上角为原点,向下和向右是正方向。

至于哪个是x,哪个是y,Mat中两种坐标都用到。

而行和列这2个词应该是没有歧义的,所以有些地方我会用行坐标和列坐标来描述。

2,Mat对象创建

可以读取图片文件创建Mat对象,也可以用数组创建Mat对象

    char c[] = "123456789";
	int row = 3, col = 3;
	Mat image = Mat(row, col, CV_8U, c);

3,Mat类型转换

修改Mat对象的值,原数组的值会改变。

int main()
{
	char c[] = "123456789";
	int row = 3, col = 3;
	Mat image = Mat(row, col, CV_8U, c);
	image.at(1, 1) = 56;
	for(int i=0;i<9;i++)cout << (c[i])<<" ";
	return 0;
}

输出:1 2 3 4 8 6 7 8 9

如果把8位图像转成32位图像,会重新分配内存:

int main()
{
	char c[] = "123456789";
	int row = 3, col = 3;
	Mat image = Mat(row, col, CV_8U, c);
	image.convertTo(image, CV_32F);
	image.at(1, 1) = 56;
	for(int i=0;i<9;i++)cout << (c[i])<<" ";
	return 0;
}

输出:1 2 3 4 5 6 7 8 9

即使是CV_32S转成CV_32F 也是一样,会重新分配内存。

二,基本操作

1,存储和读取

Opencv存图读图

2,显示图像 imshow

imshow("img", image);
waitKey(0);

本地文件:

Opencv 图片处理_第1张图片

windows自带软件显示是宽582像素,高266像素

我的程序运行结果:

Opencv 图片处理_第2张图片

文件名还有bug,连英文字母都乱码了。

如果读取参数是IMREAD_GRAYSCALE,那么显示的结果:

Opencv 图片处理_第3张图片

3,显示信息

打印每个像素点的像素值:

cout << "rows=" << image.rows << endl;
cout << "cols=" << image.cols << endl;
cout << "channels=" << image.channels() << endl;

for (int i = 0; i < image.rows; i++) {
	for (int j = 0; j < image.cols; j++) {
		cout << int(image.at(i, j)[0])<<" ";
	}
	cout << endl;
}

at是模板函数,返回值类型就是模板参数的类型。

如类型参数Vec3b对应三通道的图,返回的就是Vec3b,它是一个长为3的向量,获取其中一个通道的像素值可以用[0]、[1]、[2],类型是uchar,转化成int就是0-255

其实有Vec3i的类型,直接就是int类型,但是用这个直接报内存错误,不知道为啥。

如果是单通道的图,那么参数类型就是uchar:

for (int i = 0; i < image.rows; i++) {
	for (int j = 0; j < image.cols; j++) {
		cout << int(image.at(i, j))<<" ";
	}
	cout << endl;
}

三,图片截取

1,Rect

初始化Rectangle矩形对象,依次提供四个参数:列坐标,行坐标,宽度,高度

int main()
{
	string path = "D:\im.jpg";
	Mat image = imread(path, IMREAD_COLOR);
	namedWindow("1", WINDOW_GUI_NORMAL);

	Rect area(0, 50, 200, 350);
	Mat image2 = image(area);
	imshow("img", image);
	imshow("img2", image2);
	waitKey(0);
	return 0;
}

输出:

2,Range

Range的2个参数就是坐标的区间范围

Mat image2 = image(Range(0,200),Range(50,400));

第一个Range是选择行的范围,第二个是选择列的范围。

就感觉两种方式的参数顺序的反的!

四,图片尺寸 resize

先给出要变成的大小,Size类根据(宽度,高度)生成对象,

然后用resize函数得到一个新尺寸的Mat对象,原对象不影响。

resize的第五个参数是插值算法的类型。

Size dsize = Size(round(0.3 * image.cols), round(0.6 * image.rows));
Mat shrink;
resize(image, shrink, dsize, 0, 0, INTER_AREA);
imshow("shrink", shrink);
waitKey(0);

Opencv 图片处理_第4张图片

五,窗口控制 namedWindow

namedWindow("1", WINDOW_GUI_NORMAL);

第二个参数是用来控制窗口的属性,主要是位置和尺寸能否改变。

加上这句话之后,会多显示一个黑框,imshow输出的窗口也能移动了。

否则,imshow输出的窗口是不能移动的。

这个结果有点奇怪,我理解namedWindow函数应该就是用来控制imshow输出的窗口的属性才对。

你可能感兴趣的:(opencv)