概述
目录
一,Mat类、图像核心信息
1,Mat类坐标
2,Mat对象创建
3,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<char>(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<float>(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);
本地文件:
windows自带软件显示是宽582像素,高266像素
我的程序运行结果:
文件名还有bug,连英文字母都乱码了。
如果读取参数是IMREAD_GRAYSCALE,那么显示的结果:
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<Vec3b>(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<uchar>(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);
五,窗口控制 namedWindow
namedWindow("1", WINDOW_GUI_NORMAL);
第二个参数是用来控制窗口的属性,主要是位置和尺寸能否改变。
加上这句话之后,会多显示一个黑框,imshow输出的窗口也能移动了。
否则,imshow输出的窗口是不能移动的。
这个结果有点奇怪,我理解namedWindow函数应该就是用来控制imshow输出的窗口的属性才对。
六,图片转文本
把图片转化成文本格式:
ios::sync_with_stdio(false);
char str[] = "Z:/image_0.txt";
Mat img = imread("Z:/img.jpg", -1);
freopen(str, "w", stdout);
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
cout << int(img.at<uchar>(i, j)) << endl;
}
}
读文本也可以再转成图片格式。
七,图片转置
int main()
{
Mat im1 = imread("D:/img.jpg",0);
Mat im2 = im1.t();
imshow("img", im1);
imshow("img2", im2);
waitKey(0);
return 0;
}
效果就是沿着主对角线翻转了90度,即左上角右下角不动,左下角右上角互换。
最后
以上就是唠叨热狗为你收集整理的Opencv 图片处理一,Mat类、图像核心信息二,基本操作三,图片截取四,图片尺寸 resize五,窗口控制 namedWindow六,图片转文本七,图片转置的全部内容,希望文章能够帮你解决Opencv 图片处理一,Mat类、图像核心信息二,基本操作三,图片截取四,图片尺寸 resize五,窗口控制 namedWindow六,图片转文本七,图片转置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复