常用C++库使用实例(一)

文章介绍了如何在C++中使用Boost库进行类型转换、日期时间处理、随机数生成,以及BRPC、Caffe在RPC和深度学习中的应用,还有Crow创建HTTP服务器和cURL进行网络数据交互的示例。
摘要由CSDN通过智能技术生成

boost

#include <iostream>
#include <boost/lexical_cast.hpp> // 用于类型转换
#include <boost/date_time/gregorian/gregorian.hpp> // 日期和时间
#include <boost/random.hpp> // 随机数生成

int main() {
    // 字符串与数字之间的转换
    try {
        int myInt = boost::lexical_cast<int>("123");
        std::string myStr = boost::lexical_cast<std::string>(456);
        std::cout << "Converted integer: " << myInt << std::endl;
        std::cout << "Converted string: " << myStr << std::endl;
    } catch (boost::bad_lexical_cast& e) {
        std::cout << "Exception caught: " << e.what() << std::endl;
    }

    // 使用 Boost Date Time
    boost::gregorian::date today = boost::gregorian::day_clock::local_day();
    std::cout << "Today's date: " << boost::gregorian::to_simple_string(today) << std::endl;

    // 使用 Boost Random
    boost::random::mt19937 gen; // 随机数生成器
    boost::random::uniform_int_distribution<> dist(1, 100); // 分布范围
    std::cout << "Random number between 1 and 100: " << dist(gen) << std::endl;

    return 0;
}

这段代码展示了如何在C++中使用Boost库来进行类型转换、处理日期时间以及生成随机数:

  • 使用boost::lexical_cast进行字符串和数字之间的转换。
  • 使用boost::gregorian::date处理日期,通过boost::gregorian::day_clock::local_day()获取当前日期。
  • 利用boost::random生成随机数,这里使用了boost::random::mt19937作为随机数生成器以及boost::random::uniform_int_distribution<>来指定生成随机数的范围。

请确保在编译时链接Boost库。

RBPC

BRPC(Baidu RPC)是百度开源的一个RPC(远程过程调用)框架,旨在帮助开发者构建高性能、可扩展的分布式系统。下面是一个简单的BRPC服务端和客户端的示例代码:

首先,我们定义一个简单的服务接口。在这个例子中,我们创建一个简单的Echo服务,它接收一个字符串消息并将其返回给调用者。

echo_service.proto

syntax = "proto2";

package example;

service EchoService {
  rpc Echo(EchoRequest) returns (EchoResponse);
}

message EchoRequest {
  required string message = 1;
}

message EchoResponse {
  required string message = 1;
}

Caffe

在C++中使用Caffe进行深度学习任务是一种常见做法,特别是在需要将深度学习模型集成到现有的C++项目或产品中时。以下是一个简单的例子,展示了如何使用C++ API加载一个预训练的Caffe模型并对一张图片进行分类。

预备步骤

确保您已经正确安装了Caffe及其C++依赖,同时确保您有以下文件:

  • 预训练模型的deploy.prototxt
  • 预训练的权重文件.caffemodel
  • 如果有必要,还需要均值文件.binaryproto和标签文件
示例代码

以下是一个示例代码,展示了如何在C++中使用Caffe进行图像分类:

#include <caffe/caffe.hpp>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace caffe;  // NOLINT(build/namespaces)
using std::string;

