栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Chapter

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Chapter

文章目录
      • 一. 输入/输出
        • ① 从一个文件中加载一个图像
        • ② 写入图像到一个文件中
      • 二. 图像的基本操作
        • ① 访问像素强度值
      • 三. 内存管理和引用计数
      • 四. 原始操作
      • 五. 可视化图像

一. 输入/输出 ① 从一个文件中加载一个图像
Mat img = imread(filename);

如果你想读取一个jpg图像,默认会创建一个3通道的图像.如果你需要一个灰度图像,使用:

Mat img = imread(filename,IMREAD_GRAYSCALE);

注意:

文件的格式由其内容(前几个字节)决定. 将图像保存到文件.

② 写入图像到一个文件中
imwrite(filename,img);

注意:
文件的格式由其扩展名决定.使用cv::imdecode和cv::imencode从内存中读取和写入图像,而不是文件.

二. 图像的基本操作 ① 访问像素强度值

为了得到像素的强度值,你必须知道图像的类型和通道的数量.下面是一个单通道灰度图像(类型 8UC1)和像素坐标x和y的示例:

Scalar intensity = img.at(Point(x,y));

现在让我们考虑一个BGR颜色排序的3通道图像(imread返回的默认格式):

Vec3b intesity = img.at(y,x);
uchar blue = intesity.val[0];
uchar green = intesity.val[1];
uchar red = intesity.val[2];

你可以对浮点类型的图像使用相同的方法(例如,可以通过3通道图像上运行Soble来获得这样的图像)(仅限C++):

Vec3f intensity = img.at(y,x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];

同样的方法可以用来改变像素强度:

img.at(y,x) = 128;

Opencv中的有一些函数,特别是来自calib3d模块的函数,比如cv::projectPoints,以Mat的形式获取二维或者三维点的数组.矩阵应该恰好包含一列,每一行对应一个点,对应的矩阵类型应该是32FC2或者32FC3.这样的矩阵可以很容易地从std::vector中构造(仅限C++):

vector points;
// ... fill the array
Mat pointsMat = Mat(points);

你可以使用相同的方法访问这个矩阵中的一个点Mat::at(仅限C++):

Point2f point = pointsMat.at(i,0);
三. 内存管理和引用计数

Mat是这样一中结构体,它保存了矩阵/图像特征(行数和列数,数据类型等)和一个指向数据的指针.因此,没有什么可以阻止我们拥有多个对应相同数据的Mat实例.Mat保持了一个引用计数,当特定的Mat实例被销毁的时候,它告诉数据是否必须被释放.下面是一个在不复制数据的情况下创建两个矩阵的示例(仅限C++):

std::vector points;
// .. fill the array
Mat pointsMat = Mat(points).reshape(1);

结果,我们得到一个三列的32FC1矩阵,而不是1列的32FC3矩阵.pointsMat使用来自points的数据,销毁时不会释放内存.但是,在这个特殊的例子中,开发人员必须确保points的声明周期比pointsMat长.我们如果需要复制数据,可以使用cv::Mat::copyTo或者cv::Mat::clone()来完成.

Mat img = imread("image.jgp");
Mat img1 = img.clone();

可以为每个函数提供空的输出Mat.每个市县对目标矩阵调用Mat::create.如果矩阵为空,则此方法为其分配数据.如果它不是空的,并且具有正确的大小和类型,则该方法不执行任何操作.但是,如果大小或者类型与输入参数不同,则释放(或丢失)数据,并分配新数据.例如:

Mat img = imread("image.jgp");
Mat sobelx;
Sobel(img,sobelx,CV_32F,1,0);
四. 原始操作

矩阵上定了许多方便的运算符.例如,下面展示了我们如何从现有的灰度图像img中生成黑色图像

img = Scalar(0);

选择感应区的区域

Rect r(10,10,100,100);
Mat smallImg = img(r);

将图像从彩色图像转换为灰度图像

Mat img = imread("image.jpg"); // loading a 8UC3 image
Mat gray;
cvtColor(img,gray,COLOR_BGR2GRAY);

将图像的数据类型从8UC1转换为32FC1:

src.convertTo(dst,CV_32F);
五. 可视化图像

在开发的过程中查看算法的中间结果是非常有用的.Opencv提供了一种方便的可视化图像的方法.一个8U的图像可以显示使用:

Mat img = imread("image.jpg");
nameWindow("image",WINDOW_AUTOSIZE);
imshow("image",img);
waitKey();

通过调用waitKey()启动一个循环接收消息,等待图像串口的点击键盘.一个32F的图像需要转换为8U的类型,例如:

Mat img = imread("image.jgp");
Mat gray;
cvtColor(img,gray,COLOR_BGR2GRAY);
Mat sobelX;
Sobel(gray,sobelX,CV_32F,1,0);
double minVal,maxVal;
minMaxLoc(sobelX,&minVal,&maxVal);// find minimum and maximum intensities
Mat draw;
sobelx.convertTo(draw,CV_8U,255.0 / (maxVal - minVal),-minVal * 255.0 / (maxVal - minVal));
nameWindow("image" WINDOW_AUTOSIZE);
imshow("image",draw);
waitKey();

注意:
这里的cv::nameWindow不是必要的,因为它后面紧跟着cv::imshow,它可以用于更该窗口属性或者使用cv::createTrackbar时的时候使用.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/928820.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号