• open CV对图像的各类操作


    本文章用于记录自己使用open CV过程中的要点,便于遗忘时查看。

    首先使用

        using namespace std;
        using namespace cv;

    避免每次都需要敲 ::cv及::std;
    图像的读写显示存取

    图像定义:

    Mat image;


    图像读取:

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

        支持格式有:

        Windows bitmaps - *.bmp, *.dib (always supported)
        JPEG files - *.jpeg, *.jpg, *.jpe (see the Notes section)
        JPEG 2000 files - *.jp2 (see the Notes section)
        Portable Network Graphics - *.png (see the Notes section)
        WebP - *.webp (see the Notes section)
        Portable image format - *.pbm, *.pgm, *.ppm *.pxm, *.pnm (always supported)
        Sun rasters - *.sr, *.ras (always supported)
        TIFF files - *.tiff, *.tif (see the Notes section)
        OpenEXR Image files - *.exr (see the Notes section)
        Radiance HDR - *.hdr, *.pic (always supported)
        Raster and Vector geospatial data supported by Gdal (see the Notes section)

        读取方式有:

        IMREAD_UNCHANGED                                        按照图片原格式读入.
        IMREAD_GRAYSCALE                                         将图片转为单通道灰色图.
        IMREAD_COLOR                                                 将图片转为BGR3通道 .
        IMREAD_ANYDEPTH                                           如果图片是16-bit/32-bit ,则保持不变,其他的都转为8-bit.
        IMREAD_ANYCOLOR                                          图像以任何可能的颜色格式读取.
        IMREAD_LOAD_GDAL                                        使用GDAL载入图像.
        IMREAD_REDUCED_GRAYSCALE_2                  将图片转为单通道灰色图,同时将图片尺寸裁剪到 1/2.
        IMREAD_REDUCED_COLOR_2                          将图片转为BGR 3通道,同时将图片尺寸裁剪到 1/2.
        IMREAD_REDUCED_GRAYSCALE_4                  将图片转为单通道灰色图,同时将图片尺寸裁剪到  1/4.
        IMREAD_REDUCED_COLOR_4                          将图片转为BGR 3通道,同时将图片尺寸裁剪到 1/4.
        IMREAD_REDUCED_GRAYSCALE_8                  将图片转为单通道灰色图,同时将图片尺寸裁剪到 1/8.
        IMREAD_REDUCED_COLOR_8                          将图片转为BGR 3通道,同时将图片尺寸裁剪到 1/8.
        IMREAD_IGNORE_ORIENTATION                        如果设置,不旋转图像根据EXIF的定位标志

    显示图像:

    imshow(const String & winname, InputArray mat);

    显示窗口:

    namedWindow(const String & winname,int flags = WINDOW_AUTOSIZE)  

        WINDOW_NORMAL设置了这个值,用户便可以改变窗口的大小
        WINDOW_AUTOSIZE如果设置了这个值,窗口大小会自动调整以适应所显示的图像,并且不能手动改变窗口大小。
        WINDOW_OPENGL 如果设置了这个值的话,窗口创建的时候便会支持OpenGL。

    waitKey(int delay = 0)

    这个函数用来等待,读取和处理事件。当我们没有输入,只需要窗口停留,就可以将参数设为0。

    图像保存:

    imwrite(const String & filename InputArray img, const vector< int > & params = vector< int >())  

    图像缩放、旋转、截取、叠加

    缩放:

    resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )

    InputArray src     -原图像
    OutputArray dst    -输出图像
    Size dsize         -目标图像的大小
    double fx=0        -在x轴上的缩放比例
    double fy=0        -在y轴上的缩放比例
    int interpolation  -插值方式,有以下四种方式
        INTER_NN      -最近邻插值
        INTER_LINEAR  -双线性插值 (缺省使用)
        INTER_AREA    -使用象素关系重采样,当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 INTER_NN 方法。
        INTER_CUBIC   -立方插值。

    dsize与(fx,fy)不能同时为0

    旋转:

        Mat rotMat;Point rotCenter = Point(x,y);    //    x,y为旋转中心坐标
        rotMat = getRotationMatrix2D(Point2f center, double angle, double scale);//获取旋转矩阵,angle为逆时针;scale为缩放比例.
        warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar());

    根据getAffineTransform或getRotationMatrix2D得到的变换矩阵,计算变换后的图像。

    src为输入图像

    dst为变换后图像,类型与src一致。
    M为变换矩阵,需要通过其它函数获得,当然也可以手动输入。
    dsize为输出图像的大小

    flags,插值算法,详细如下:

        INTER_NEAREST        = 0,  //最近邻插值  
        INTER_LINEAR         = 1, //双线性插值  
        INTER_CUBIC          = 2, //双三次插值  
        INTER_AREA           = 3, //区域插值,使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。
        INTER_LANCZOS4       = 4, //Lanczos插值(超过8×8像素邻域的Lanczos插值)
        INTER_MAX            = 7,  
        WARP_FILL_OUTLIERS   = 8, //填充所有输出图像的象素  
        WARP_INVERSE_MAP     = 16  //逆变换

    borderMode为边界处理方式:

        BORDER_CONSTANT    = 0, //!< `iiiiii|abcdefgh|iiiiiii`  with some specified `i`  
        BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`  
        BORDER_REFLECT     = 2, //!< `fedcba|abcdefgh|hgfedcb`  
        BORDER_WRAP        = 3, //!< `cdefgh|abcdefgh|abcdefg`  
        BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`  
        BORDER_TRANSPARENT = 5, //!< `uvwxyz|absdefgh|ijklmno`  
        BORDER_REFLECT101  = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101  
        BORDER_DEFAULT     = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101  

        BORDER_ISOLATED    = 16 //!< do not look outside of ROI  

    截取:

        Mat imageROI;
        imageROI = image(Rect(100, 100, 400, 400));

    或者用:

    imageROI = image(Range(100, 400),Range(100, 400));

    叠加:

    addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);

    公式为: dst = src1*alpha + src2*beta + gamma;

    注意:图像大小必须一致。如果不一致,可以用ROI方法:

    首先在原图中取出需要添加的位置图像:

    imageROI = image(Rect(200, 200, image_to_add.cols, image_to_add.rows));

    然后将需要添加的图像融合:

    addWeighted(image_to_add, 0.8, imageROI, 0.1, 0., imageROI);

    这样需要叠加的图像 image_to_add 就添加到imageROI区域了。
    直方图、梯度、滤波

    直方图:
            参考:点击打开链接

    sobel算子计算梯度:

            参考:点击打开链接

    直方图均衡:

        equalizeHist(InputArray src,
                     OutputArray dst
        );

    中值滤波:

        blur(InputArray src,
             OutputArray dst,
             Size ksize,
             Point anchor = Point(-1,-1),
             int borderType = BORDER_DEFAULT
        );

    高斯滤波:

        GaussianBlur(InputArray src,
                     OutputArray dst,
                     Size ksize,
                     double sigmaX,
                     double sigmaY = 0,
                     int borderType = BORDER_DEFAULT
        );

    双边滤波:

        bilateralFilter(InputArray src,
                        OutputArray dst,
                        int d,
                        double sigmaColor,
                        double sigmaSpace,
                        int borderType = BORDER_DEFAULT
        );

    方框滤波:

        boxFilter(InputArray src,
                  OutputArray dst,
                  int ddepth,
                  Size ksize,
                  Point anchor = Point(-1,-1),
                  bool normalize = true,
                  int borderType = BORDER_DEFAULT
        );


    颜色空间转换

    参考:点击打开链接

    边缘、轮廓

    用Sobel计算边缘

     假定输入图像矩阵为 I,卷积核大小为 3x3,则水平一阶导数 Gx 和垂直一阶导数 Gy 分别为:

      OpenCV 中,Sobel 函数如下:

        void cv::Sobel   (     
            InputArray  src,    // 输入图像
            OutputArray  dst,   // 输出图像
            int      ddepth,    // 输出图像深度,-1 表示等于 src.depth()
            int      dx,        // 水平方向的阶数
            int      dy,        // 垂直方向的阶数
            int     ksize = 3,    // 卷积核的大小,常取 1, 3, 5, 7 等奇数
            double  scale = 1,    // 缩放因子,应用于计算结果
            double  delta = 0,    // 增量数值,应用于计算结果
            int borderType = BORDER_DEFAULT // 边界模式
        );

    用Scharr卷积核计算:

    当卷积核大小为 3x3 时,使用 sobel 卷积核来计算并不是很精确,此时常用 Scharr 卷积核来代替,如下:

      而 Sharr 函数,本质上就是令 ksize = 3 且使用 Scharr 卷积核的 Sobel 函数。

        void cv::Scharr (     
            InputArray  src,    
            OutputArray  dst,    
            int      ddepth,    
            int      dx,        
            int      dy,        
            double  scale = 1,
            double  delta = 0,
            int     borderType = BORDER_DEFAULT        
        );

      对于 Scharr 函数,要求 dx 和 dy 都 >= 0 且 dx + dy == 1,假如 dx 和 dy 都设为 1,则会抛出异常。

      因此,对于 Sobel 和 Scharr 函数,通常各自求其 x 和 y 方向的导数,然后通过加权来进行边缘检测。

    用 Laplace算子计算:

        void cv::Laplacian (     
            InputArray     src,
            OutputArray    dst,
            int       ddepth,
            int       ksize = 1,
            double    scale = 1,
            double    delta = 0,
            int       borderType = BORDER_DEFAULT
        );

    用Canny算子计算:

    Canny 边缘检测算子,其算法步骤大体如下:

    1) 用高斯滤波器对输入图像做平滑处理 (大小为 5x5 的高斯核)

    2) 计算图像的梯度强度和角度方向 ( x 和 y 方向上的卷积核)

      角度方向近似为四个可能值,即 0, 45, 90, 135

    3) 对图像的梯度强度进行非极大抑制

       可看做边缘细化:只有候选边缘点被保留,其余的点被移除

    4) 利用双阈值检测和连接边缘

        若候选边缘点大于上阈值,则被保留;小于下阈值,则被舍弃;处于二者之间,须视其所连接的像素点,大于上阈值则被保留,反之舍弃

        void cv::Canny (     
            InputArray    image,    // 输入图像 (8位)
            OutputArray   edges,    // 输出图像 (单通道,8位)
            double      threshold1,  // 下阈值
            double      threshold2,  // 上阈值
            int         apertureSize = 3,
            bool        L2gradient = false
        );

    找出轮廓直线:

        HoughLines( InputArray image,
                    OutputArray lines,//line[i][0]为半径,line[i][1]为角度.定义用    vector<Vec2f> lines;
                    double rho,//半径
                    double theta,//角度
                    int threshold,
                    double srn = 0,
                    double stn = 0,
                    double min_theta = 0,
                    double max_theta = CV_PI
        );

    例子参考:
            Houghlines找出轮廓直线

    找出闭合轮廓:

        findContours(InputOutputArray image,
                    OutputArrayOfArrays contours,//    vector<vector<Point>> contours;
                    OutputArray hierarchy,//    vector<Vec4i> hierarchy
                    int mode,    //    CV_RETR_EXTERNAL只检测最外围轮廓
                                 //    CV_RETR_LIST   检测所有的轮廓,无等级
                                 //    CV_RETR_CCOMP  检测所有的轮廓,但所有轮廓只建立两个等级关系
                                 //    CV_RETR_TREE, 检测所有轮廓,所有轮廓建立一个等级树结构
                    int method,    //    CV_CHAIN_APPROX_NONE 保存物体边界上所有连续的轮廓点到contours向量内
                                   //    CV_CHAIN_APPROX_SIMPLE 仅保存轮廓的拐点信息
                                   //    CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS
                    Point offset = Point()
    ————————————————
    版权声明:本文为CSDN博主「benedict_tao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/benedict_tao/article/details/79871150

  • 相关阅读:
    命令别名与历史命令
    Shell的变量功能
    Shell的变量功能
    认识BASH这个Shell
    vim程序编辑器
    其他vim使用注意事项
    vim的额外功能
    六、集合
    五、字典
    四、列表 元组
  • 原文地址:https://www.cnblogs.com/lykbk/p/13073634.html
Copyright © 2020-2023  润新知