opencv02-image loading, displaying, modifying and saving

opencv01-image loading, displaying, modifying and saving

image loading

Method definition:

// filename 要加载的文件名
// flags 标识,参考cv::ImreadModes
CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );

Explanation of the method:

  1. Load the image from the specified file and return
  2. If the file cannot be read (because the file does not exist, does not have appropriate permissions, or has an invalid file format), return an empty matrix, ie Mat::data==NULL
  3. There are many supported file formats: bitmaps, JPEG, TIFF, png

Precautions:

  1. The method determines the type of image, not by the file extension

  2. If it is color images, then the channel order of images stored after decoding is: BGR

  3. 当使用 IMREAD_GRAYSCALE,那么the codec’s internal grayscale conversion will be used, if available

  4. The result may be different from cvtColor()

  5. 在Windows系统和MacOSX上,the codecs shipped with an OpenCV image (libjpeg,libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs,and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware that currently these native image loaders give images with different pixel values because of the color management embedded into MacOSX.

  6. On Linux, BSD flavors and other Unix-like open source operating systems, OpenCV looks for codecs provided by the operating system mirror, by installing the relevant packages (don't forget the development files, for example: "libjpeg-dev" in Debian or Ubuntu systems ) to get codec support, or turn on OPENCV_BUILD_3RDPARTY_LIBSflags in CMake

  7. In this case, set to true in CMake WITH_GDALand load the image settings IMREAD_LOAD_GDAL, then to decode the image, the [GDAL] driver will be used, supporting the following formats: [Raster] and [Vector]

  8. EXIFIf information is embedded in the image , then EXIFthe orientation of the image will also be taken into account, as the image will be rotated unless flags are set IMREAD_IGNORE_ORIENTATIONor IMREAD_UNCHANGEDparameters are passed

  9. Use IMREAD_UNCHANGEDthe flag bit to keep the image value in PFM format as a floating point type

  10. By default, the pixels of an image must be smaller than 2^30, and this limit can be OPENCV_IO_MAX_IMAGE_PIXELSset through system variables:

flags identification:

enum ImreadModes {
    
    
       IMREAD_UNCHANGED            = -1, //按原样加载图片(with alpha channel, otherwise it gets cropped). 忽略EXIF orientation.
       IMREAD_GRAYSCALE            = 0,  //总是转换图片为单通道的grayscale图片(codec 内转换).
       IMREAD_COLOR                = 1,  //总是转换图片为3通道的BGR彩色图片, 默认值
       IMREAD_ANYDEPTH             = 2,  //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
       IMREAD_ANYCOLOR             = 4,  //如果设置了,那么以任意可能的颜色格式读取图片
       IMREAD_LOAD_GDAL            = 8,  //如果设置了,那么使用gdal驱动加载图片
       IMREAD_REDUCED_GRAYSCALE_2  = 16, //总是转换图片为单通道的grayscale图片,图片size减少为1/2
       IMREAD_REDUCED_COLOR_2      = 17, //总是转换图片为3通道的BGR彩色图片,图片size减少为1/2
       IMREAD_REDUCED_GRAYSCALE_4  = 32, //总是转换图片为单通道的grayscale图片,图片size减少为1/4
       IMREAD_REDUCED_COLOR_4      = 33, //总是转换图片为3通道的BGR彩色图片,图片size减少为1/4
       IMREAD_REDUCED_GRAYSCALE_8  = 64, //总是转换图片为单通道的grayscale图片,图片size减少为1/8
       IMREAD_REDUCED_COLOR_8      = 65, // 总是转换图片为3通道的BGR彩色图片,图片size减少为1/8
       IMREAD_IGNORE_ORIENTATION   = 128 //不根据EXIF's orientation flag来旋转图片
     };

Create windows and image displays

Method definition:

// filename window的标题,可以用来作为window的标识符
// flags window的标识,The supported flags are: (cv::WindowFlags)
CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);

Explanation of the method:

  1. Create a window that can be used as a placeholder for images and trackbars
  2. If a window with the same name already exists, then this method does nothing
  3. You can use cv::destroyWindowor cv::destroyAllWindowsto close all windows and de-allocate any associated memory. For a simple program, there is no need to explicitly call these functions, because all resources and applications will be automatically closed when the operating system exits

Precautions:

  1. Additional flags supported by Qt
  • WINDOW_NORMAL or WINDOW_AUTOSIZE:WINDOW_NORMAL allows resizing the window, but WINDOW_AUTOSIZE automatically adjusts the size of the window to fit the size of the displayed image, and cannot manually adjust the size of the window
  • WINDOW_FREERATIO or WINDOW_KEEPRATIO:WINDOW_FREERATIO adjusts the size of the image regardless of the ratio, while WINDOW_KEEPRATIO keeps the ratio of the image
  • WINDOW_GUI_NORMAL or WINDOW_GUI_EXPANDED:WINDOW_GUI_NORMAL is the old way to draw a window without statusbar and toolbar, while WINDOW_GUI_EXPANDED is a new enhanced GUI
  1. By default, flags == WINDOW_AUTOSIZE | WINDOW_KEEPRATIO | WINDOW_GUI_EXPANDED

flags identification:

enum WindowFlags {
    
    
       WINDOW_NORMAL     = 0x00000000, //可以调整窗口大小
       WINDOW_AUTOSIZE   = 0x00000001, //不能调整窗口大小
       WINDOW_OPENGL     = 0x00001000, //opengl 支持的窗口,需要编译opencv的时候支持opengl

       WINDOW_FULLSCREEN = 1,          //!< change the window to fullscreen.
       WINDOW_FREERATIO  = 0x00000100, //!< the image expends as much as it can (no ratio constraint).
       WINDOW_KEEPRATIO  = 0x00000000, //!< the ratio of the image is respected.
       WINDOW_GUI_EXPANDED=0x00000000, //!< status bar and tool bar
       WINDOW_GUI_NORMAL = 0x00000010, //!< old fashious way
    };

Method definition:

// winname window的标识符
// mat 要显示的图片
CV_EXPORTS_W void imshow(const String& winname, InputArray mat);

Explanation of the method:

  1. The function will display the picture on the specified window. If the window is created using cv::WINDOW_AUTOSIZE, then the picture will show the original size, but it is still limited by the screen resolution. In other cases, the image fits the size of the window. This function will scale the picture, depending on the depth of the picture:
  • If the image is 8-bit unsigned, it will be displayed as it is
  • If the picture is 16-bit unsigned, then the pixel will be divided by 256, that is, the value range [0,255*256] is mapped to [0,255]
  • If the picture is 32-bit or 64-bit floating-point, then the pixel value will be multiplied by 255, that is, the value range [0,1] is mapped to [0,255]
  • 32-bit integer images will no longer be processed because the conversion required is ambiguous
  • Convert 8-bit unsigned matrix using custom preprocessing specific to image's context.
  • If a window supported by OpenGL is created, then cv::imshow also supports ogl::Buffer , ogl::Texture2D and cuda::GpuMat as input
  • If no window is created before this function call, a cv::WINDOW_AUTOSIZE window will be created
  • If you want to display a picture that exceeds the screen resolution, you need to call namedWindow("", WINDOW_NORMAL) before imshow

Precautions:

  1. Immediately after this function should be called cv::waitKeyor cv::pollKey, to perform the housekeeping tasks of the GUI,
    which is usually very necessary in order to display the given image and make the window wait for mouse and keyboard events. Otherwise, the picture will not be displayed and the window may be locked.
    For example: waitKey(0)the window will be displayed infinitely until any key is pressed (suitable for image display), waitKey(25)will display a frame, and wait for about 25ms (suitable for a frame-by-frame display video stream), call cv::destroyWindow to remove the window .
  2. [ Windows Backend Only ] Ctrl+C copy image to clipboard.
  3. [ Windows Backend Only ] Ctrl+S pops up the dialog box for saving pictures.
#include <iostream>
#include <opencv2/highgui/highgui.hpp>


using namespace std;
using namespace cv;

/**
 * 图像的加载,修改图像和保存图像
 *
 * @return
 */
int main() {
    
    
    string filename= "D:/workspace/cpp_workspace/my-cv/data/img/lena.jpg";
    Mat img = imread(filename, ImreadModes::IMREAD_COLOR);
    if (img.data == nullptr) {
    
    
        cout << "can not load image" << endl;
        return -1;
    }

    //cout << img << endl;

    namedWindow("test", WINDOW_AUTOSIZE);
    imshow("test", img);
    waitKey();
    return 0;
}

image modification

Method definition:

//将图像从一个色彩空间转换为另一个色彩空间
// @param src 输入图像:8 位无符号、16 位无符号 ( CV_16UC...) 或单精度浮点数。
// @param dst 与SRC大小和深度相同的输出图像。
// @param code 代码颜色空间转换代码(请参阅 #ColorConversionCodes)。
// @param dstCn 目标图像中的dstCn通道数;如果参数为 0,则通道是从 SRC 和代码自动推导出来
// 可以参考:imgproc_color_conversions
CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );

