1、所用函数原型:
Mat cv::imread(const String & filename,
int flags = IMREAD_COLOR)
功能介绍:函数imread从指定的文件中加载一个图像并返回它。如果图像不能被读取(因为文件丢失、权限不当、不支持或无效格式),函数返回一个空矩阵(Mat::data==NULL)
参数 filename:指定希望读取图像的路径,可以为相对路径和绝对路径
参数 flags:指定读取图像的格式。该值枚举自 cv::ImreadModes,默认值为1。具体见下表
枚举类型 | 枚举值 | 类型描述 |
---|---|---|
IMREAD_UNCHANGED | -1 | 将加载的图像按原样返回,包括alpha通道。会忽略EXIF方向 |
IMREAD_GRAYSCALE | 0 | 编解码器内部将图像转换为单通道灰度图像返回 |
IMREAD_COLOR | 1 | 将图像转换为RGB通道排列的彩色图像,该值是函数的默认值 |
IMREAD_ANYDEPTH | 2 | 如果图像具有深度,则返回对应的16/32位图像。否则转换为8位返回 |
IMREAD_ANYCOLOR | 4 | 图像以任何可能的颜色读取 |
IMREAD_LOAD_GDAL | 8 | 使用gdal驱动程序加载图像 |
IMREAD_REDUCED_GRAYSCALE_2 | 16 | 将图像转换为单通道的灰度图像,图像的尺寸缩小为1/2 |
IMREAD_REDUCED_COLOR_2 | 17 | 将图像转换为RGB通道排列的彩色图像,图像尺寸缩小为1/2 |
IMREAD_REDUCED_GRAYSCALE_4 | 32 | 将图像转换为单通道的灰度图像,图像的尺寸缩小为1/4 |
IMREAD_REDUCED_COLOR_4 | 33 | 将图像转换为RGB通道排列的彩色图像,图像尺寸缩小为1/4 |
IMREAD_REDUCED_GRAYSCALE_8 | 64 | 将图像转换为单通道的灰度图像,图像的尺寸缩小为1/8 |
IMREAD_REDUCED_COLOR_8 | 65 | 将图像转换为RGB通道排列的彩色图像,图像尺寸缩小为1/8 |
IMREAD_IGNORE_ORIENTATION | 128 | 不要根据EXIF的方向标志旋转图像 |
注意:上表中的参数,我们常用的为前三个,其它参数不必去刻意记住。用的时候查询即可
2、对于图片路径的参数,在测试案例中,我们通常会用到函数:
cv::String cv::samples::findFile (const cv::String & relative_path,
bool required = true,
bool silentMode = false)
该函数会到相关路径下去找到相关的图片,这个相关路径通常涵盖以下路径:
该函数与 cv::utils::findDataFile 函数的功能一致。此处不赘述。返回图片所在路径。
3、函数调用示例代码(C++):
Mat src = imread(samples::findFile("lena.jpg",true,true), IMREAD_COLOR);
4、OpenCV所支持的图像类型说明:
注意:
判断图像读取内容是否为空的方法有以下两种:
1、调用 Mat 对象的 empty() 方法。如:src.empty()
通常将该函数的返回值放到 if 的判断逻辑中,如果为真,表示读取图像内容为空,则处理:
if (src.empty())
{
fprintf(stderr, "Failed oepen image: lena.jpg\n");
return EXIT_FAILURE;
}
2、看 Mat 对象的data属性是否为空,如:src.data
if (!src.data)
{
fprintf(stderr, "Failed oepen image: lena.jpg\n");
return EXIT_FAILURE;
}
1、所用函数原型:
void cv::imshow (const String & winname,
InputArray mat)
函数imshow在指定的窗口中显示图像。如果窗口是用cv::WINDOW_AUTOSIZE标志创建的,图像将以原始大小显示,但是它仍然受到屏幕分辨率的限制。否则,图像将被缩放以适应窗口。函数可以根据图像的深度对图像进行缩放:
2、调用 waitKey() 函数等待用户输入,否则图像显示会一闪而过。
int cv::waitKey (int delay = 0)
该函数会等待 delay所指示的时间间隔后,执行后续指令。返回用户所按的键值,通常与ASCII相关联。如果delay≤0,则表示无限制等待。否则等待时间为delay值,单位毫秒。由于线程间的切换存在着时间消耗,所以该等待时间不会严格等于delay,与当前系统执行的任务等有关。
3、调用实例:
namedWindow("demo", WINDOW_AUTOSIZE);
imshow("demo", src);
waitKey(0);
注意此处我在显示之前调用namedWindow函数新建了一个窗口,这一步不是必须,后续会解释其用处。
1、所用函数原型:
bool cv::imwrite (const String & filename,
InputArray img,
const std::vector< int > & params = std::vector< int >())
函数imwrite将img所指代的图像保存到指定的文件中(filename)。图像格式是根据文件名扩展名选择的。一般情况下,使用该函数只能保存8位单通道或3通道(通道顺序为BGR)的图像,但有以下几种例外情况:
参数 filename:指示文件的名称,包含后缀。写入图像支持的格式与读入支持的格式一致
参数 img:需要保存的图像或图像数组(vector)
参数 params:特定于图像保存格式的参数编码对,参数类型为int 构成的vector,其值枚举自 cv::ImwriteFlags,见下表:
枚举类型 | 枚举值 | 类型说明 |
---|---|---|
IMWRITE_JPEG_QUALITY | 1 | 对于JPEG,它的取值可以是0到100(越高越好)。默认值为95 |
IMWRITE_JPEG_PROGRESSIVE | 2 | 启用JPEG特性,0或1,默认为False |
IMWRITE_JPEG_OPTIMIZE | 3 | 启用JPEG特性,0或1,默认为False |
IMWRITE_JPEG_RST_INTERVAL | 4 | JPEG重启间隔,0 - 65535,默认为0 表示不重启 |
IMWRITE_JPEG_LUMA_QUALITY | 5 | 单独的亮度质量等级,0 - 100,默认为0 表示不使用 |
IMWRITE_JPEG_CHROMA_QUALITY | 6 | 单独的色度质量级别,0 - 100,默认为0 表示不使用 |
IMWRITE_PNG_COMPRESSION | 16 | PNG格式的压缩级别为0 ~ 9。数值越高,压缩时间越长。如果指定了,strategy会变为IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY)。默认值为1(最佳速度) |
IMWRITE_PNG_STRATEGY | 17 | cv::ImwritePNGFlags的一种,默认为IMWRITE_PNG_STRATEGY_RLE。 |
IMWRITE_PNG_BILEVEL | 18 | 二值PNG, 0或1,默认为0 |
IMWRITE_PXM_BINARY | 32 | 对于PPM、PGM或PBM,可以是二进制格式标志0或1。默认值为1 |
IMWRITE_EXR_TYPE | EXR存储类型(默认为FLOAT (FP32)) | |
IMWRITE_WEBP_QUALITY | 64 | 对于WEBP,它的质量可以从1到100(越高越好)。默认情况下(没有任何参数),如果质量超过100,则使用无损压缩。 |
IMWRITE_PAM_TUPLETYPE | 128 | 对于PAM,将TUPLETYPE字段设为为该格式定义的对应字符串值 |
IMWRITE_TIFF_RESUNIT | 256 | 对于TIFF格式,使用指定要设置的DPI分辨率单元;有关有效值,请参阅libtiff文档 |
IMWRITE_TIFF_XDPI | 257 | 对于TIFF,用于指定X方向DPI |
IMWRITE_TIFF_YDPI | 258 | 对于TIFF,用于指定Y方向DPI |
IMWRITE_TIFF_COMPRESSION | 259 | 对于TIFF格式,用于指定图像压缩方案。有关压缩格式对应的整数常量,请参阅libtiff。注意,对于深度为CV_32F的图像,只使用libtiff的SGILOG压缩方案。对于其他支持的深度,压缩方案可以由这个标志指定;默认为LZW压缩 |
IMWRITE_JPEG2000_COMPRESSION_X1000 | 272 | 对于JPEG2000,使用指定目标压缩率(乘以1000)。取值范围为0 ~ 1000。默认是1000 |
2、简单调用代码:
int k =waitKey(0);
if (k == 's')
{
imwrite("O:\\image\\test.jpg", src);
}
// 只include一个hpp即可,可以自行查看该文件,包含了所有的hpp
#include
// 引入命名空间后,使用opencv的方法时就不需要特定指定cv::? 了
using namespace cv;
int main(int argc, char** argv)
{
// 调用imrad函数读取名为”lena.jpg“的图像,该图像在系统的搜索路径下,图像打开格式为IMREAD_COLOR
Mat src = imread(samples::findFile("lena.jpg",true,true), IMREAD_COLOR);
// 判读读入的图像内容是否为空
if (!src.data)
{
fprintf(stderr, "Failed oepen image: lena.jpg\n");
return EXIT_FAILURE;
}
// 新命名一个窗口,窗体的大小根据图像大小自动调整
namedWindow("demo", WINDOW_AUTOSIZE);
// 在名为”demo“的窗体上显示src所指向的图像
imshow("demo", src);
// 一直等待用户按键,按键的返回值存入变量k
int k =waitKey(0);
// 如果用户按下了's'键,则在相应路径下保存图片
if (k == 's')
{
// 调用imwrite保存图像
imwrite("O:\\image\\test.jpg", src);
}
system("pause");
return EXIT_SUCCESS;
}
#include
using namespace cv;
using namespace std;
// 自定义函数生成带alpha通道的图像
static void paintAlphaMat(Mat& 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);
// 分别设置 B G R A 通道的像素值
bgra[0] = UCHAR_MAX; // Blue
bgra[1] = saturate_cast<uchar>((float(mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); // Green
bgra[2] = saturate_cast<uchar>((float(mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // Red
bgra[3] = saturate_cast<uchar>(0.5 * (bgra[1] + bgra[2])); // Alpha
}
}
}
int main(int argc,char **argv)
{
// 自定义一个名为mat的Mat对象,尺寸为480*640,数据类型为CV_8UC4,表示无符号的8位4通道图
Mat mat(480, 640, CV_8UC4);
// 调用自定义函数生成带alpha通道的图像
paintAlphaMat(mat);
// 定义int元素类型的vector变量compression_params作为保存图片时的参数
vector<int> compression_params;
compression_params.push_back(IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
// result用于接受保存图像的结果,成功为true ,失败为false
bool result = false;
try
{
result = imwrite("alpha.png", mat, compression_params);
}
catch (const cv::Exception & ex)
{
fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
}
if (result)
printf("Saved PNG file with alpha data.\n");
else
printf("ERROR: Can't save PNG file.\n");
// 定义Mat元素类型的vector变量imgs
vector<Mat> imgs;
imgs.push_back(mat);
imgs.push_back(~mat);
imgs.push_back(mat(Rect(0, 0, mat.cols / 2, mat.rows / 2)));
imwrite("test.tiff", imgs);
printf("Multiple files saved in test.tiff\n");
system("pause");
return result ? 0 : 1;
}
1、还是感谢CCTV,感谢所有支持的朋友
2、有兴趣探讨一起学习的欢迎入群 725027506 。入群飞机票