OpenCV4 C++学习 必备基础语法知识二

小白学视觉

共 6502字,需浏览 14分钟

 ·

2021-06-03 17:41

点击上方小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

本文转自|OpenCV学堂

前言

之前我写过一篇介绍学习OpenCV C++一些前置基础C++11的基础知识,主要是介绍了输出打印、各种常见数据容器,这里又整理了一篇,主要涉及时间计算与格式化输出、各种数据类型之间的相互转换、简单的定义方法与泛型方法定义使用。

01

时间计算与转换

很久以前我写过一篇OpenCV中如何计算程序执行时间的文章,这个一直有效,链接如下:

https://mp.weixin.qq.com/s/CRzViZv8wY3PQ2uN70AtSA

这里我们使用C++11,同样可以计算,而且C++11还支持各种日期与系统时间的格式化输出,主要是基于std::chrono包的各种函数应用,这部分的代码演示如下:

std::cout << "Hello World, C++" << std::endl;// 毫秒std::chrono::milliseconds ms(3);std::cout << ms.count() << std::endl;// 转换为微秒std::chrono::microseconds us = ms * 2;std::cout << us.count() << std::endl;// 计算执行时间auto t1 = std::chrono::system_clock::now();cv::Mat src = cv::imread("D:/images/test.png");cv::Mat gray;cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);auto t2 = std::chrono::system_clock::now();std::cout <<"毫秒数:"<<         std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() <<         " 微秒数:"<< std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() <<         " 秒数:" << std::chrono::duration_cast<std::chrono::seconds>(t2 - t1).count() << std::endl;

// 计算当前时间与日期auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());std::cout << "Current Time: "<<std::put_time(std::localtime(&t), "%Y-%m-%d %H.%M.%S")<< std::endl;

运行结果如下:

支持毫秒、微秒、秒、支持获取系统的当前时间等。

02

数值转换

 在OpenCV编程开发中,有时候会读取数据文件,需要把数据从字符(string)类型转为数值(number)类型,常见的有int、float、double、long等类型与string类型的相互转换,这部分的转换主要依赖函数:

  • std::to_string 这个是万能的,我写出了C#与Java的既视感!

  • atoi 转化为整数int类型

  • atof 转换为浮点数float类型

代码演示如下:

// 各种字符与数值转换
double d = 1.234;
float f = 3.145;
int i = 314;
long l = 22;
std::cout << std::to_string(d) << std::endl;
std::cout << std::to_string(f) << std::endl;
std::cout << std::to_string(i) << std::endl;
std::cout << std::to_string(l) << std::endl;


// 从string到数值
const char* str1 = "3.2333";
const char* str2 = "5.321";
float f1 = std::atof(str1);
float f2 = std::atof(str2);
float f3 = f1 + f2;
std::cout << f3 << std::endl;


const char* str3 = "100";
const char* str4 = "121";
int i3 = std::atoi(str3) + std::atoi(str4);
std::cout << i3 << std::endl;

运行结果如下:

此外各种数值类型相互转化,主要依赖static_cast函数,使用如下:

int a1 = 100;
float f8 = 20;
float sum = std::max(static_cast<float>(a1), f8);


03

简单的泛型应用

有时候你看到一些C++的代码中会有template<typename  T>类似的语法,很多小白都直接蒙了,其实这个是现代编译器支持,各种语言都会有的泛型。说白了就是运行期识别。先定义个,到时候传什么类型就是什么类型。OpenCV中的图像数据常见支持uchar与float类型操作,我们以此为例定义一个泛型函数,实现浮点数与字节类型图像数据的遍历与操作,方法定义与代码实现如下:

template <typename T>
void pixel_visit_demo(cv::Mat& src, cv::Mat& dst) {
    // 指针读取
    int height = src.rows;
    int width = src.cols;
    int ch = src.channels();
    int blue = 0, green = 0, red = 0;
    int gray;
    for (int row = 0; row < height; row++) {
        T *curr_row = src.ptr<T>(row);
        T *result_row = dst.ptr<T>(row);
        for (int col = 0; col < width; col++) {
            if (ch == 3) {
                blue = *curr_row++;
                green = *curr_row++;
                red = *curr_row++;

                *result_row++ = 255 - blue;
                *result_row++ = 255 - green;
                *result_row++ = 255 - red;
            }
            else if (ch == 1) {
                gray = *curr_row++;
                *result_row++ = 255 - gray;
            }
        }
    }
}

调用该方法实现浮点数与字节类型的Mat对象操作代码如下:

// 泛型,处理不同类型的图像数据
 imshow("输入图像", src);
 Mat dst = Mat::zeros(src.size(), src.type());
 pixel_visit_demo<uchar>(src, dst);
 imshow("result-uchar", dst);

 // 处理浮点数图像数据
 src.convertTo(src, CV_32F);
 dst.convertTo(dst, CV_32F);
 pixel_visit_demo<float>(src, dst);
 imshow("result-float", dst/255.0);
 waitKey(0);

运行结果如下:



下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~


浏览 27
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报