Explanation of the method:

  1. This function converts an input image from one color space to another. In case of conversion from to-from RGB color space, the order of the channels should be explicitly specified (RGB or BGR, note: the default color format in OpenCV is usually called RGB, but it is actually BGR (bytes reversed), Thus, the first byte in a standard (24-bit) color image will be the 8-bit blue component, the second byte will be green, and the third byte will be red. The fourth, fifth, and then, The sixth byte will be the second pixel (blue, then green, then red), etc. The
    normal ranges for R, G, and B channel values ​​are:
  • 0 to 255 means CV_8U image
  • 0 to 65535 means CV_16U image
  • 0 to 1 for a CV_32F image
    For linear transformations, the range does not matter. But when converting in the case of non-linearity, the input RGB image should be normalized to the appropriate value range to get the correct value result, eg: RGB -> Luv conversion, for example, if you have 32 bit floating point image directly from 8 bit If the image is converted without any scaling, it will have a value range of 0…255 instead of 0…1 as the function assumes. So cvtColoryou need to scale the image before calling:
img *= 1./255;
cvtColor(img, img, COLOR_BGR2Luv);
  1. If you use #cvtColor with 8-bit images, the conversion will lose some information. For many applications this will not be noticeable, but it is recommended to use 32-bit images in the application, which guarantees the full range of colors or in the Convert an image before an operation and convert it back after.

  2. If the conversion adds an alpha channel, its value will be set to the maximum value of the corresponding channel. Range: CV_8U is 255, CV_16U is 65535, CV_32F is 1.

Code example:

#include <opencv2/opencv.hpp>
int main() {
    
    
    string filename = "D:/workspace/cpp_workspace/my-cv/data/img/lena.jpg";
    Mat srcImage = imread(filename, ImreadModes::IMREAD_COLOR);
    Mat dstImage;
    cvtColor(srcImage, dstImage, COLOR_BGR2Lab);
    imshow("原图", srcImage);
    imshow("效果图", dstImage);

    waitKey(0);
    return 0;
}

image save

Method definition:

// 保存图片到指定的文件
// img 待保存的图片(一个或多个)(Mat or vector of Mat)
// params 用来设置对应图片格式的参数的,因为一般情况下这些图片格式都是经过了压缩的,这里就是设置这些压缩参数来控制图片的质量。该参数是一个vector<int>类型,里面分别存入paramId_1, paramValue_1, paramId_2, paramValue_2, ... 也就是说存入一对属性值。如果不设置该参数的话,则程序会自动根据所保存的图像格式采用一个默认的参数。参考: cv::ImwriteFlags
CV_EXPORTS_W bool imwrite( const String& filename, InputArray img,
              const std::vector<int>& params = std::vector<int>());

Explanation of the method:

  1. This function imwritesaves the picture to the specified file, and the format of the picture is based on the file extension (you can view the list of extensions). Usually, only 8-bit unsigned single-channel pictures (CV_8U) or 3-channel pictures (in 'BGR' channel order) can be saved by this function. There are also exceptions:

    • With OpenEXR encoder, only 32-bit floating point (CV_32F) images can be saved, not supported (CV_8U)

    • With the Radiance HDR encoder, non-64-bit floating point (CV_64F) images can be saved, all images will be converted to 32-bit floating point (CV_32F)

    • 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved using the JPEG 2000 encoder

    • With the PAM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved

    • With the PNG encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved, and this function can be used to save PNG images with an alpha channel. To do this, create

      • 8-bit (or 16-bit) 4-channel image BGRA with the alpha channel last. fully transparent pixels
      • 2 Alpha should be set to 0, fully opaque pixels should have Alpha set to 255/65535 (see code sample below).
    • 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved using the PGM/PPM encoder

    • 7 With TIFF encoder, 8-bit unsigned (CV_8U), 16-bit unsigned (CV_16U), can save 32-bit floating point (CV_32F) and 64-bit floating point (CV_64F) images. Multiple images (vectors of Mats) can be saved in TIFF format (see code example below). Will save 32-bit floating point 3-channel (CV_32FC3) TIFF image, encoded with LogLuv high dynamic range (4 bytes per pixel)

  2. If the image format is not supported, the image will be converted to 8-bit unsigned (CV_8U) and saved that way.

  3. If the format, depth or channel order is different, use Mat::convertToand cv::cvtColorconvert them before saving. Alternatively, use the common file storage I/O functions to save the image in XML or YAML format.

  4. The example below shows how to create a BGRA image, set custom compression parameters and save it to a PNG file. It also demonstrates how to save multiple images in a TIFF file:
    @include snippets/imgcodecs_imwrite.cpp

enum ImwriteFlags {
    
    
       IMWRITE_JPEG_QUALITY        = 1,  //!< For JPEG, it can be a quality from 0 to 100 (the higher is the better). Default value is 95.
       IMWRITE_JPEG_PROGRESSIVE    = 2,  //!< Enable JPEG features, 0 or 1, default is False.
       IMWRITE_JPEG_OPTIMIZE       = 3,  //!< Enable JPEG features, 0 or 1, default is False.
       IMWRITE_JPEG_RST_INTERVAL   = 4,  //!< JPEG restart interval, 0 - 65535, default is 0 - no restart.
       IMWRITE_JPEG_LUMA_QUALITY   = 5,  //!< Separate luma quality level, 0 - 100, default is -1 - don't use.
       IMWRITE_JPEG_CHROMA_QUALITY = 6,  //!< Separate chroma quality level, 0 - 100, default is -1 - don't use.
       IMWRITE_JPEG_SAMPLING_FACTOR = 7, //!< For JPEG, set sampling factor. See cv::ImwriteJPEGSamplingFactorParams.
       IMWRITE_PNG_COMPRESSION     = 16, // 针对PNG的压缩等级,值0 to 9,值越大,压缩之后图片越小,更长的压缩时间。如果指定了该参数,IMWRITE_PNG_STRATEGY应该修改为IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY),默认为1(最好的速度设置).
       IMWRITE_PNG_STRATEGY        = 17, //默认值为:IMWRITE_PNG_STRATEGY_RLE.
       IMWRITE_PNG_BILEVEL         = 18, //!< Binary level PNG, 0 or 1, default is 0.
       IMWRITE_PXM_BINARY          = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1.
       IMWRITE_EXR_TYPE            = (3 << 4) + 0, /* 48 */ //!< override EXR storage type (FLOAT (FP32) is default)
       IMWRITE_EXR_COMPRESSION     = (3 << 4) + 1, /* 49 */ //!< override EXR compression type (ZIP_COMPRESSION = 3 is default)
       IMWRITE_EXR_DWA_COMPRESSION_LEVEL = (3 << 4) + 2, /* 50 */ //!< override EXR DWA compression level (45 is default)
       IMWRITE_WEBP_QUALITY        = 64, //!< For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used.
       IMWRITE_HDR_COMPRESSION     = (5 << 4) + 0, /* 80 */ //!< specify HDR compression
       IMWRITE_PAM_TUPLETYPE       = 128,//!< For PAM, sets the TUPLETYPE field to the corresponding string value that is defined for the format
       IMWRITE_TIFF_RESUNIT        = 256,//!< For TIFF, use to specify which DPI resolution unit to set; see libtiff documentation for valid values
       IMWRITE_TIFF_XDPI           = 257,//!< For TIFF, use to specify the X direction DPI
       IMWRITE_TIFF_YDPI           = 258,//!< For TIFF, use to specify the Y direction DPI
       IMWRITE_TIFF_COMPRESSION    = 259,//!< For TIFF, use to specify the image compression scheme. See libtiff for integer constants corresponding to compression formats. Note, for images whose depth is CV_32F, only libtiff's SGILOG compression scheme is used. For other supported depths, the compression scheme can be specified by this flag; LZW compression is the default.
       IMWRITE_JPEG2000_COMPRESSION_X1000 = 272,//!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000.
       IMWRITE_AVIF_QUALITY        = 512,//!< For AVIF, it can be a quality between 0 and 100 (the higher the better). Default is 95.
       IMWRITE_AVIF_DEPTH          = 513,//!< For AVIF, it can be 8, 10 or 12. If >8, it is stored/read as CV_32F. Default is 8.
       IMWRITE_AVIF_SPEED          = 514 //!< For AVIF, it is between 0 (slowest) and (fastest). Default is 9.
     };

ImwritePNGFlags, PNG image format parameters:

//1. Imwrite 用于调整压缩算法的 PNG 特定标志。这些标志将修改 PNG 图像压缩的方式,并将传递到底层 zlib 处理阶段。
//2. IMWRITE_PNG_STRATEGY_FILTERED的效果是强制更多的霍夫曼编码和更少的字符串匹配;它介于IMWRITE_PNG_STRATEGY_DEFAULT和IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY之间。
//3. IMWRITE_PNG_STRATEGY_RLE 设计为几乎与 IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY 一样快,但为 PNG 图像数据提供更好的压缩。策略参数仅影响压缩比,而不影响压缩输出的正确性,即使设置不当也是如此。
//4. IMWRITE_PNG_STRATEGY_FIXED防止使用动态霍夫曼代码,允许为特殊应用提供更简单的解码器。
enum ImwritePNGFlags {
    
    
       IMWRITE_PNG_STRATEGY_DEFAULT      = 0, //!< Use this value for normal data.
       IMWRITE_PNG_STRATEGY_FILTERED     = 1, //!< Use this value for data produced by a filter (or predictor).Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better.
       IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY = 2, //!< Use this value to force Huffman encoding only (no string match).
       IMWRITE_PNG_STRATEGY_RLE          = 3, //!< Use this value to limit match distances to one (run-length encoding).
       IMWRITE_PNG_STRATEGY_FIXED        = 4  //!< Using this value prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.
     };

Code example:

int main() {
    
    
    string filename = "D:/workspace/cpp_workspace/my-cv/data/img/lena.jpg";
    Mat img = imread(filename, ImreadModes::IMREAD_COLOR);
    vector<int> params;
    params.push_back(IMWRITE_PNG_COMPRESSION);
    params.push_back(9);
    params.push_back(IMWRITE_PNG_STRATEGY);
    params.push_back(IMWRITE_PNG_STRATEGY_DEFAULT);
    
    imwrite(R"(D:\workspace\cpp_workspace\my-cv\1.png)", img);
    imwrite(R"(D:\workspace\cpp_workspace\my-cv\2.png)", img, params);
    return 0;
}

Remark:

1、RGB和BGR(opencv默认的彩色图像的颜色空间是BGR)颜色空间的转换

cv::COLOR_BGR2RGB
cv::COLOR_RGB2BGR
cv::COLOR_RGBA2BGRA
cv::COLOR_BGRA2RGBA

2、向RGB和BGR图像中增添alpha通道

cv::COLOR_RGB2RGBA
cv::COLOR_BGR2BGRA

3、从RGB和BGR图像中去除alpha通道

cv::COLOR_RGBA2RGB
cv::COLOR_BGRA2BGR

4、从RBG和BGR颜色空间转换到灰度空间

cv::COLOR_RGB2GRAY
cv::COLOR_BGR2GRAY

cv::COLOR_RGBA2GRAY
cv::COLOR_BGRA2GRAY

5、从灰度空间转换到RGB和BGR颜色空间

cv::COLOR_GRAY2RGB
cv::COLOR_GRAY2BGR

cv::COLOR_GRAY2RGBA
cv::COLOR_GRAY2BGRA

6、RGB和BGR颜色空间与BGR565颜色空间之间的转换

cv::COLOR_RGB2BGR565
cv::COLOR_BGR2BGR565
cv::COLOR_BGR5652RGB
cv::COLOR_BGR5652BGR
cv::COLOR_RGBA2BGR565
cv::COLOR_BGRA2BGR565
cv::COLOR_BGR5652RGBA
cv::COLOR_BGR5652BGRA

7、灰度空间域BGR565之间的转换

cv::COLOR_GRAY2BGR555
cv::COLOR_BGR5552GRAY

8、RGB和BGR颜色空间与CIE XYZ之间的转换

cv::COLOR_RGB2XYZ
cv::COLOR_BGR2XYZ
cv::COLOR_XYZ2RGB
cv::COLOR_XYZ2BGR

9、RGB和BGR颜色空间与uma色度(YCrCb空间)之间的转换

cv::COLOR_RGB2YCrCb
cv::COLOR_BGR2YCrCb
cv::COLOR_YCrCb2RGB
cv::COLOR_YCrCb2BGR

10、RGB和BGR颜色空间与HSV颜色空间之间的相互转换

cv::COLOR_RGB2HSV
cv::COLOR_BGR2HSV
cv::COLOR_HSV2RGB
cv::COLOR_HSV2BGR

11、RGB和BGR颜色空间与HLS颜色空间之间的相互转换

cv::COLOR_RGB2HLS
cv::COLOR_BGR2HLS
cv::COLOR_HLS2RGB
cv::COLOR_HLS2BGR

12、RGB和BGR颜色空间与CIE Lab颜色空间之间的相互转换

cv::COLOR_RGB2Lab
cv::COLOR_BGR2Lab
cv::COLOR_Lab2RGB
cv::COLOR_Lab2BGR

13、RGB和BGR颜色空间与CIE Luv颜色空间之间的相互转换

cv::COLOR_RGB2Luv
cv::COLOR_BGR2Luv
cv::COLOR_Luv2RGB
cv::COLOR_Luv2BGR

14、Bayer格式(raw data)向RGB或BGR颜色空间的转换

cv::COLOR_BayerBG2RGB
cv::COLOR_BayerGB2RGB
cv::COLOR_BayerRG2RGB
cv::COLOR_BayerGR2RGB
cv::COLOR_BayerBG2BGR
cv::COLOR_BayerGB2BGR
cv::COLOR_BayerRG2BGR
cv::COLOR_BayerGR2BGR

Guess you like

Origin blog.csdn.net/guo20082200/article/details/132017374