opencv3以后都是32位_OpenCV3学习笔记(1)

fb76be40022ea788bc5a1cea7038e847.png

OpenCV3学习笔记(1)

1. 版本

OpenCV Version 3.4.5 CMake Version 3.6.3 MinGW Version x86_64-8.1.0-release-posix-seh-rt_v6-rev0 Clion Version 2018.2.2

2. 图像读入与输出

2.1 命名空间与Mat类

OpenCV的所有类和函数都声明在命名空间cv,所以代码开头加上using namespace cv可以方便的使用其中的各种类和函数。否则的话,在使用前还需要加上cv::这样的领域限定符。

OpenCV中的图像都存储在其的Mat类的对象中,可以认为Mat就是一个矩阵,存储图像个像素的信息。

2.2 图像的载入

图像的载入只需要一行代码

Mat scrImage = imread(string fileName, int flag=1)

其中第二个参数flag默认是1,表示读入的方式,flag不同表示不同种的读入方式。通过查看源代码imgcodecs.hpp,其中的ImreadModes枚举类型如下。

enum ImreadModes {
    IMREAD_UNCHANGED            = -1,   // 原始图像
    IMREAD_GRAYSCALE            = 0,    // 单通道灰度值
    IMREAD_COLOR                = 1,    // 3通道RGB图
    IMREAD_ANYDEPTH             = 2,    // 当图片深度足够时转换为16/32位深度图片,否则为8位深度图片
    IMREAD_ANYCOLOR             = 4,    // 以任何可能的颜色读取图像
    IMREAD_REDUCED_GRAYSCALE_2  = 16,   // 转换为单通道灰度值并将图片尺寸缩小到原来1/2
    IMREAD_REDUCED_COLOR_2      = 17,   // 转换为3通道RGB图片并将图片尺寸缩小到原来的1/2
    IMREAD_REDUCED_GRAYSCALE_4  = 32,   // 转换为单通道灰度值并将图片尺寸缩小到原来1/4
    IMREAD_REDUCED_COLOR_4      = 33,   // 转换为3通道RGB图片并将图片尺寸缩小到原来的1/4
    IMREAD_REDUCED_GRAYSCALE_8  = 64,   // 转换为单通道灰度值并将图片尺寸缩小到原来1/8
    IMREAD_REDUCED_COLOR_8      = 65,   // 转换为3通道RGB图片并将图片尺寸缩小到原来的1/8
    IMREAD_IGNORE_ORIENTATION   = 128,  // 忽略EXIF的旋转标志
    };

其中最长用的还属flag=-1,flag=0,flag=1这三种,当图片过大的时候,可以选择适当比例缩放。效果如图1.1所示。

abe127a2df05a0c47dd24f4311161e03.png

2.3 图像的输出

OpenCV中图像输出一般使用imwirte函数,声明如下

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

filename为文件名,img为要保存的图像变量,params为保存的参数。 可以看到img的格式要求是InputArray类型的,一般我们传入Mat类的变量即可。InputArray和Mat类的关系有必要说明一下。

首先在官方文档中,可以看到

typedef const _InputArray& cv::InputArray

也就是_InputArrayInputArray没有什么区别,带下划线的是其引用类型。对InputArray的定义是// Proxy datatype for passing Mat's and vector<>'s as input parameters class _InputArray。 当我们查看_InputArray可以看到。其中有个参数为Mat的构造函数,这也就解释的通为什么参数是InputArray时,传入Mat类型的变量是可以的了。

class CV_EXPORTS _InputArray
{
......
    _InputArray();
    _InputArray(const Mat& m); // 构造函数
......
};
......
_InputArray::_InputArray(const Mat& m) : flags(MAT), obj((void*)&m) {}

第三个参数params,一般情况下可以忽略不写,具体介绍可以参见官方文档。

2.4 代码示例

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main() {
    Mat srcImage1 = imread("data.jpg", -1);
    Mat srcImage2 = imread("data.jpg", 0);
    Mat srcImage3 = imread("data.jpg", 1);
    if(!srcImage1.empty()) imshow("Image1", srcImage1);
    else {
        cout << "scrImage is empty! Please check your image dir!" << endl;
        return -1;
    }

    if(!srcImage2.empty()) imshow("Image2", srcImage2);
    else {
        cout << "scrImage is empty! Please check your image dir!" << endl;
        return -1;
    }

    if(!srcImage3.empty()) imshow("Image3", srcImage3);
    else {
        cout << "scrImave is empty! Please check your image dir!" << endl;
    }

    imwrite("dst1.jpg", srcImage1);
    imwrite("dst2.jpg", srcImage2);
    imwrite("dst3.jpg", srcImage3);

    waitKey();
    return 0;
}