int main(int argc, char** argv) {
    if (argc != 4) {
        std::cerr << "Usage: " << argv[0]
                  << " deploy.prototxt network.caffemodel"
                  << " img.jpg" << std::endl;
        return 1;
    }

    ::google::InitGoogleLogging(argv[0]);

    // 设置为CPU模式
    Caffe::set_mode(Caffe::CPU);

    // 加载网络
    Net<float> net(argv[1], TEST);
    net.CopyTrainedLayersFrom(argv[2]);

    // 加载图像
    cv::Mat img = cv::imread(argv[3], -1);
    CHECK(!img.empty()) << "Unable to decode image " << argv[3];

    // 配置预处理
    Blob<float>* input_layer = net.input_blobs()[0];
    int width = input_layer->width();
    int height = input_layer->height();
    cv::Mat resized;
    cv::resize(img, resized, cv::Size(width, height));
    cv::Mat sample_float;
    resized.convertTo(sample_float, CV_32FC3);
    cv::Mat mean = cv::Mat(width, height, CV_32FC3, cv::Scalar(104.0, 117.0, 123.0));
    cv::subtract(sample_float, mean, sample_float);

    // 将数据复制到内存中
    std::vector<cv::Mat> input_channels;
    float* input_data = input_layer->mutable_cpu_data();
    for (int i = 0; i < input_layer->channels(); ++i) {
        cv::Mat channel(height, width, CV_32FC1, input_data);
        input_channels.push_back(channel);
        input_data += width * height;
    }
    cv::split(sample_float, input_channels);

    // 前向传播
    net.Forward();

    // 获取输出
    Blob<float>* output_layer = net.output_blobs()[0];
    const float* begin = output_layer->cpu_data();
    const float* end = begin + output_layer->channels();
    std::vector<float> output(begin, end);

    // 输出最可能的类别
    std::cout << "Predicted class: " << std::max_element(output.begin(), output.end()) - output.begin() << std::endl;

    return 0;
}

这个示例中,我们首先加载了模型和权重文件,然后加载了一张图片并对其进行了预处理,以适配网络输入的大小和格式。之后,我们执行了前向传播来获取网络的输出。最后,我们找到了最大的输出值对应的索引,这对应于预测的类别。

请注意,本示例需要OpenCV支持进行图像的加载和预处理。确保您的系统中已经正确安装了OpenCV和Caffe的C++库。

编译此代码时,您需要链接Caffe和OpenCV库。确保在编译命令中包含适当的头文件路径和库路径。例如,如果您使用g++编译器,编译命令可能如下

g++ -o classify_image classify_image.cpp -I/path/to/caffe/include -I/path/to/caffe/.build_release/src -L/path/to/caffe/build/lib -lcaffe -lopencv_core -lopencv_imgproc -lopencv_highgui -lglog -lboost_system
这里的路径/path/to/caffe需要替换为您本地Caffe安装的实际路径。同样,确保链接了所有必要的库,这可能根据您的具体安装和系统配置有所不同。

Caffe

Caffe是一个深度学习框架,由伯克利人工智能研究小组(BAIR)开发。它以其速度和模块化设计著称,并且特别适合于图像处理的应用。以下是一个使用Caffe进行图像分类的简单示例。这个示例假设您已经安装了Caffe及其依赖,并且有一个预训练的模型可以使用。

步骤1: 准备模型和权重文件

确保您有以下文件:

  • 预训练模型定义文件(.prototxt)
  • 预训练的权重文件(.caffemodel)
  • 类别标签文件(可选,用于将输出的索引映射到实际的类别标签)

例如,假设我们使用Caffe自带的BVLC GoogleNet模型进行图像分类。

步骤2: 编写代码加载模型并进行预测

创建一个Python脚本classify_image.py,并编写以下代码:

import numpy as np
import caffe
import sys

# 设置模型架构和模型权重的路径
model_def = 'models/bvlc_googlenet/deploy.prototxt'
model_weights = 'models/bvlc_googlenet/bvlc_googlenet.caffemodel'

# 设置要预测的图片路径
image_path = sys.argv[1]

# Caffe在GPU还是CPU模式下运行
caffe.set_mode_cpu()

# 加载模型
net = caffe.Net(model_def,      # 定义模型结构
                model_weights,  # 包含了模型的训练权重
                caffe.TEST)     # 使用测试模式(不执行dropout)

# 输入预处理
# 加载ImageNet图像均值 (作为模型训练的一部分)
mu = np.load('models/bvlc_googlenet/ilsvrc_2012_mean.npy')
mu = mu.mean(1).mean(1)  # 平均值,按通道计算

# 图像预处理,作为模型输入
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))  # 将图像从HxWxC转为CxHxWPYthon
transformer.set_mean('data', mu)            # 减去ImageNet的均值
transformer.set_raw_scale('data', 255)      # 缩放到[0, 255]
transformer.set_channel_swap('data', (2,1,0))  # 从RGB交换到BGR

# 设置输入图像大小
net.blobs['data'].reshape(1,          # 批量大小
                          3,          # 3-channel (BGR) images
                          224, 224)   # 图像大小为224x224

# 加载图像
image = caffe.io.load_image(image_path)

# 执行预处理
transformed_image = transformer.preprocess('data', image)

