OpenCV各模块函数使用实例(3 基本输入输出和色彩变换)

本节主要翻译自OpenCV的帮助资料,并结合一些编程考量。

         D、基本输入输出函数

  • imread(fln),imwrite(fln,img);

函数原型:

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

从文件中装入图像

函数imread从指定的文件中加载图像并返回一个Mat类型的图像对象。如果加载失败(由于文件错,不合适的权限,不支持或不可用的格式),这个函数返回空矩阵( Mat::data==NULL )。

       当前版本的openCV中这个函数支持下列格式的图像文件:

  • Windows 位图 - *.bmp, *.dib (总是支持的格式)
  • JPEG 文件 - *.jpeg, *.jpg, *.jpe(见注释节)
  • JPEG 2000 文件 - *.jp2 (见注释节)
  • 便携网络图文件 - *.png (见注释节)
  • WebP - *.webp (见注释节)
  • 便携图像格式 - *.pbm, *.pgm, *.ppm *.pxm, *.pnm (总是支持的格式)
  • PFM 文件 - *.pfm (见注释节)
  • Sun光栅文件 - *.sr, *.ras (总是支持的格式)
  • TIFF 文件 - *.tiff, *.tif (见注释节)
  • OpenEXR 图像文件 - *.exr (见注释节)
  • 辐射HDR - *.hdr, *.pic (总是支持的格式)
  • 由GDAL所支持的光栅和向量几何数据(见注释节)

注释

  • 这个函数通过内容确定图像类型,而不是通过文件的扩展名。
  • 在彩色图像中解码图像使用B G R 顺序存储图像的彩色通道。
  • 在使用IMREAD_GRAYSCALE图像标志时,也可能使用编解码器内部的灰度转换,此时的结果可能与cvtColor()的输出不一样。
  • 在微软的Windows OS 和MacOSX*下,编解码器默认使用附带的OpenCV图像(libjpeg, libpng, libtiff, and libjasper)库。所以OpenCV 总是能读取JPEGs, PNGs, 和TIFFs。在MacOSX下,还可以允许选择MacOSX原生的图像读取器。但是要当心,到现在为止,这些原生的图像加载器获得的图像具有不同的像素值,这是因为嵌入到MacOSX内的色彩管理操作是有差异的。
  • 对于Linux,BSD风格和其它类Unix的开源操作系统,OpenCV查找操作系统支持的图像编解码器。一定要记得安装相关的包(不要忘了这些开发文件,如,"libjpeg-dev",在Debian 和Ubuntu中)以便获得编解码的支持或者在CMake中打开OPENCV_BUILD_3RDPARTY_LIBS标志开关。
  • 在CMake设置WITH_GDAL 标志为true,且使用IMREAD_LOAD_GDAL 来加载图像时,GDAL 驱动器将用于解码图像,支持: RasterVector格式。
  • 如果EXIF信息嵌入到图像文件中,就要考虑EXIF的朝向,因而,图像将依据EXIF进行旋转,除非传输了IMREAD_IGNORE_ORIENTATION 或 IMREAD_UNCHANGED 标志。
  • 使用IMREAD_UNCHANGED 标志来保持PFM图像的浮点值。
  • 默认情况下像素数必需小于2^30。这个限制可以使用OPENCV_IO_MAX_IMAGE_PIXELS进行设置。

参数

filename

装入的文件名。

flags

标志,可以取值于cv::ImreadModes

 

 

cv::ImreadModes { cv::IMREAD_UNCHANGED = -1,
                   cv::IMREAD_GRAYSCALE = 0,
                   cv::IMREAD_COLOR = 1,
                   cv::IMREAD_ANYDEPTH = 2,
                   cv::IMREAD_ANYCOLOR = 4,
                   cv::IMREAD_LOAD_GDAL = 8,
                   cv::IMREAD_REDUCED_GRAYSCALE_2 = 16,
                   cv::IMREAD_REDUCED_COLOR_2 = 17,
                   cv::IMREAD_REDUCED_GRAYSCALE_4 = 32,
                   cv::IMREAD_REDUCED_COLOR_4 = 33,
                   cv::IMREAD_REDUCED_GRAYSCALE_8 = 64,
                   cv::IMREAD_REDUCED_COLOR_8 = 65,
                   cv::IMREAD_IGNORE_ORIENTATION = 128
}

 

 

 

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 imgconst std::vector<int> & params=std::vector< int >());

保存图像到指定的文件。

函数imwrite()保存图像到指定的文件。图像格式以选择的文件名扩展为准(参见cv::imread中文件名扩展的列表)。一般而言,只有8位单通道或3通道(BGR通道顺序)图像可以使用这个函数保存,除此之外还可以有:

  • 16位无符号(CV_16U)图像可以存储成PNG,JPEG 2000,和TIFF格式
  • 32位浮点(CV_32F)图像可以存储成PFM,TIFF,OpenEXR,和辐射HDR格式;3通道(CV_32FC3) TIFF 图像则存储成LogLuv高动态变幅编码(每像素4字节)格式。
  • 具有alpha 通道的PNG图像可以使用这个函数存储。此时可建立8位(或16位) 4通道图像BGRA,其中alpha通道排在最后。完全透明的像素的alpha设置到0,完全不透明像素的alpha设置到255/65535(参见下面的示例代码)。

如果格式的深度或通道顺序不同,需使用 Mat::convertTo 和 cv::cvtColor 在保存之前进行转换。也可通过FileStorage I/O 函数保存图像到XML 或 YAML 格式。