3. 窗口组件的创建

3.1 窗口的创建

窗口的创建需要用到namedWindow()函数。当然在使用imshow()函数的时候,OpenCV会自动创建一个窗口。所以如果只是简单的显示图面,直接调用imshow()函数即可,没有必要先创建窗口,再显示图片。nameWindow()的定义如下

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

第一个参数为窗口的名称,第二个参数为标志位,默认为自动大小。在官方文档中,给出了一系列的参数,如下所示。

enum WindowFlags {
       WINDOW_NORMAL     = 0x00000000, // 可以自由更改窗口大小(可拖拽)
       WINDOW_AUTOSIZE   = 0x00000001, // 窗口大小由图片决定,不可自由更改
       WINDOW_OPENGL     = 0x00001000, // OpenGL支持的窗口

       WINDOW_FULLSCREEN = 1,          // 全屏
       WINDOW_FREERATIO  = 0x00000100, // 最大化,不受图片的纵横比影响
       WINDOW_KEEPRATIO  = 0x00000000, // 图片纵横比保持不变
       WINDOW_GUI_EXPANDED=0x00000000, // 带状态栏和工具栏
       WINDOW_GUI_NORMAL = 0x00000010, // 旧式窗口形式
    };

这些参数可以根据实际需要进行选择。

3.2 滑动条的创建

在实际的时候,可能经常需要调整成参数,如果使用修改代码再编译运行的方式,会十分繁琐。一个简单的方式是创建一个滑动条,使用滑动条动态修改参数,实时预览。

滑动条创建需要两部分,一部分使用滑动条创建函数创建滑动条,另一部分设置滑动条的回调函数。 创建滑动条需要使用createTrackbar()函数。函数原型如下。

int createTrackbar  ( const String & trackbarname,const String & winname, int * value, int  count, TrackbarCallback onChange = 0,void * userdata = 0 )

第一个参数trackbarname为滑动条的名字; 第二个参数winname为窗口的名字; 第三个参数value指针为int型的指针,表示滑动条创建时的初始值,在移动滑动条的过程中也会改变这个值; 第四个参数count为滑动条的最大值; 第五个参数onchange为滑动条的回调函数,回调函数即在改变滑动条的值后会执行何种操作; 第六个参数userdata是用户的其他类型数据,即在回调函数中,还需要什么参数。

在创建滑动条的时候,会默认创建到窗口的最上方,如果有多个,根据窗口宽度选择向右平铺还是向下平铺。 创建完滑动条后,可以就要编写滑动条的回调函数了,回调函数是一个必须以int类型作为第一个参数, void*类型作为第二个参数的函数,分别对应滑动条创建过程中的第三个参数和第六个参数。如:

namedWindow("TrackBarTest");
createTrackbar("TrackBar1", "TrackBarTest", &initPosition1, 10, moveOnTrackBar1, &initPosition2);
void moveOnTrackBar1(int value , void * otherValue) {
    int * pOtherValue = (int*)otherValue;
    cout << "TrackBar1: " << value << " " << (*pOtherValue) << endl;
}

3.3 代码示例

e9b8382fe2db82b5d7365fa31a13f9ab.png
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

void moveOnTrackBar1(int value , void * otherValue) {
    int * pOtherValue = (int*)otherValue;
    cout << "TrackBar1: " << value << " " << (*pOtherValue) << endl;
}

void moveOnTrackBar2(int value, void * otherValue) {
    int * pOtherValue = (int*)otherValue;
    cout << "TrackBar2: " << value << " " << (*pOtherValue) << endl;
}

int main() {

    int initPosition1 = 0, initPosition2 = 0;
    namedWindow("TrackBarTest", WINDOW_AUTOSIZE);
    Mat srcImage = imread("data.jpg");
    imshow("TrackBarTest", srcImage);
    createTrackbar("TrackBar1", "TrackBarTest", &initPosition1, 5, moveOnTrackBar1, &initPosition2);
    createTrackbar("TrackBar2", "TrackBarTest", &initPosition2, 5, moveOnTrackBar2, &initPosition1);

    waitKey();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值