成像代码读入部分
Posted 曙光晨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了成像代码读入部分相关的知识,希望对你有一定的参考价值。
成像实验代码
声明
由于实验的老师特有的查重方式以及计算成绩的方法,所以请不要直接照抄本文的代码。
这里的代码可能会有一些BUG,请大家注意
注:我这里的使用的是C++,VS2019 ,Graph2019,可能之后的版本会不同这里说明一下,说不定等我啥时间闲了,我写个C#版本的。(笑)
C++的知识
这里我先简单的说一下C++的知识,如果您是大佬请自行跳过。
这里是我对C++的理解,勿喷。
我放个链接
https://www.runoob.com/cplusplus/cpp-tutorial.html (这个是在网上自学C++使用网站,确实不错)
首先:我是用的是VS,如果你使用的是VScode,你加油,我至今没配置好VScode的C++环境(哭)。
这里新建一个文件请看清楚是不是C++,还要选择控制台应用(就是会自动生成Hello word的),后面会让你输入你项目的名字,这里我写的是实验但是我认为写英文或者拼音可以防止一些Bug.
你打开软件应该是这样的,有这个自动生成的Hello World就行了,这里我建议你先运行一下,看看自己你的环境配置有没有啥问题,如果你不幸出现了bug,先看看是不是自己的SDK出现了问题(这里建议上网搜搜吧)。
你确认可以运行之后。
把不需要的注释删除。打头文件(就是一堆.h文件);
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <graphics.h>
#include <conio.h>
#include <iostream>
#include <cstdio>
#include <fstream>
#include <istream>
#include<string>
#include<regex>
#include<sstream>
#include <cassert>
这里是我的,好像有一些没用上不要在意这些细节(笑)。注意看上面有一个graphics.h的文件这个是需要你个人在网上下载的。
这里我放个链接https://blog.csdn.net/edc370/article/details/79944550 可以参考这个去下载和配置。
C++的知识
仔细观察这个hello world的输出方式,
std::cout << "Hello World!\\n";
这里的std:: 是命名空间建议在开头写在头文件下面。
using namespace std;
这里的<<可以理解为数据流的传递,如果无法理解就请先记忆吧。
这里说的都是对控制台的输入输出,不是文件(害)
cout<<"someting you want to output";
cout<<"someting you want to output"<<endl;//这个是输出之后会自动换行的
//读入
int x;
double y;
cin>>x;//这个是从控制台读入数据放到x中
cin>>y;//同理这个也是一样的
//如果你出现cin ,cout,endl;下面有红线你看看是不是命名空间有问题。
//试试这种方式
std::cout<<"someting you want to output"<<std::endl;
std::cin>>x;
//在这些前面加一个std::
//大致意思就是使用std命名空间中的啥啥的意思,注意后面跟的是两个英文的冒号::
类和对象
我尽量写的通俗一些。如果你实在不会那就不用使用这个了,直接在main花括号中写把。
如果你想让自己查重低点就学学这个吧。如果你用的是C但是看到了这个文章我说一下:C中没有类这个概念,直接在main 中写把
这里的类我简单解释一下:用我们之前的数电实验来举例,类就相当于一个模块(NE555?),但是这里注意一下,现在的类还没有实例化相当于这个模块还在别人工厂的电脑中做仿真。你用之前需要先实例化,相当于你从老师那里拿到了一个可以用的模块,之后就可以开始搭电路了。
大家都知道,模块有各种各样的功能,类也是一样就是一堆功能的集合。
你可以在VS上直接生成一个类,但是这样的话就不符合老师说的要一个文件(害)。所以我这里就没写了。
这里我用的是我的代码,请不要照抄
//写class 之后写个{} 在class后面写你的命名
class Read//这里的Read是我类的名称(就是NE555这个名字)
{
//记得C系列的都需要提前命名,别matlab写太多了忘了。
int i, j, k, s, t;
double ElecThickness;//电极厚度
int ElecNumber;//电极总数
//这里的 啥啥* 是指针如果你不会就直接写 啥啥[]开个数组,至于大小嘛,看后面把
double* DisBetweenAdjacentEle;//相邻电极之间的距离
double* StepBetweenAdjacentEle;//相邻电极划分的步长
double* ElecPotential;//电极电位
double RadiusAperture;//电极内孔径半径
int GridAperture;//电极内孔径半径等步长划分的网格数
double RadiusBoundary;//从电极内孔沿到封闭边界处的径向距离
int GridBoundary;//从电极内孔沿到封闭边界处划分的网格数
double IterationAccuracy;//迭代精度
int NST;//输出打印空间电位时网格点间隔数
//注:这里的等位线可能只有一个或者多个,这里处理还是很烦的。注意
double* EOE;//要求扫描搜索等电位线的电位间隔值
//这里是文件的指针,不能改成数组,主要是为了读入数据
FILE* ParameterFile;
//这里我是使用结构体去进行类之间的数据传递,所以我写了这个东西。
//要是看不同这里public的话就写一个function写一个public:
public://这里的public :是说明这个东西可以在外部调用,类比就是NE555的一些功能之类的
struct data {
public://这里的public 是说明这个结构体中的东西可以被外部调用。
double mElecThickness;//电极厚度
int mElecNumber;//电极总数
double* mDisBetweenAdjacentEle;//相邻电极之间的距离
double* mStepBetweenAdjacentEle;//相邻电极划分的步长
double* mElecPotential;//电极电位
double mRadiusAperture;//电极内孔径半径
int mGridAperture;//电极内孔径半径等步长划分的网格数
double mRadiusBoundary;//从电极内孔沿到封闭边界处的径向距离
int mGridBoundary;//从电极内孔沿到封闭边界处划分的网格数
double mIterationAccuracy;//迭代精度
int mNST;//输出打印空间电位时网格点间隔数
double* mEOE;//要求扫描搜索等电位线的电位间隔值
double mdov;//要求扫描等位线间隔值
};
};
之后开始学习function的使用。
//这里我临时写了一个类
class hhh {
public ://这就是上面那个public,不会用的话就在每一个函数前写一个public吧。
void jj() //这个是函数,jj是名称,void表示啥都不反回。
{
cout << "Huang WeiChen";
}
double gg() //这个是返回一个double类型的数据,这里我就随便写了个1。
{
cout << "I'm yellow boss" << endl;
return 1;
}
};
这里我假设你已经写好了你自己的class,下面就是如果使用它(就是用NE555搭个电路,笑)
int main() {
/*在你的main函数中写*/
double kk;
hhh test;//这里就是实例化,模板: 你的类名称 你的实例化名称
//简单的理解就是你把你的NE555叫小花 它有个功能(函数)叫开花(不知道NE555有没有这个功能,笑)
// 那就这样写: NE555 小花
//就简单的类比一下把,感觉和结构体比较像
/*接下来就是函数的调用,写: 小花.开花();*/
kk = test.gg();//kk是返回的值,这里是1
test.jj();
}
好了这里为止就是C++大致的内容(我认为这次编写需要的)。
好像还有一个开空间的(笑)
记得要关闭空间,不然会出bug,但是VS好像有一个机制啥的吧会自动释放的,但是还是建议你写,因为不知道会发生啥bug。
这个是C开空间的方式,C++也能用,但是注意它应该是没有初始化的。记得初始化
名称 =(类型*)calloc(大小 ,sizeof(类型));
StepBetweenAdjacentEle = (double*)calloc(ElecNumber, sizeof(double));//
free(StepBetweenAdjacentEle);
另外一种方式:
使用new
double* StepBetweenAdjacentEle = new double[ElecNumber];
类型* 名称 =new double[大小];
delete[] StepBetweenAdjacentEle;
开始编写代码(读入数据)
老师会给一个.dat文件,它包含了你需要的各种信息。可能你会对此有一定的修改,但是这里还是按照我的来(笑)
这里我就直接在main中写了,如果你用的是class就自己改改把
首先声明一点:这个代码我没跑通,我也不知道是啥情况,我的正册好像不太行所以放这里做个例子(笑)
int main() {
int i, j, k, s, t;//这个其实写不写都行,但是后面定义麻烦我就直接写了。
下面这些都是老师给的数据,自己写好命名,给个建议如果英文不好就用拼音代替,但是别写啥a,b,c,d的这个代码我整个写下来1200+行,后面真的记不清不如直接在这里就把命名搞好一点至少,你要让你30分钟后明白。
ps:VS有个好处就是如果你在命名后面写注释的话(比如下面这个 ElcThickness//电极厚度)
后面你debug时候用鼠标去靠近EleThickness时候会自动显示注释(电极厚度),这个VS还是很好用的,但是还是希望你写把命名写好。
double ElecThickness;//电极厚度
int ElecNumber;//电极总数
double* DisBetweenAdjacentEle;//相邻电极之间的距离
double* StepBetweenAdjacentEle;//相邻电极划分的步长
double* ElecPotential;//电极电位
double RadiusAperture;//电极内孔径半径
int GridAperture;//电极内孔径半径等步长划分的网格数
double RadiusBoundary;//从电极内孔沿到封闭边界处的径向距离
int GridBoundary;//从电极内孔沿到封闭边界处划分的网格数
double IterationAccuracy;//迭代精度
int NST;//输出打印空间电位时网格点间隔数
double* EOE;//要求扫描搜索等电位线的电位间隔值
FILE* ParameterFile;
//这里我定义一个函数,后面有
double inputTest(string temp);
//注:C++中从文件读入有多种方式,这个你自己上网搜搜把。
fopen_s(&ParameterFile, "E:\\\\Learning(School)\\\\光电成像原理与技术", "r+");
//注:这个判断是否打开文件的记得写,不然不好debug。
if (ParameterFile == NULL)//detect the file
{
printf("Open filefailure!");
exit(1);
}
/*test*/
//
//这是另外一种方式读入
string fileName = "E:\\\\Learning(School)\\\\1120160852.dat";
ifstream in; //ifstream读文件(ofstream写文件)
in.open(fileName);
if (!in)
{
cout << "打开文件出错!" << endl;
//return 1;
}
string temp;
if (getline(in, temp))
{
string str;
regex e("(.*):(.*);");
smatch m;
bool found = regex_search(temp, m, e);
string num = m[2].str();
istringstream Convert(num);
Convert >> ElecNumber;
Convert.clear();
}
if (getline(in, temp))
{
string str;
regex e("(.*):(.*);");
smatch m;
bool found = regex_search(temp, m, e);
string num = m[2].str();
istringstream Convert(num);
Convert >> ElecThickness;
Convert.clear();
}
if (getline(in, temp))
{
DisBetweenAdjacentEle = (double*)calloc(ElecNumber, sizeof(double));//分配电极距离数组大小
fscanf_s(ParameterFile, "相邻电极之间的距离:%lf,", &DisBetweenAdjacentEle[0]);//扫描距离数组第一个元素
for (i = 1; i < ElecNumber - 1; i++)
{
fscanf_s(ParameterFile, "%lf,", &DisBetweenAdjacentEle[i]);
}//把第二个至倒数第二个距离元素都扫描到数组里
cout << "hhh" << endl;
}
if (getline(in, temp))
{
StepBetweenAdjacentEle = (double*)calloc(ElecNumber, sizeof(double));//给步长数组分配内存空间
fscanf_s(ParameterFile, "相邻电极划分的步长:%lf,", &StepBetweenAdjacentEle[0]);//扫描步长数组第一个元素
for (i = 1; i < ElecNumber - 1; i++)
{
fscanf_s(ParameterFile, "%lf,", &StepBetweenAdjacentEle[i]);
}//把从第二个至倒数第二个步长元素扫描到数组里
fscanf_s(ParameterFile, "%lf;\\n", &StepBetweenAdjacentEle[ElecNumber - 1]);//把最后一个数组元素扫描到数组里
}
if (getline(in, temp)) {
ElecPotential = (double*)calloc(ElecNumber, sizeof(double));//Allocates memory space to the electronic potential array.
fscanf_s(ParameterFile, "电极电位:%lf,", &ElecPotential[0]);
for (i = 1; i < ElecNumber - 1; i++)
{
fscanf_s(ParameterFile, "%lf,", &ElecPotential[i]);
}
fscanf_s(ParameterFile, "%lf;\\n", &ElecPotential[ElecNumber - 1]);//Put the last element into the array
}
if (getline(in, temp)) {
RadiusAperture = inputTest(temp);
}
if (getline(in, temp)) {
GridAperture = inputTest(temp);
}
if (getline(in, temp)) {
RadiusBoundary = inputTest(temp);
}
if (getline(in, temp)) {
GridBoundary = inputTest(temp);
}
if (getline(in, temp)) {
IterationAccuracy = inputTest(temp);
}
if (getline(in, temp)) {
NST = inputTest(temp);
}
EOE = (double*)calloc(100, sizeof(double));
//dov = 0;
i = -1;
do
{
i++;
fscanf_s(ParameterFile, "%lf;", &EOE[i]);
} while (EOE[i] != 0);
in.close();
/*到这里你都将数据读入了,之后就用前面写的cout去输出吧*/
cout<<啥啥;
double inputTest(string temp);
{
string str;
regex e("(.*):(.*);");
smatch m;
bool found = regex_search(temp, m, e);
string num = m[2].str();
istringstream Convert(num);
double Result;
Convert >> Result;
Convert.clear();
return Result;
}
}
到这里为止是程序中读入数据的部分。
希望你能跑通这部分,得到5分(害,这个分也太低了)。
关于bug的部分:
注意空间的初始(memset()可以用这个,或者其他方式),释放问题。
注意;的问题。注意中英文的问题。祝大家好运。
以上是关于成像代码读入部分的主要内容,如果未能解决你的问题,请参考以下文章