opencv 怎么将vector<double> YValues 放入mat中
时间: 2024-03-11 12:50:49 浏览: 22
将vector<double> YValues放入Mat中,可以使用以下代码:
```c++
std::vector<double> YValues;
int Size = YValues.size();
cv::Mat mat_array(1, Size, CV_64F);
// 将vector数据复制到Mat中
memcpy(mat_array.data, YValues.data(), YValues.size()*sizeof(double));
```
首先,定义了一个vector<double>对象YValues,然后根据YValues的大小定义了一个Mat对象mat_array。最后,使用memcpy函数将vector中的数据复制到Mat中。
需要注意的是,这里使用memcpy函数的前提是vector和Mat对象的内存布局是相同的,即在内存中都是连续的double类型数据。如果vector和Mat对象的内存布局不同,需要使用其他方法来实现数据的复制。
相关问题
opencv 怎么将vector<double> XValues, std::vector<double> YValues 放入到mat中两行
将vector<double> XValues和YValues放入到Mat中,每个向量对应矩阵的一行,可以使用以下代码:
```c++
std::vector<double> XValues, YValues;
int Size = XValues.size();
cv::Mat mat_array(2, Size, CV_64F);
// 将XValues和YValues数据复制到Mat的两行中
memcpy(mat_array.row(0).data, XValues.data(), XValues.size()*sizeof(double));
memcpy(mat_array.row(1).data, YValues.data(), YValues.size()*sizeof(double));
```
首先,定义了两个vector<double>对象XValues和YValues,并根据XValues的大小定义了一个2行Size列的Mat对象mat_array。然后,使用memcpy函数将XValues和YValues中的数据分别复制到Mat的两行中。
需要注意的是,这里使用memcpy函数的前提是vector和Mat对象的内存布局是相同的,即在内存中都是连续的double类型数据。如果vector和Mat对象的内存布局不同,需要使用其他方法来实现数据的复制。
由void readDataset(string imagesFile, string labelsFile, vector<Mat>& images, vector<int>& labels) void convolve(Mat& input, Mat filter, Mat& output) void pool(Mat& input, Mat& output) void fullyConnected(Mat& input, Mat& weight, Mat& bias, Mat& output) void softmax(Mat& input, Mat& output) void cnnModel(Mat& input, Mat& output)组成的C++手写数字识别main函数实现
好的,以下是一个简单的手写数字识别的C++程序实现:
```c++
#include <iostream>
#include <fstream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
// 读取MNIST数据集
void readDataset(string imagesFile, string labelsFile, vector<Mat>& images, vector<int>& labels)
{
ifstream ifsImages(imagesFile, ios::binary);
ifstream ifsLabels(labelsFile, ios::binary);
if (!ifsImages.is_open() || !ifsLabels.is_open()) {
cout << "Failed to open file." << endl;
return;
}
int magicImages, magicLabels, numImages, numLabels;
ifsImages.read((char*)&magicImages, sizeof(magicImages));
ifsLabels.read((char*)&magicLabels, sizeof(magicLabels));
ifsImages.read((char*)&numImages, sizeof(numImages));
ifsLabels.read((char*)&numLabels, sizeof(numLabels));
magicImages = reverseInt(magicImages);
magicLabels = reverseInt(magicLabels);
numImages = reverseInt(numImages);
numLabels = reverseInt(numLabels);
for (int i = 0; i < numImages; ++i) {
Mat image = Mat::zeros(28, 28, CV_8UC1);
for (int r = 0; r < 28; ++r) {
for (int c = 0; c < 28; ++c) {
unsigned char pixel;
ifsImages.read((char*)&pixel, sizeof(pixel));
image.at<uchar>(r, c) = pixel;
}
}
images.push_back(image);
}
for (int i = 0; i < numLabels; ++i) {
unsigned char label;
ifsLabels.read((char*)&label, sizeof(label));
labels.push_back((int)label);
}
}
// 卷积操作
void convolve(Mat& input, Mat filter, Mat& output)
{
int filterSize = filter.rows;
int pad = filterSize / 2;
Mat paddedInput;
copyMakeBorder(input, paddedInput, pad, pad, pad, pad, BORDER_CONSTANT, Scalar(0));
output.create(input.rows, input.cols, input.type());
for (int r = pad; r < paddedInput.rows - pad; ++r) {
for (int c = pad; c < paddedInput.cols - pad; ++c) {
double sum = 0.0;
for (int fr = 0; fr < filterSize; ++fr) {
for (int fc = 0; fc < filterSize; ++fc) {
int ir = r - pad + fr;
int ic = c - pad + fc;
sum += paddedInput.at<double>(ir, ic) * filter.at<double>(fr, fc);
}
}
output.at<double>(r - pad, c - pad) = sum;
}
}
}
// 池化操作
void pool(Mat& input, Mat& output)
{
output.create(input.rows / 2, input.cols / 2, input.type());
for (int r = 0; r < input.rows; r += 2) {
for (int c = 0; c < input.cols; c += 2) {
double maxVal = 0.0;
for (int pr = 0; pr < 2; ++pr) {
for (int pc = 0; pc < 2; ++pc) {
double val = input.at<double>(r + pr, c + pc);
if (val > maxVal) {
maxVal = val;
}
}
}
output.at<double>(r / 2, c / 2) = maxVal;
}
}
}
// 全连接层操作
void fullyConnected(Mat& input, Mat& weight, Mat& bias, Mat& output)
{
output.create(1, weight.cols, CV_64FC1);
for (int c = 0; c < weight.cols; ++c) {
double sum = 0.0;
for (int r = 0; r < weight.rows; ++r) {
sum += input.at<double>(r) * weight.at<double>(r, c);
}
sum += bias.at<double>(0, c);
output.at<double>(0, c) = sum;
}
}
// Softmax操作
void softmax(Mat& input, Mat& output)
{
output.create(1, input.cols, CV_64FC1);
double sum = 0.0;
for (int c = 0; c < input.cols; ++c) {
double expVal = exp(input.at<double>(0, c));
output.at<double>(0, c) = expVal;
sum += expVal;
}
for (int c = 0; c < input.cols; ++c) {
output.at<double>(0, c) /= sum;
}
}
// CNN模型
void cnnModel(Mat& input, Mat& output)
{
// 卷积层1
Mat filter1 = (Mat_<double>(5, 5) << -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,24,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
Mat conv1;
convolve(input, filter1, conv1);
// 激活函数ReLU
Mat relu1;
cv::max(0, conv1, relu1);
// 池化层1
Mat pool1;
pool(relu1, pool1);
// 卷积层2
Mat filter2 = (Mat_<double>(5, 5) << -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,24,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
Mat conv2;
convolve(pool1, filter2, conv2);
// 激活函数ReLU
Mat relu2;
cv::max(0, conv2, relu2);
// 池化层2
Mat pool2;
pool(relu2, pool2);
// 全连接层1
Mat fcInput = pool2.reshape(1, 1);
Mat weight1 = (Mat_<double>(fcInput.cols, 128) << ...);
Mat bias1 = (Mat_<double>(1, 128) << ...);
Mat fc1;
fullyConnected(fcInput, weight1, bias1, fc1);
// 激活函数ReLU
Mat relu3;
cv::max(0, fc1, relu3);
// 全连接层2
Mat weight2 = (Mat_<double>(relu3.cols, 10) << ...);
Mat bias2 = (Mat_<double>(1, 10) << ...);
Mat fc2;
fullyConnected(relu3, weight2, bias2, fc2);
// Softmax
softmax(fc2, output);
}
int main()
{
// 读取MNIST数据集
vector<Mat> images;
vector<int> labels;
readDataset("train-images-idx3-ubyte", "train-labels-idx1-ubyte", images, labels);
// 训练CNN模型
for (int i = 0; i < images.size(); ++i) {
Mat input = images[i] / 255.0;
Mat output;
cnnModel(input, output);
// 计算损失函数
double loss = 0.0;
for (int c = 0; c < output.cols; ++c) {
int label = (c == labels[i]) ? 1 : 0;
loss += -label * log(output.at<double>(0, c));
}
// 反向传播更新权重和偏置
// ...
}
return 0;
}
```
需要注意的是,这只是一个简单的手写数字识别程序实现,具体的实现细节还需要根据实际需求进行调整和完善。