下面的示例给出建立BGRA 图像并存储成PNG 文件的例子。 它还展示了怎样设置图像的压缩参数:

#include <opencv2/imgcodecs.hpp>

using namespace cv;

using namespace std;

static void createAlphaMat(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; // 蓝

            bgra[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); // 绿

            bgra[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // 红

            bgra[3] = saturate_cast<uchar>(0.5 * (bgra[1] + bgra[2])); // Alpha

       }

   }

}

int main()

{

    //建立具有alpha通道的矩阵

    Mat mat(480, 640, CV_8UC4);

    createAlphaMat(mat);

    vector<int> compression_params;

    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 {
  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

}

 

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。

 

  • cv::imshow (const String &winname, InputArray mat);

在指定窗口中显示图像。

函数imshow()在指定窗口中显示图像。如果窗口使用cv::WINDOW_AUTOSIZE标志建立,图像将以其初始的尺寸显示,此时,图像将受到屏幕分辨率的限制。反之图像将以适合窗口大小的尺寸压缩显示。这个函数可以使用相关的深度标识图像。

  • 如果图像为8位无符号,它就被实际显示(无任何转换)
  • 如果图像为16位无符号或32位整数,像素被256除。即,值范围在[0,255*256]被映射到[0,255]。
  • 如果图像为32位或64位浮点数,像素值乘以255。即,值范围在[0,1]被映射到[0,255]。

如果窗口是以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

要显示的图像数据。

 

  • cv::namedWindow (const String &winname, int flags=WINDOW_AUTOSIZE);

建立窗口(并在openCV窗口管理中注册窗口,可用窗口名进行检索)

函数namedWindow()建立一个用于图像或跟踪条显示的占位窗口(原始窗口)。所建立的窗口可由窗口名加以引用。如果存在同名窗口,这个函数不做任何操作。

可以调用 cv::destroyWindow 或 cv::destroyAllWindows 来关闭窗口和释放任何相关的内存。为简化程序,并不要求必需调用这些函数,因为应用的所有资源和窗口都在退出时由操作系统自动关闭和释放。

注意

Qt 环境支持的附加标志:

  • WINDOW_NORMAL WINDOW_AUTOSIZE: WINDOW_NORMAL 允许改变窗口尺寸,而WINDOW_AUTOSIZE 自动调节窗口尺寸到适合显示的图像尺寸(见imshow),并且不能手动改变窗口尺寸。
  • WINDOW_FREERATIO WINDOW_KEEPRATIO: WINDOW_FREERATIO 不依据图像比例调节图像,而WINDOW_KEEPRATIO保持图像比例。
  • WINDOW_GUI_NORMALWINDOW_GUI_EXPANDED: WINDOW_GUI_NORMAL使用旧风格画不带状态条和工具条的窗口,而WINDOW_GUI_EXPANDED是新风格的GUI界面。默认,flags== WINDOW_AUTOSIZE | WINDOW_KEEPRATIO | WINDOW_GUI_EXPANDED。

参数

winname

窗口标题上的窗口名,可用作窗口标识。

flags

窗口标志。支持的标志是:(cv::WindowFlags)

 

 

cv::WindowFlags {
 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

}

 

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

  • void cv::cvtColor (InputArray src, OutputArray dst, int code, int dstCn=0)

转换图像从一种彩色空间到另一种彩色空间。

这个函数转换图像从一种彩色空间到另一种彩色空间。在转换RGB彩色空间时,应显式地指定通道顺序(RGB 或 BGR)。注意在openCV中默认的彩色格式通常不同于RGB顺序,而是BGR (字节是颠倒的,Intel CPU是低字节在前)。所以在标准(24位)彩色图像中头一个字节应该是8位的蓝色分量,第二个字节是绿色,而第三个字节是红色。而后的第四,第五,和第六字节是下一个像素(蓝,然后绿,然后红)等等。

R,G,和B 通道值的转换范围是:

  • 0 to 255 为CV_8U 图像
  • 0 to 65535 为CV_16U 图像
  • 0 to 1 为CV_32F 图像

在线性变换时,范围并不重要。但是在非线性变换中,输入的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中导出。

 

  • void cv::cvtColorTwoPlane (InputArray src1, InputArray src2, OutputArray dst, int code)

转换图像从一种颜色空间到另一种颜色空间,此处的源图像存储在两个位面中。

这个函数现在仅支持YUV420 到 RGB 转换。

参数

src1

Y位面的8位图像(CV_8U)。

src2

包含交替U/V 位面的图像。

dst

输出图像。

code

指定转换类型。可以取值下面任何值:

  • COLOR_YUV2BGR_NV12
  • COLOR_YUV2RGB_NV12
  • COLOR_YUV2BGRA_NV12
  • COLOR_YUV2RGBA_NV12
  • COLOR_YUV2BGR_NV21
  • COLOR_YUV2RGB_NV21
  • COLOR_YUV2BGRA_NV21
  • COLOR_YUV2RGBA_NV21

 

  • void cv::demosaicing (InputArray src, OutputArray dst, int code, int dstCn=0)

所有去马赛克过程的主函数

参数

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

  • 使用alpha 通道去马赛克

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()函数做暂停。

以后的所有示例和函数调用都是以这种形式进行,通过主菜单选择功能,对话框获取参数,对图像对象进行操作。这样的展示适合图像的对比和操作结果的显示。

上一篇:opencv_python 读取4通道png图片


下一篇:用python读取tif格式图像,opencv读取