C++读取文件,将cv::Point3d点集保存在vector中,然后把点集的vector保存在vector中。vector<vector<cv::Point3d>>

文章目录


前言

该代码有2个作用:
(1)读取文件,可以通用
(2)读取3维坐标点,存入vector中

结构

这是需要读取的文件
这是一个.poly文件里的内容,每一行是三个坐标值,中间用空格分开(数据是随意捏造的)
这是运行后的数据存储的位置

代码

#include <opencv2/core.hpp>
#include <iostream>
#include <fstream>
#include <io.h>

using namespace std;
using namespace cv;


void getFiles(string path, vector<string>& files);


int main()
{
   
	const char* filePath = "D:\\vs 项目\\poly";
	vector<string> files;

	//获取该路径下的所有文件
	getFiles(filePath
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个基于LeNet的手写数字识别程序,使用C++编写,带详细注释。 首先,我们需要包含一些头文件,包括OpenCV和一些标准库文件。 ```c++ #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> #include <fstream> #include <string> #include <vector> #include <algorithm> #include <cmath> ``` 接下来,我们定义一些常量和全局变量。这里的常量和变量都是LeNet网络使用到的,包括输入图像的大小、卷积核的大小、池化的大小、网络的层数、隐藏层的神经元数目等。 ```c++ // define constants const int WIDTH = 28; // 输入图像宽度 const int HEIGHT = 28; // 输入图像高度 const int CHANNELS = 1; // 输入图像通道数 const int KERNEL_SIZE = 5; // 卷积核大小 const int POOL_SIZE = 2; // 池化大小 const int NUM_HIDDEN = 128; // 隐藏层神经元数 const int NUM_LABELS = 10; // 标签数目 // 定义全局变量 cv::Mat inputImage; // 输入图像 cv::Mat outputImage; // 输出图像 std::vector<cv::Mat> kernels; // 卷积核 std::vector<cv::Mat> bias; // 偏置 std::vector<cv::Mat> convOutputs; // 卷积输出 std::vector<cv::Mat> poolOutputs; // 池化输出 cv::Mat hiddenWeights; // 隐藏层权重 cv::Mat hiddenBias; // 隐藏层偏置 cv::Mat outputWeights; // 输出层权重 cv::Mat outputBias; // 输出层偏置 ``` 接下来是定义函数的部分。我们需要定义一些辅助函数,包括读取数据集、对图像进行预处理、进行卷积操作、进行池化操作、进行激活函数操作、进行全连接操作等。 ```c++ // 辅助函数:读取数据集 std::vector<std::pair<cv::Mat, int>> readDataset(const std::string& filename) { std::vector<std::pair<cv::Mat, int>> dataset; std::ifstream file(filename); if (file.is_open()) { std::string line; while (std::getline(file, line)) { std::replace(line.begin(), line.end(), ',', ' '); std::stringstream ss(line); std::vector<int> values; int label; for (int i = 0; i < WIDTH * HEIGHT; i++) { int value; ss >> value; values.push_back(value); } ss >> label; cv::Mat image = cv::Mat(WIDTH, HEIGHT, CV_8UC1, cv::Scalar(0)); for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { image.at<uchar>(i, j) = values[i*WIDTH+j]; } } dataset.push_back(std::make_pair(image, label)); } file.close(); } return dataset; } // 辅助函数:对图像进行预处理 cv::Mat preprocessImage(const cv::Mat& image) { cv::Mat grayImage; cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY); cv::Mat resizedImage; cv::resize(grayImage, resizedImage, cv::Size(WIDTH, HEIGHT)); cv::Mat normalizedImage; resizedImage.convertTo(normalizedImage, CV_32FC1); normalizedImage /= 255.0f; return normalizedImage; } // 辅助函数:进行卷积操作 void convolve(const cv::Mat& input, const cv::Mat& kernel, cv::Mat& output) { cv::filter2D(input, output, -1, kernel, cv::Point(-1,-1), 0, cv::BORDER_DEFAULT); } // 辅助函数:进行池化操作 void pool(const cv::Mat& input, cv::Mat& output) { cv::Size poolSize(POOL_SIZE, POOL_SIZE); cv::Size strideSize(POOL_SIZE, POOL_SIZE); cv::maxPool(input, output, poolSize, strideSize); } // 辅助函数:进行激活函数操作 void activate(const cv::Mat& input, cv::Mat& output) { cv::Mat temp; cv::exp(-input, temp); output = 1.0 / (1.0 + temp); } // 辅助函数:进行全连接操作 void fullyConnected(const cv::Mat& input, const cv::Mat& weights, const cv::Mat& bias, cv::Mat& output) { cv::gemm(input, weights, 1.0, bias, 1.0, output); } // 初始化函数:对卷积核、偏置、权重、偏置进行初始化 void init() { // 初始化卷积核和偏置 kernels.push_back(cv::Mat(KERNEL_SIZE, KERNEL_SIZE, CV_32FC1, cv::Scalar(0.1))); kernels.push_back(cv::Mat(KERNEL_SIZE, KERNEL_SIZE, CV_32FC1, cv::Scalar(0.2))); kernels.push_back(cv::Mat(KERNEL_SIZE, KERNEL_SIZE, CV_32FC1, cv::Scalar(0.3))); kernels.push_back(cv::Mat(KERNEL_SIZE, KERNEL_SIZE, CV_32FC1, cv::Scalar(0.4))); bias.push_back(cv::Mat::ones(cv::Size(WIDTH-KERNEL_SIZE+1, HEIGHT-KERNEL_SIZE+1), CV_32FC1)); bias.push_back(cv::Mat::ones(cv::Size(WIDTH-KERNEL_SIZE+1, HEIGHT-KERNEL_SIZE+1), CV_32FC1)); bias.push_back(cv::Mat::ones(cv::Size(WIDTH-KERNEL_SIZE+1, HEIGHT-KERNEL_SIZE+1), CV_32FC1)); bias.push_back(cv::Mat::ones(cv::Size(WIDTH-KERNEL_SIZE+1, HEIGHT-KERNEL_SIZE+1), CV_32FC1)); // 初始化隐藏层权重和偏置 hiddenWeights = cv::Mat(NUM_HIDDEN, WIDTH*HEIGHT*3, CV_32FC1); cv::randn(hiddenWeights, 0.0, 1.0); hiddenBias = cv::Mat::ones(cv::Size(NUM_HIDDEN, 1), CV_32FC1); // 初始化输出层权重和偏置 outputWeights = cv::Mat(NUM_LABELS, NUM_HIDDEN, CV_32FC1); cv::randn(outputWeights, 0.0, 1.0); outputBias = cv::Mat::ones(cv::Size(NUM_LABELS, 1), CV_32FC1); } ``` 接下来是主函数的部分,我们需要读入数据集、对数据集的图像进行预处理、对图像进行卷积、池化、激活函数、全连接等一系列操作,最终输出预测的标签。 ```c++ int main(int argc, char** argv) { // 读取数据集 std::vector<std::pair<cv::Mat, int>> dataset = readDataset("mnist.csv"); // 初始化 init(); // 循环处理每个图像 for (int i = 0; i < dataset.size(); i++) { // 读取图像 inputImage = dataset[i].first; // 对图像进行卷积和池化操作 for (int j = 0; j < kernels.size(); j++) { convolve(inputImage, kernels[j], convOutputs[j]); convOutputs[j] += bias[j]; pool(convOutputs[j], poolOutputs[j]); } // 将池化后的图像转化为向量 cv::Mat flattenedImage = cv::Mat::zeros(cv::Size(1, WIDTH*HEIGHT*3), CV_32FC1); int index = 0; for (int c = 0; c < 3; c++) { for (int x = 0; x < WIDTH/POOL_SIZE; x++) { for (int y = 0; y < HEIGHT/POOL_SIZE; y++) { flattenedImage.at<float>(index++, 0) = poolOutputs[c].at<float>(x, y); } } } // 对隐藏层进行操作 cv::Mat hiddenOutput; fullyConnected(flattenedImage, hiddenWeights, hiddenBias, hiddenOutput); activate(hiddenOutput, hiddenOutput); // 对输出层进行操作 cv::Mat output; fullyConnected(hiddenOutput, outputWeights, outputBias, output); activate(output, output); // 找到最大值的索引 cv::Point maxLoc; cv::minMaxLoc(output, NULL, NULL, NULL, &maxLoc); int predictedLabel = maxLoc.y; // 输出预测的标签 std::cout << "Predicted label: " << predictedLabel << std::endl; } return 0; } ``` 这样,我们就完成了一个基于LeNet的手写数字识别程序,使用C++编写。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值