本节主要翻译自OpenCV的帮助资料,并结合一些编程考量。
D、基本输入输出函数
函数原型:
Mat cv::imread(const String &filename, int flags = IMREAD_COLOR );
从文件中装入图像
函数imread从指定的文件中加载图像并返回一个Mat类型的图像对象。如果加载失败(由于文件错,不合适的权限,不支持或不可用的格式),这个函数返回空矩阵( Mat::data==NULL )。
当前版本的openCV中这个函数支持下列格式的图像文件:
注释
参数
filename | 装入的文件名。 |
flags | 标志,可以取值于cv::ImreadModes |
cv::ImreadModes { cv::IMREAD_UNCHANGED = -1, | |
|
|
IMREAD_UNCHANGED Python: cv.IMREAD_UNCHANGED | 如果设置,返回加载的源图,(对alpha通道保留,否则裁剪掉)。不考虑EXIF朝向。 |
IMREAD_GRAYSCALE Python: cv.IMREAD_GRAYSCALE | 如果设置,总是转换图像到单一通道的灰度图(编解码器内部转换)。 |
IMREAD_COLOR Python: cv.IMREAD_COLOR | 如果设置,总是转换图像到3通道BGR的彩色图。 |
IMREAD_ANYDEPTH Python: cv.IMREAD_ANYDEPTH | 如果设置,在输入有对应深度时返回16-bit/32-bit图像,否则转换成8-bit图像。 |
IMREAD_ANYCOLOR Python: cv.IMREAD_ANYCOLOR | 如果设置,图像以任何可能的彩色格式读取。 |
IMREAD_LOAD_GDAL Python: cv.IMREAD_LOAD_GDAL | 如果设置,使用gdal驱动器装载图像。 |
IMREAD_REDUCED_GRAYSCALE_2 Python: cv.IMREAD_REDUCED_GRAYSCALE_2 | 如果设置,总是转换图像到单通道灰度图像,并且图像尺寸缩减1/2。 |
IMREAD_REDUCED_COLOR_2 Python: cv.IMREAD_REDUCED_COLOR_2 | 如果设置,总是转换图像到3通道BGR彩色图像,并且图像尺寸缩减1/2。 |
IMREAD_REDUCED_GRAYSCALE_4 Python: cv.IMREAD_REDUCED_GRAYSCALE_4 | 如果设置,总是转换图像到单通道灰度图像,并且图像尺寸缩减1/4。 |
IMREAD_REDUCED_COLOR_4 Python: cv.IMREAD_REDUCED_COLOR_4 | 如果设置,总是转换图像到3通道BGR彩色图像,并且图像尺寸缩减1/4。 |
IMREAD_REDUCED_GRAYSCALE_8 Python: cv.IMREAD_REDUCED_GRAYSCALE_8 | 如果设置,总是转换图像到单通道灰度图像,并且图像尺寸缩减1/8。 |
IMREAD_REDUCED_COLOR_8 Python: cv.IMREAD_REDUCED_COLOR_8 | 如果设置,总是转换图像到3通道BGR彩色图像,并且图像尺寸缩减1/8。 |
IMREAD_IGNORE_ORIENTATION Python: cv.IMREAD_IGNORE_ORIENTATION | 如果设置,不依据EXIF朝向标志旋转图像。 |
bool cv::imwrite(const String & filename, InputArray img, const std::vectorstd::vector< int >()
);
保存图像到指定的文件。
函数imwrite()保存图像到指定的文件。图像格式以选择的文件名扩展为准(参见cv::imread中文件名扩展的列表)。一般而言,只有8位单通道或3通道(BGR通道顺序)图像可以使用这个函数保存,除此之外还可以有:
如果格式的深度或通道顺序不同,需使用 Mat::convertTo 和 cv::cvtColor 在保存之前进行转换。也可通过FileStorage I/O 函数保存图像到XML 或 YAML 格式。
下面的示例给出建立BGRA 图像并存储成PNG 文件的例子。 它还展示了怎样设置图像的压缩参数:
#include
using namespace cv;
using namespace std;
static void createAlphaMat(Mat &mat)
{
CV_Assert(mat.channels() == 4);
for (int i = 0; i for (int j = 0; j Vec4b& bgra = mat.at bgra[0] = UCHAR_MAX; // 蓝 bgra[1] = saturate_cast bgra[2] = saturate_cast bgra[3] = saturate_cast } } } int main() { //建立具有alpha通道的矩阵 Mat mat(480, 640, CV_8UC4); createAlphaMat(mat); vector compression_params.push_back(IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); bool result = false; try{ result = imwrite("alpha.png", mat, compression_params); }catch (const cv::Exception& ex){ fprintf(stderr, "转换图像到PNG格式出现异常: %s\n", ex.what()); } if (result) printf("存储成具有alpha数据的PNG格式文件.\n"); else printf("错误: 不能存储成PNG格式文件.\n"); return result ? 0 : 1; } 参数 filename 文件名 img 要存储的图像 params 格式指定的编码参数使用名-值对(paramId_1, paramValue_1, paramId_2, paramValue_2, ... .) 参见 cv::ImwriteFlags cv::ImwriteFlags { } IMWRITE_JPEG_QUALITY Python: cv.IMWRITE_JPEG_QUALITY JPEG图像的存储质量0 - 100 (越高越好)。默认为95。 IMWRITE_JPEG_PROGRESSIVE Python: cv.IMWRITE_JPEG_PROGRESSIVE 允许的JPEG属性,0/1,默认为False。 IMWRITE_JPEG_OPTIMIZE Python: cv.IMWRITE_JPEG_OPTIMIZE 允许的JPEG属性,0/1,默认为False. IMWRITE_JPEG_RST_INTERVAL Python: cv.IMWRITE_JPEG_RST_INTERVAL JPEG重启间隔,0 – 65535,默认为0 – 无重起。 IMWRITE_JPEG_LUMA_QUALITY Python: cv.IMWRITE_JPEG_LUMA_QUALITY 不同的流明质量级,0 – 100,默认为0 – 不使用。 IMWRITE_JPEG_CHROMA_QUALITY Python: cv.IMWRITE_JPEG_CHROMA_QUALITY 不同的浓度质量级,0 – 100,默认为0 – 不使用。 IMWRITE_PNG_COMPRESSION Python: cv.IMWRITE_PNG_COMPRESSION 对于PNG格式,标识压缩级别从0 到9。较高的值说明较小的图像文件尺寸和较长的压缩时间。如果指定,压缩策略变为IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY)。默认值为1 (最快的速度)。 IMWRITE_PNG_STRATEGY Python: cv.IMWRITE_PNG_STRATEGY cv::ImwritePNGFlags标志之一 ,默认为IMWRITE_PNG_STRATEGY_RLE。 IMWRITE_PNG_BILEVEL Python: cv.IMWRITE_PNG_BILEVEL 二进制层的PNG,0 或1,默认为0。 IMWRITE_PXM_BINARY Python: cv.IMWRITE_PXM_BINARY 对PPM,PGM,或PBM,可以为二进制格式标志,0 或 1。默认为1。 IMWRITE_EXR_TYPE Python: cv.IMWRITE_EXR_TYPE IMWRITE_WEBP_QUALITY Python: cv.IMWRITE_WEBP_QUALITY 重载EXR存储类型(FLOAT,默认为 (FP32) ) 对于WEBP,可以是1到100的质量值(越高越好)。默认(没有任何参数)和大于100的值,使用最低压缩形式。 IMWRITE_PAM_TUPLETYPE Python: cv.IMWRITE_PAM_TUPLETYPE 对于PAM,设置TUPLETYPE字段用对应串值定义使用的格式。. IMWRITE_TIFF_RESUNIT Python: cv.IMWRITE_TIFF_RESUNIT 对于TIFF,用于指定DPI分辨率单位;参见libtiff 资料设置可用的值。 IMWRITE_TIFF_XDPI Python: cv.IMWRITE_TIFF_XDPI 对于TIFF,用于指定X方向的DPI。 IMWRITE_TIFF_YDPI Python: cv.IMWRITE_TIFF_YDPI 对于TIFF,用于指定Y方向上的DPI。 IMWRITE_TIFF_COMPRESSION Python: cv.IMWRITE_TIFF_COMPRESSION 对于TIFF,用于指定图像压缩策略。参见libtiff 的整数内容对应的压缩格式。注意,对于深度为CV_32F的图像,仅仅libtiff 的SGILOG压缩策略可用。对于其它支持的深度,压缩策略可以由这个标志指定;LZW压缩标识是默认选择。 IMWRITE_JPEG2000_COMPRESSION_X1000 Python: cv.IMWRITE_JPEG2000_COMPRESSION_X1000 对于JPEG2000,用于指定目标压缩率(乘以1000)。可以指定从0 到1000。默认为1000。 在指定窗口中显示图像。 函数imshow()在指定窗口中显示图像。如果窗口使用cv::WINDOW_AUTOSIZE标志建立,图像将以其初始的尺寸显示,此时,图像将受到屏幕分辨率的限制。反之图像将以适合窗口大小的尺寸压缩显示。这个函数可以使用相关的深度标识图像。 如果窗口是以OpenGL支持的方式建立,cv::imshow 也支持 ogl::Buffer , ogl::Texture2D 和 cuda::GpuMat 作为输入。 如果在这个函数之前没有建立窗口,这个函数则使用cv::WINDOW_AUTOSIZE建立窗口。 如果需要显示大于屏幕分辨率的图像,则需在imshow()之前要调用namedWindow("", WINDOW_NORMAL)。 注意 在控制台程序操作中,这个函数之后应该调用cv::waitKey 函数来指定显示图像几毫秒(暂停程序)。否则,将不能显示图像。例如,waitKey(0) 将无限长时间显示窗口,直到按下任意键(这适合于图像显示)。waitKey(25) 将显示帧25ms,之后将自动关闭显示。(如果将其放到读视频的循环中,将会逐帧显示视频图像) [在Windows环境下] 按下Ctrl+C 拷贝图像到剪裁板。 [在Windows环境下] 按下Ctrl+S 将显示保存文件对话框。 参数 winname 窗口名(窗口标题) mat 要显示的图像数据。 建立窗口(并在openCV窗口管理中注册窗口,可用窗口名进行检索) 函数namedWindow()建立一个用于图像或跟踪条显示的占位窗口(原始窗口)。所建立的窗口可由窗口名加以引用。如果存在同名窗口,这个函数不做任何操作。 可以调用 cv::destroyWindow 或 cv::destroyAllWindows 来关闭窗口和释放任何相关的内存。为简化程序,并不要求必需调用这些函数,因为应用的所有资源和窗口都在退出时由操作系统自动关闭和释放。 注意 Qt 环境支持的附加标志: 参数 winname 窗口标题上的窗口名,可用作窗口标识。 flags 窗口标志。支持的标志是:(cv::WindowFlags) cv::WindowFlags { } WINDOW_NORMAL Python: cv.WINDOW_NORMAL 用户可以改变窗口大小(无限制) / 也可用于切换全屏窗口到正常大小。 WINDOW_AUTOSIZE Python: cv.WINDOW_AUTOSIZE 用户不能改变窗口大小,窗口大小由显示的图像所限制。 WINDOW_OPENGL Python: cv.WINDOW_OPENGL 具有opengl 支持的窗口。 WINDOW_FULLSCREEN Python: cv.WINDOW_FULLSCREEN 改变窗口到全屏。 WINDOW_FREERATIO Python: cv.WINDOW_FREERATIO 图像可以任意扩展(没有比例限制)。 WINDOW_KEEPRATIO Python: cv.WINDOW_KEEPRATIO 保持图像比例 WINDOW_GUI_EXPANDED Python: cv.WINDOW_GUI_EXPANDED 建立有状态条和工具条窗口。 WINDOW_GUI_NORMAL Python: cv.WINDOW_GUI_NORMAL 旧风格的窗口 E、色彩空间转换(Color Space Conversions) 转换图像从一种彩色空间到另一种彩色空间。 这个函数转换图像从一种彩色空间到另一种彩色空间。在转换RGB彩色空间时,应显式地指定通道顺序(RGB 或 BGR)。注意在openCV中默认的彩色格式通常不同于RGB顺序,而是BGR (字节是颠倒的,Intel CPU是低字节在前)。所以在标准(24位)彩色图像中头一个字节应该是8位的蓝色分量,第二个字节是绿色,而第三个字节是红色。而后的第四,第五,和第六字节是下一个像素(蓝,然后绿,然后红)等等。 R,G,和B 通道值的转换范围是: 在线性变换时,范围并不重要。但是在非线性变换中,输入的RGB图像应该归一化到适当的值范围以便获得正确结果,如,对RGB → L*u*v* 变换。例,假设32位浮点图像直接从8位图像转换而来,而没有定义任何比例,结果是将0..255值范围取代函数设定的0..1。所以在调用cvtColor 之前,需要首先标定像素比例如下: img *= 1./255; cvtColor(img, img, COLOR_BGR2Luv); 如果函数 cvtColor 用于8位图像,转换将丢失某些信息。对于很多应用这样的损失并不显著,但是还是推荐在应用中使用32位图像保证全彩色范围或在操作之前先转换为32位图像,然后再转换回来。 如果转换附加了alpha通道,其值将被设置到最大对应通道范围:255 对应CV_8U,65535 对应CV_16U,1 对应CV_32F。 参数 src 输入图像:8位无符号,16位无符号( CV_16UC... ),或单精度浮点数。 dst 与源图同尺寸和深度的输出图像。 code 色彩空间转换码(参见ColorConversionCodes)。 dstCn 输出图像的通道数;如果这个参数为0,通道数自动从src和code中导出。 转换图像从一种颜色空间到另一种颜色空间,此处的源图像存储在两个位面中。 这个函数现在仅支持YUV420 到 RGB 转换。 参数 src1 Y位面的8位图像(CV_8U)。 src2 包含交替U/V 位面的图像。 dst 输出图像。 code 指定转换类型。可以取值下面任何值: 所有去马赛克过程的主函数 参数 src 输入图像:8位无符号或16位无符号。 dst 输出图像,与输入图像同尺寸和深度。 code 色彩空间转换码(参见下面的描述)。 dstCn 输出图像的通道数;如果为0,通道数自动从scr和code参数中导出。 这个函数可以做如下转换: COLOR_BayerBG2BGR ,COLOR_BayerGB2BGR ,COLOR_BayerRG2BGR ,COLOR_BayerGR2BGR COLOR_BayerBG2GRAY , COLOR_BayerGB2GRAY , COLOR_BayerRG2GRAY , COLOR_BayerGR2GRAY COLOR_BayerBG2BGR_VNG , COLOR_BayerGB2BGR_VNG , COLOR_BayerRG2BGR_VNG , COLOR_BayerGR2BGR_VNG COLOR_BayerBG2BGR_EA , COLOR_BayerGB2BGR_EA , COLOR_BayerRG2BGR_EA , COLOR_BayerGR2BGR_EA COLOR_BayerBG2BGRA , COLOR_BayerGB2BGRA , COLOR_BayerRG2BGRA , COLOR_BayerGR2BGRA 示例程序中首先建立操作对象ImageCls定义如下: class CV_EXPORTS ImageCls { public: static ImageCls* CurMy;//存储回调函数调用的对象 void setCurMy() { //设置当前对象为回调函数调用的对象 CurMy = this; } static INT_PTR CALLBACK iwinProcCls(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);//static void* callback(void*);//回调函数 // HWND hwndMain;//主窗口消息处理handle,在winproc中实现消息处理 char filenm[255]; //图像文件名 // Mat img; //图像数组,初始化为wid = 0,hig = 0,填充为0 Mat Gry_img; char buffer_str[255]; //信息显示缓冲 // ImageCls();//默认构造函数 ImageCls(HWND hwnd, char * flnm, int fltID, int matID); ~ImageCls(void); // public: int handCnt; procHandle* pHandler[255]; int findHandlerPos();//查找空位 int findHandlerPos(HWND hsWnd);//查找定位 int findHandlerPos(char * wnm);//查找定位 public: bool showImageToWin(int imgID); bool showImageToWin(int imgID, char *winNm); HWND SetWinProcTo(char * wname);//绑定键盘消息处理函数 void ShowImage(HWND hpWnd, char * wname, Mat dimg); void Closed(); public: //滤波器节 char filterNM[255];//滤波器显示名 Mat Flt_img;//滤波器操作图像 }; 然后在程序初始化中调用opencv_ImageCls自定义函数: void opencv_ImageCls(HWND hwnd, int filterSz) { MyImageCls = ImageCls(hwnd, filenm, filterID, borderID); MyImageCls.setCurMy();//设置回调操作的静态对象指针变量,静态函数使用非静态类变量需要对象指针。 MyImageCls.handCnt = 0; MyImageCls.showImageToWin(IMAGE_COLOR);//其中包含给图像窗口挂接回调函数,每一个窗口都挂接函数(多个窗口需要不同的操作变量)。 MyImageCls.showImageToWin(IMAGE_GRAY); } 其中showImageToWin函数: bool ImageCls::showImageToWin(int imgID) { bool retV = false; HWND hwd; int ndx = -1; if(img.data){ ndx = findHandlerPos("源图像窗口"); if (ndx >= 0) { retV = true; break; } newNamedWindow( "源图像窗口",CV_WINDOW_AUTOSIZE ); hwd = SetWinProcTo("源图像窗口");//绑定键盘消息处理函数 ShowImage(hwd, "源图像窗口", img); retV = true; } } 其中newNamedWindow函数是对namedWindow函数的改写以适应对图像窗口的管理,其中调用了namedWindow函数。ShowImage函数如下: void ImageCls::ShowImage(HWND hpWnd, char * wname, Mat dimg) { int ndx = findHandlerPos(hpWnd); if(ndx <0) return; procHandle *wpHandler = pHandler[ndx]; // Mat _img = ((InputArray)dimg).getMat(); wpHandler->c_img = _img; wpHandler->arrData = &wpHandler->c_img; wpHandler->iwid = img.cols; wpHandler->ihig = img.rows; newShowImage(wname,&wpHandler->c_img); } newShowImage函数是对imShow的改写。 注意:这里使用的不是控制台形式的操作,而是简单的窗口操作,因此,在winproc回调函数中做了处理,利用了win32的消息循环,不需要使用waitkey()函数做暂停。 以后的所有示例和函数调用都是以这种形式进行,通过主菜单选择功能,对话框获取参数,对图像对象进行操作。这样的展示适合图像的对比和操作结果的显示。
cv::IMWRITE_JPEG_QUALITY = 1,
cv::IMWRITE_JPEG_PROGRESSIVE = 2,
cv::IMWRITE_JPEG_OPTIMIZE = 3,
cv::IMWRITE_JPEG_RST_INTERVAL = 4,
cv::IMWRITE_JPEG_LUMA_QUALITY = 5,
cv::IMWRITE_JPEG_CHROMA_QUALITY = 6,
cv::IMWRITE_PNG_COMPRESSION = 16,
cv::IMWRITE_PNG_STRATEGY = 17,
cv::IMWRITE_PNG_BILEVEL = 18,
cv::IMWRITE_PXM_BINARY = 32,
cv::IMWRITE_EXR_TYPE = (3 <<4) + 0,
cv::IMWRITE_WEBP_QUALITY = 64,
cv::IMWRITE_PAM_TUPLETYPE = 128,
cv::IMWRITE_TIFF_RESUNIT = 256,
cv::IMWRITE_TIFF_XDPI = 257,
cv::IMWRITE_TIFF_YDPI = 258,
cv::IMWRITE_TIFF_COMPRESSION = 259,
cv::IMWRITE_JPEG2000_COMPRESSION_X1000 = 272
cv::WINDOW_NORMAL = 0x00000000,
cv::WINDOW_AUTOSIZE = 0x00000001,
cv::WINDOW_OPENGL = 0x00001000,
cv::WINDOW_FULLSCREEN = 1,
cv::WINDOW_FREERATIO = 0x00000100,
cv::WINDOW_KEEPRATIO = 0x00000000,
cv::WINDOW_GUI_EXPANDED =0x00000000,
cv::WINDOW_GUI_NORMAL = 0x00000010