# 复制图像数据到内存中并执行前向传播
net.blobs['data'].data[...] = transformed_image

# 执行分类
output = net.forward()

# 输出预测的类别
output_prob = output['prob'][0]  # 批量中的第一个图像
print('Predicted class is:', output_prob.argmax())
步骤3: 使用模型进行预测

确保您的环境中已经安装了Caffe和必要的Python库,然后在命令行中运行以下命令,将<path_to_your_image>替换为您要分类的图像的路径。

python classify_image.py <path_to_your_image>

Crow

Crow 是一个现代的C++库,用于开发HTTP服务器,特别适合构建微服务。以下是使用Crow创建一个简单HTTP服务器的示例,它能够处理GET请求并返回一个简单的消息。

首先,确保你已经安装了Crow库及其依赖项。

main.cpp

#include "crow_all.h"

int main() {
    crow::SimpleApp app;

    CROW_ROUTE(app, "/")([](){
        return "Hello, world!";
    });

    CROW_ROUTE(app, "/hello/<string>")([](const std::string& name){
        return "Hello " + name + "!";
    });

    app.port(18080).multithreaded().run();
}

这段代码演示了如何使用Crow库创建一个简单的HTTP服务器,具有以下特点:

  • 服务器监听在18080端口上。
  • 定义了两个路由:
    • /:访问这个路由将返回"Hello, world!"。
    • /hello/<string>:这个路由能接收一个字符串参数,访问时将返回"Hello "加上该字符串参数的值。

为了编译这个例子,你需要在CMakeLists.txt文件中链接Crow库和必要的依赖。以下是一个基本的CMakeLists.txt示例,仅供参考:

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(crow_example)

set(CMAKE_CXX_STANDARD 11)

add_executable(crow_example main.cpp)

find_package(Boost REQUIRED)
target_link_libraries(crow_example PRIVATE ${Boost_LIBRARIES})

# 假设你已经正确安装了Crow,这里需要链接Crow库
# 如果Crow安装在非标准路径下,你可能需要使用include_directories()和link_directories()指明头文件和库文件的位置
target_link_libraries(crow_example PRIVATE crow)

注意:实际使用时,你需要根据你的开发环境和安装的库调整CMakeLists.txt文件。确保你已经安装了Crow需要的所有依赖项,特别是Boost库。

编译并运行这个程序后,你就可以通过浏览器访问http://localhost:18080/或者使用curl命令来测试这个简单的HTTP服务器了。

cURL

C++中使用cURL进行数据传输,你需要利用cURL的C库(libcurl),这允许你在C++程序中发送HTTP请求、上传文件等。以下是一个基本的示例,展示了如何在C++中使用libcurl发起一个简单的HTTP GET请求。

为了运行以下示例,你需要确保你的系统上安装了libcurl库。在大多数Linux发行版中,你可以通过包管理器安装libcurl开发包。在Windows上,你可能需要从cURL官网下载并安装libcurl。

简单的HTTP GET请求示例:
 
#include <iostream>
#include <curl/curl.h>

// 此回调函数被libcurl调用,用于保存接收到的数据
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

int main() {
    CURL *curl; // 定义CURL指针
    CURLcode res; // 用于接收CURL操作的返回码
    std::string readBuffer; // 用于存储从服务器接收到的数据

    curl = curl_easy_init(); // 初始化CURL操作
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); // 设置目标URL
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); // 设置数据接收回调函数
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // 设置回调函数的用户数据

        res = curl_easy_perform(curl); // 执行CURL操作

        // 检查错误
        if(res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            std::cout << readBuffer << std::endl; // 输出接收到的数据
        }

        curl_easy_cleanup(curl); // 清理CURL,释放资源
    }

    return 0;
}
  1. 安装libcurl: 确保你的开发环境中安装了libcurl库。
  2. 线程安全: 如果你在多线程程序中使用libcurl,需要注意线程安全问题,详细信息可以查阅libcurl文档。
  3. 错误处理: 示例代码中对curl_easy_perform的返回值进行了基本的错误检查,实际使用中可能需要更详细的错误处理逻辑。

通过使用libcurl,C++程序可以方便地执行各种网络操作,包括文件下载、上传、HTTP请求等。更多高级功能和详细配置选项,可以参考libcurl的官方文档。

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值