OpenCV开发笔记(八):OpenCV常用操作之计时、缩放、旋转、镜像

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/101168828
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)

OpenCV开发专栏(点击传送门)

上一篇:《OpenCV开发笔记(七):OpenCV基础图形绘制》

下一篇:《OpenCV开发笔记(九):OpenCV区域图像(ROI)和整体、局部图像混合》

 

前言

       图片浏览器的一些常规操作。

 

常用操作

       在OpenCV开发过程中用于测试性能计时的:计时(计算处理的时间)。

       在一般的图像处理中有的几个操作:缩放(放大、缩小),旋转(90度的倍数)、镜像(x轴反向、y轴反向)。

注意:意角度的旋转使用cv::Mat不太合适,开发过程中会用到其他ui框架,所以使用其他ui框架做旋转是比较合适的。

 

Demo

 

计时函数

       OpenCV提供了两个渐变的计时函数:getTickCount()和getTickFrequency()。

  • getTickCount():getTickCount()函数返回CPU自某个事件(如启动电脑)以来走过的时钟周期数。
  • getTickFrequency()getTickFrequency()函数返回CPU一秒钟所走的时钟周期数。

       测试结果如下:

OpenCV开发笔记(八):OpenCV常用操作之计时、缩放、旋转、镜像_第1张图片

       cv::getTickFrequency()获取的频率为10,000,000,得到cpu的周期为一千万次每秒。

 

访问图像中像素的三类方法

       cv::Mat访问的三类方法:

  • 方法一:at函数
  • 方法二:使用迭代器
  • 方法三:通过数据指针

       具体可查看:OpenCV开发笔记(三):OpenCV图像的概念和基本操作中的像素值的读写。

 

旋转(90度的整数倍)

       旋转90°的整数就是对矩阵位置进行变换,如下图:

OpenCV开发笔记(八):OpenCV常用操作之计时、缩放、旋转、镜像_第2张图片

旋转函数1:cv::transpose()

       该函数无任何函数,直接对矩阵进行顺时钟旋转90°,函数原型如下:

CV_EXPORTS_W void transpose(InputArray src, OutputArray dst);

旋转函数2:cv::rotate()

       该函数旋转函数,三个枚举可以旋转90°,180°,270°,逆时针旋转90°就是顺时钟270°,函数原型如下:

CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode);
  • 参数一:输入mat
  • 参数二:输出mat
  • 参数三:旋转枚举,如下:
enum RotateFlags {
    ROTATE_90_CLOCKWISE = 0,         //Rotate 90 degrees clockwise
    ROTATE_180 = 1,                   //Rotate 180 degrees clockwise
    ROTATE_90_COUNTERCLOCKWISE = 2, //Rotate 270 degrees clockwise
};

       代码示例:

cv::rotate(srcMat, srcMat, cv::ROTATE_90_CLOCKWISE);

 

镜像(x轴翻转,y轴翻转)

       镜像就是对X轴和Y轴的值翻转对调,如下图:

OpenCV开发笔记(八):OpenCV常用操作之计时、缩放、旋转、镜像_第3张图片

翻转函数:cv::flip

       该函数为翻转函数,函数圆形如下:

CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);
  • 参数一:输入mat
  • 参数二:输出mat
  • 参数三:只有3种值,小于0,等于0,大于0,分别对应xy轴翻转、x轴翻转、y轴翻转。

       代码示例:

cv::flip(srcMat, srcMat, 0);

 

缩放

缩放函数:cv::resize

       该函数为缩放函数,特别注意:函数缩放会失真,尤其是以缩放后的图像继续缩放会原来大小,所以笔者建议,缩放用缓存,缓存存放原图,每次以原图缩放。

       该函数原形如下:

CV_EXPORTS_W void resize( InputArray src, OutputArray dst,
                          Size dsize, double fx = 0, double fy = 0,
                          int interpolation = INTER_LINEAR );
  • 参数一:输入mat
  • 参数二:输出mat
  • 参数三:缩放后的大小
  • 参数四:x缩放比例,一般默认0就可以
  • 参数五:y缩放比例,一般默认0就可以
  • 参数六:差值,一般默认即可

       此处额外介绍下差值的枚举:

enum InterpolationFlags{
    INTER_NEAREST        = 0,	// 最临近差值
    INTER_LINEAR         = 1,   // 双线性差值
    INTER_CUBIC          = 2,   // 双立方差值
    INTER_AREA           = 3,
    INTER_LANCZOS4       = 4,  // 附近像素及原像素加权取值
    INTER_LINEAR_EXACT = 5,
    INTER_MAX            = 7,
    WARP_FILL_OUTLIERS   = 8,
    WARP_INVERSE_MAP     = 16
};

 

Demo源码

void OpenCVManager::testCommonOperate()
{
#define TEST_GET_TICK_COUNT (1)
#define TEST_ROTATE_90      (1)

#if TEST_GET_TICK_COUNT     // 测试计时函数
    for(int index = 0; index < 10; index++)
    {
        int64 tickCount = cv::getTickCount();
        qDebug() << __FUNCTION__ << __LINE__ << "===================== test cv::getTickCount(), now times:" << index;
        qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
        // Qt的线程睡眠函数
        QThread::msleep(200 * index);
        int64 tickCount2 = cv::getTickCount();
        qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
        int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
        qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickFrequency() =" << (int64)cv::getTickFrequency() << ", ms:" << ms;
    }
#endif

#if TEST_ROTATE_90
    cv::Mat srcMat;
    QString fileName = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
    srcMat = cv::imread(fileName.toStdString());
    if(!srcMat.data)
    {
        qDebug() << __FILE__ << __LINE__ << "Failed to load image:" << fileName;
        return;
    }
    cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
    float scaleStep = 0.05f;
    while(true)
    {
        int key = cv::waitKey();
        if(key == '1')          // 逆时钟旋转90度
        {
            int64 tickCount = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
            cv::rotate(srcMat, srcMat, cv::ROTATE_90_COUNTERCLOCKWISE);
            int64 tickCount2 = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
            int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
            qDebug() << __FUNCTION__ << __LINE__ << "take time ms:" << ms;
            cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
        }else if(key == '2')    // 顺时钟旋转90度
        {
            int64 tickCount = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
            cv::rotate(srcMat, srcMat, cv::ROTATE_90_CLOCKWISE);
            int64 tickCount2 = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
            int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
            qDebug() << __FUNCTION__ << __LINE__ << "take time ms:" << ms;
            cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
        }else if(key == '3')    // x轴翻转(镜像)
        {
            int64 tickCount = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
            cv::flip(srcMat, srcMat, 0);
            int64 tickCount2 = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
            int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
            qDebug() << __FUNCTION__ << __LINE__ << "take time ms:" << ms;
            cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
        }else if(key == '4')    // y轴翻转(镜像)
        {
            int64 tickCount = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
            cv::flip(srcMat, srcMat, 1);
            int64 tickCount2 = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
            int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
            qDebug() << __FUNCTION__ << __LINE__ << "take time ms:" << ms;
            cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
        }else if(key == '5')    // 缩小
        {
            int64 tickCount = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
            cv::resize(srcMat, srcMat, cv::Size((int)(srcMat.cols * (1.0f - scaleStep)),
                                                (int)(srcMat.rows * (1.0f - scaleStep))));
            int64 tickCount2 = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
            int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
            qDebug() << __FUNCTION__ << __LINE__ << "take time ms:" << ms;
            cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
        }else if(key == '6')    // 放大
        {
            int64 tickCount = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount;
            cv::resize(srcMat, srcMat, cv::Size((int)(srcMat.cols * (1.0f + scaleStep)),
                                                (int)(srcMat.rows * (1.0f + scaleStep))));
            int64 tickCount2 = cv::getTickCount();
            qDebug() << __FUNCTION__ << __LINE__ << "cv::getTickCount() =" << tickCount2;
            int64 ms = ((double)tickCount2 - tickCount) * 1000.0f/ cv::getTickFrequency();
            qDebug() << __FUNCTION__ << __LINE__ << "take time ms:" << ms;
            cv::imshow("OpenCVDemo v1.5.0 QQ:21497936 blog:blog.csdn.net/qq21497936", srcMat);
        }
        if(key == 27)
        {
            break;
        }
    }
#endif
}

 

工程模板:对应版本号v1.5.0

       对应版本号v1.5.0

 

上一篇:《OpenCV开发笔记(七):OpenCV基础图形绘制》

下一篇:《OpenCV开发笔记(九):OpenCV区域图像(ROI)和整体、局部图像混合》


原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/101168828

你可能感兴趣的:(图形图像处理,#,OpenCV)