OpenCV4入门教程010:imread/imshow/imwrite

索引地址:系列索引

imread()

OpenCV主要用于图片数据处理和图片处理(视频算是连续的图片),既然要处理那么就需要读取图片数据,OpenCV提供的读取图片的函数是imread()(与Matlab类似)。

C/C++声明是:

1
2
Mat cv::imread( const String&  filename,
int flags = IMREAD_COLOR);

filename位置加载图片,然后将数据保存到Mat对象中。

支持常见的图片格式如:*.jpg *.png *.bmp。

后面的flags表示读取方式,可以原格式读取,也可以按灰度图方式读取。我暂时只用到这两个,如果有其他需要,参见参考手册。

测试代码:

1
2
3
4
5
6
7
8
9
10
#include <opencv2/opencv.hpp>  //头文件
using namespace cv; //包含cv命名空间

void main()
{
// 【1】读入一张图片,载入图像
Mat srcImage = imread("lena.jpg");
// 【3】等待任意按键按下
waitKey(0);
}

使用方法就是创建一个新Mat对象,然后将imread()读取生成的Mat值赋值给此对象,后续就可以使用了。

imshow()

读取图片数据结束之后,需要查看一下是否读取正确,OpenCV提供一个GUI显示接口:imshow()。

函数原型为:

1
2
3
4
5
6
7
8
9
10
11
12
#include <opencv2/opencv.hpp>  //头文件
using namespace cv; //包含cv命名空间

void main()
{
// 【1】读入一张图片,载入图像
Mat srcImage = imread("1.jpg");
// [2]显示图片
imshow("imshow testing",srcImage);
// 【3】等待任意按键按下
waitKey(0);
}

第一个参数是窗口名,显示图片时位于界面正上方。第二个参数是图片数据,最常用的就是imread()读取的Mat对象,当然了,其他的mat对象也可以。

1
2
3
4
5
6
7
8
9
10
11
12
#include <opencv2/opencv.hpp>  //头文件
using namespace cv; //包含cv命名空间

void main()
{
// 【1】读入一张图片,载入图像
Mat srcImage = imread("1.jpg");
// [2]显示图片
imshow("imshow testing",srcImage);
// 【3】等待任意按键按下
waitKey(0);
}

测试结果:

imshow

注意:如果没有特别修改代码,第一个参数不能是中文,否则,文字会显示为???并且图片会全黑。

imwrite()

图片处理完成之后需要将内存中的数据保存起来,imwrite()可以实现这个需求。

函数声明:

1
2
bool cv::imwrite (const String& filename,InputArray img,
const std::vector<int>& params = std::vector< int >());

函数参数:

  • filename:需要保存图像的文件名,要保存图片为哪种格式,就带什么后缀。
  • img:要保存的图像。
  • params:表示为特定格式保存的参数编码。

注意:imwrite函数是基于文件扩展名选择图像的格式。通常,使用此功能只能保存8位单通道或3通道(带有BGR通道顺序)图像,但有以下例外:

  • 对于PNG,JPEG2000和TIFF格式,可以保存16位无符号(CV_16U)图像。
  • 32位浮点(CV_32F)图像可以保存为PFM,TIFF,OpenEXR和Radiance HDR格式; 使用LogLuv高动态范围编码(每像素4个字节)保存3通道(CV_32FC3)TIFF图像
  • 可以使用此功能保存带有Alpha通道的PNG图像。为此,创建8位(或16位)4通道图像BGRA,其中alpha通道最后。完全透明的像素应该将alpha设置为0,完全不透明的像素应该将alpha设置为255/65535。

如果格式,深度或通道顺序不同,请在保存之前使用Mat::convertTocv::cvtColor进行转换。或者,使用通用FileStorage I / O函数将图像保存为XML或YAML格式。

编码参数:

参数说明
IMWRITE_JPEG_QUALITY对于JPEG,它可以是从0到100的质量(越高越好)。默认值为95。
IMWRITE_JPEG_PROGRESSIVE启用JPEG功能,0或1,默认为False。
IMWRITE_JPEG_OPTIMIZE启用JPEG功能,0或1,默认为False。
IMWRITE_JPEG_RST_INTERVALJPEG重启间隔,0 - 65535,默认为0 - 无重启。
IMWRITE_JPEG_LUMA_QUALITY单独的亮度质量等级,0 - 100,默认为0 - 不使用。
IMWRITE_JPEG_CHROMA_QUALITY单独的色度质量等级,0 - 100,默认为0 - 不使用。
IMWRITE_PNG_COMPRESSION对于PNG,它可以是从0到9的压缩级别。
值越高意味着更小的尺寸和更长的压缩时间。
如果指定,则策略更改为IMWRITE_PNG_STRATEGY_DEFAULT(Z_DEFAULT_STRATEGY)。
默认值为1(最佳速度设置)。
IMWRITE_PNG_STRATEGY其中一个Type::ImwritePNGFlags,默认为IMWRITE_PNG_STRATEGY_RLE。
IMWRITE_PNG_BILEVEL二进制级别PNG,0或1,默认为0。
IMWRITE_PXM_BINARY对于PPM,PGM或PBM,它可以是二进制格式标志,0或1.默认值为1。
IMWRITE_EXR_TYPE
IMWRITE_WEBP_QUALITY
覆盖EXR存储类型(默认为FLOAT(FP32))对于WEBP,它可以是1到100的质量(越高越好)。默认情况下(不带任何参数),如果质量高于100,则使用无损压缩。
IMWRITE_PAM_TUPLETYPE对于PAM,将TUPLETYPE字段设置为为格式定义的相应字符串值。
IMWRITE_TIFF_RESUNIT对于TIFF,用于指定要设置的DPI分辨率单位; 请参阅libtiff文档以获取有效值。
IMWRITE_TIFF_XDPI对于TIFF,用于指定X方向DPI。
IMWRITE_TIFF_YDPI对于TIFF,用于指定Y方向DPI。
IMWRITE_TIFF_COMPRESSION对于TIFF,用于指定图像压缩方案。请参阅libtiff以获取与压缩格式对应的整数常量。
注意,对于深度为CV_32F的图像,仅使用libtiff的SGILOG压缩方案。
对于其他支持的深度,可以通过此标志指定压缩方案; LZW压缩是默认值。
IMWRITE_JPEG2000_COMPRESSION_X1000对于JPEG2000,用于指定目标压缩率(乘以1000)。该值可以是0到1000.默认值是1000。

测试代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <opencv2/opencv.hpp>
#include <iostream>

int main()
{
cv::Mat srcImage;
//加载图像
srcImage = cv::imread("image.jpg",1);
if (srcImage.empty())
{
std::cout << "图像加载失败!" << std::endl;
return -1;
}
cv::imshow("main", srcImage);
//保存图像到当前项目
cv::imwrite("save.jpg", srcImage);
cv::waitKey(0);
return 0;
}

imwrite

测试代码2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <vector>
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

//--------------------------------【createAlphaMat( )函数】--------------------------------
// 描述:创建带alpha通道的Mat
//-------------------------------------------------------------------------------------------------
void createAlphaMat(Mat &mat)
{
for(int i = 0; i < mat.rows; ++i) {
for(int j = 0; j < mat.cols; ++j) {
Vec4b&rgba = mat.at<Vec4b>(i, j);
rgba[0]= UCHAR_MAX;
rgba[1]= saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) *UCHAR_MAX);
rgba[2]= saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) *UCHAR_MAX);
rgba[3]= saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
}
}
}

int main( )
{
//创建带alpha通道的Mat
Mat mat(480, 640, CV_8UC4);
createAlphaMat(mat);

//此部分用于赋给imwrite的第二个参数,用于压缩图片设置压缩格式
vector<int>compression_params;
compression_params.push_back(IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);

//显示图片
try{
imwrite("透明Alpha值图.png", mat, compression_params);
imshow("生成的png图",mat);
fprintf(stdout,"PNG图片文件的alpha数据保存完毕~\n可以在工程目录下查看由imwrite函数生成的图片\n");
waitKey(0);
}
catch(runtime_error& ex) {
fprintf(stderr,"图像转换成PNG格式发生错误:%s\n", ex.what());
return 1;
}

return 0;
}

使用imwrite来生成一个渐变图片。具体像素操作在下一篇介绍。

效果如下:

imwrite


OpenCV4入门教程010:imread/imshow/imwrite
https://blog.jackeylea.com/opencv/opencv-useful-imread-imshow-imwrite/
作者
JackeyLea
发布于
2020年5月12日
许可协议