简单记录opencv有关图像操作部分的笔记
Image Watch是一个免费且非常强大的图像数据查看插件,在进行图片查看时,可以显示其像素值和通道数,对于图片的操作后查看结果非常有帮助。
附下载地址
VS2019版:Image Watch 2019 - Visual Studio Marketplace
VS2017版:Image Watch 2017 - Visual Studio Marketplace
VS2015及以下版:Image Watch - Visual Studio Marketplace
打开方式在【视图】→【其他窗口】中找到image watch后打开,可以配合调试中的断点使用。
创建方式:
Mat a; //创建一个名为a的矩阵头
a=imread("lena.jpg");
数据类型 | 具体类型 | 取值范围 |
---|---|---|
CV_8U | 8位无符号整数 | 0~255 |
CV_8S | 8位符号整数 | -128~127 |
CV_16U | 16位无符号整数 | 0~65535 |
CV_16S | 16位符号整数 | -32768~32767 |
CV_32S | 32位符号整数 | -2147483648~2147483647 |
CV_32F | 32位浮点整数 | |
CV_64F | 64位浮点整数 |
关于通道,C1、C2、C3、C4分别表示单通道、双通道、3通道以及4通道。
方式1:
Mat(int rows,int cols,int type)
例如 Mat a(640,480,CV_8UC3)表示创建了一个640*480的8位无符号整数的3通道矩阵用于存放彩色图像
方式2:
Mat(Size size(),int type)
例如 Mat b(Size(480,640),CV_32FC3)表示创建了一个640*480的32位浮点整数的3通道矩阵用于存放彩色图像
Mat(int rows,int cols,int type,const Scalar &s)
例如:Mat img1(2, 2, CV_8UC3, Scalar(0, 0, 255))
创建了一个三通道的矩阵,第三层通道值为255,前两层为0,启动Image Watch查看效果如下:
其他方式(枚举法):
Mat a=(Mat_(3,3)<<1,2,3,4,5,6,7,8,9)
常用方式:
通过at方法读取单通道Mat类矩阵中的元素
Mat a=(Mat_(3,3)<<1,2,3,4,5,6,7,8,9);
int value=(int)a.at(0,0);
对于多通道类型,存储方式见下图
3通道的存储方式:
图示为一个3*3通道的存储方式,对于单个元素,是按照每个通道相邻这样去存储的。
那么需要特殊的数据结构去存放这些Vec3b,Vec3s,Vec3w,Vec3d,Vec3f,Vec3i
通过at方法读取多通道Mat类矩阵中的元素
Mat b(3,4,CV_8UC3,Scalar(0,0,1));
Vec3b vc3 = b.at(0, 0);
int first = (int)vc3.val[0];
int second = (int)vc3.val[1];
int third = (int)vc3.val[2];
强制转换不能少!
其他还有指针ptr和迭代器方式,这里不做记录了
图像操作是opencv的重头戏,从几个函数分别介绍
imread(const String&filename,int flags=IMREAD_COLOR)
其中第一个参数为图像的完整地址,如“D:/vs项目/opencv4_test/opencv4_test/lena.jpg”,第二个参数为读取方式,比如以灰度图读取(IMREAD_GRAYSCALE)、彩色图读取(IMREAD_COLOR)
imshow(const String & winname,InputArray mat)
其中第一个参数为要显示图像的窗口名字,第二个参数为要显示的图像矩阵
该函数为图像窗口函数,用于创建图像要显示的窗口
void namedWindow(const String & winname,int flags=WINDOW_AUTOSIZE)
bool imwrite(const String & filename,InputArray img,Const vector& params =vector())
filename:保存图像的地址和文件名
img:将要保存的Mat类矩阵变量
params:保存图片格式属性设置标志
#include //加载OpenCV4的头文件
#include
using namespace std;
using namespace cv; //OpenCV命名空间
void AlphaMat(Mat &mat)
{
CV_Assert(mat.channels() == 4);
for (int i = 0; i < mat.rows; i++)
{
for(int j=0;j<mat.cols;j++)
{
Vec4b& bgra = mat.at<Vec4b>(i, j);
bgra[0] = UCHAR_MAX; //蓝色通道B
bgra[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols)*UCHAR_MAX); //绿色通道G
bgra[2] = saturate_cast<uchar>((float(mat.cols - i)) / ((float)mat.rows)*UCHAR_MAX); //红色通道R
bgra[3] = saturate_cast<uchar>(0.5*(bgra[1] + bgra[2])); //Alpha通道
}
}
}
int main()
{
Mat mat(480, 640, CV_8UC4);
AlphaMat(mat);
vector<int> compression_params;
compression_params.push_back(IMWRITE_PNG_COMPRESSION); //PNG格式图像压缩标志
compression_params.push_back(9); //设置最高压缩质量
bool result = imwrite("alpha.png", mat, compression_params);
if (!result)
{
cout << "保存成PNG格式图像失败" << endl;
return -1;
}
cout << "保存成功" << endl;
return 0; //程序结束
}
转换前与转换后成功保存的图像对比,4通道(Alpha通道)图像可以保存成PNG格式文件。
感谢阅读!也欢迎大家关注小白博主,多多鼓励一下!