Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
PCLµü´ú×î½üµãËã·¨£¨ICP£©µÄC++ʵÏÖ
 
×÷ÕßêdzƣºRson555
  3905  次浏览      27
 2021-3-19 
 
±à¼­ÍƼö:
±¾ÎÄÖ÷Òª½éÉܵü´ú×î½üµãËã·¨ ,c++´úÂëÀ´ÊµÏÖ £¬²¢¸½¼Ó´úÂëʾÀý£¬Ï£Íû¿ÉÒÔΪÄúµÄѧϰ´øÀ´ÊÕ»ñ¡£
ÎÄÕÂÀ´×ÔÓÚcsdn£¬ÓÉ»ðÁú¹ûAlice±à¼­ÍƼö¡£

¼ò½é£º

ÔÚά»ù°Ù¿ÆÖÐÊÇÕâÑù½éÉܵü´ú×î½üµãËã·¨¡£µü´ú×î½üµã£¨ICP£©ÊÇÒ»ÖÖÓÃÓÚ×îС»¯Á½µãÔÆÖ®¼ä²îÒìµÄËã·¨¡£¸ø¶¨P¡¢QÁ½¸öµã¼¯£¬Çó½âÐýת¾ØÕóRºÍÆ½ÒÆ¾ØÕóTʹµÃmin{distance(P,Q)}.

C++Ëã·¨Á÷³Ìͼ£º

ËÄÔªÊýÇó½â·½·¨

C++´úÂë

/**
** Filename:icp.h
** Copyright (c) 2017-2018
** Author:Rson
** Date:2018/04/03
** Modifier:
** Date:
** Description:
**
** Version:
**/
#ifndef _ICP_H
#define _ICP_H
#include <vector>
#include <string>
#include <pcl\point_cloud.h>
#include <pcl\point_types.h>
#include <pcl\visualization\pcl_visualizer.h>


struct Vertex
{
double coord[3];
};
struct Point
{
float x;
float y;
float z;
};
class ICP
{
public:
ICP();
ICP(int controlnum=1000,double thre=0.01,int iter=100);
virtual ~ICP();
void readfile(std::string firstname, std::string secondname);
void run();
void writefile(std::string name);
void showcloud(std::string firstname, std::string secondname,std::string thirdname);
private:
void initransmat();//³õʼ»¯Ðýת¾ØÕóºÍÆ½ÒÆ¾ØÕó
void sample();//²ÉÑù¿ØÖƵã
double closest();//ÕÒ³ö×î½üµã²¢·µ»ØÎó²î
void getcenter();//»ñÈ¡Á½¸ö¿ØÖƵãµÄÖÐÐÄ
void rmcontcenter();//ÒÆ¶¯Á½¸ö¿ØÖƵãµÄÖÐÐÄ
void transform();//½«ËÄÔªÊýת»»³É¾ØÕ󲢸üÐÂÕû¸öÐýת¾ØÕó
void uprotate();// ¸üб任¾ØÕó
void uptranslate();
void updata();//¸üпØÖƵã×ø±ê
void applyall();
private:
double distance(Vertex a, Vertex b);
void printTT();
void printTR();

private:
int conNum;//¿ØÖƵãÊýÄ¿
int iterate;//µü´ú´ÎÊý
double threshold;//ãÐÖµ
std::vector<Vertex> VarrP;//Æðʼµã
std::vector<Vertex> VarrQ;
Vertex meanP;//¿ØÖƵãÖÐÐÄ
Vertex meanQ;
Vertex *contP;//P¿ØÖƵã
Vertex *contQ;
Vertex *rmcoP;//ÒÆ¶¯ºóµÄ¿ØÖƵã
Vertex *rmcoQ;
int *index; //ÔÚ²ÉÑù¿ØÖƵãºÍѰÕÒÏàÓ¦µÄµãË÷ÒýʱʹÓÃ
double TT[3];//Æ½ÒÆÏòÁ¿
double TR[3][3];//Ðýת¾ØÕó
double Rw[3][3];//ÐýתµÄ²½¾à
double Tw[3];//Æ½ÒÆµÄ²½¾à
double quad[4];//ËÄÔªÊý

};
#endif /* ICP_H */


/**
** Filename:icp.cpp
** Copyright (c)
** Author:Rson
** Date:2018/04/03
** Modifier:
** Date:
** Description:
**
** Version:
**/
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <cassert>
#include <math.h>
#include <time.h>
#include <newmat10/newmat.h>
#include <newmat10/newmatap.h>
#include "ICP.h"

ICP::ICP()
{

ICP::ICP(int controlnum, double thre, int iter)
{
conNum = controlnum;
threshold = thre;
iterate = iter;
contP = new Vertex[conNum];
assert(contP != NULL);
contQ = new Vertex[conNum];
assert(contQ != NULL);
rmcoP = new Vertex[conNum];
assert(rmcoP != NULL);
rmcoQ = new Vertex[conNum];
assert(rmcoQ != NULL);
index = new int[conNum];
assert(index != NULL);
}
ICP::~ICP()
{
delete[] contP;
delete[] contQ;
delete[] rmcoP;
delete[] rmcoQ;
delete[] index;
}
void ICP::readfile(std::string firstname, std::string secondname)
{
std::cout << "¶ÁÈ¡Á½¸öµãÔÆÎļþ£¡£¡" <<std:: endl;
ifstream in;
in.open(firstname.c_str(), std::ios::in);
if (!in.is_open())
{
std::cout << "error open!" <<std:: endl;
system("pause");
}
Vertex v;
while(in>>v.coord[0]>>v.coord[1]>>v.coord[2])
{
VarrP.push_back(v);
}
std::cout << "µãÔÆAµÄ´óС£º" << VarrP.size() << std::endl;
in.close();
//
in.open(secondname.c_str(), std::ios::in);
if (!in.is_open())
{
cout << "error open!" << endl;
system("pause");
}

//Vertex v;
while (in >> v.coord[0] >> v.coord[1] >> v.coord[2])
{
VarrQ.push_back(v);
}
std::cout << "µãÔÆBµÄ´óС£º" << VarrQ.size() << std::endl;
in.close();
}
void ICP::run()
{
initransmat();
sample();
//
double err = closest();
std::cout << "³õʼÎó²î£ºerror = " << err << std::endl;
//
for (int i = 0; i<iterate; i++)
{
getcenter();
rmcontcenter();
transform();
uprotate();
uptranslate();
updata();
double newerr = closest();
std::cout << "µü´ú´ÎÊý times = " << i << std::endl;
std::cout << "error = " << newerr << std::endl;
double delta = fabs(err - newerr) / conNum;
std::cout << "delta = " << delta << std::endl;
if (delta<threshold)
break;
err = newerr;
}
printTR();
printTT();
applyall();
}
void ICP::writefile(std::string name)
{
ofstream outobj;
outobj.open(name.c_str());
//outobj << "# Geomagic Studio" << endl;
int num = 1;
for (vector<Vertex>::const_iterator p = VarrP.begin();
p != VarrP.end(); p++)
{
Vertex v;
v = *p;
outobj << v.coord[0] << " " << v.coord[1] << " "
<< v.coord[2] << endl;
//outobj << "p " << num++ << endl;
//outobj << "v " << v.coord[0] << " " << v.coord[1]
<< " " << v.coord[2] << endl;
//outobj << "p " << num++ << endl;
}
//
outobj.close();
}
//³õʼ»¯±ä»»¾ØÕó
// -
// | 1.0 0.0 0.0 | 0.0 |
// | 0.0 1.0 0.0 | 0.0 |
// | 0.0 0.0 1.0 | 0.0 |
// | -------------|----- |
// | 0.0 0.0 0.0 | 1.0 |
void ICP::initransmat()//³õʼ»¯±ä»»¾ØÕó
{
std::cout << "³õʼ»¯±ä»»¾ØÕó" << endl;
for (int i = 0; i < 3; i++)
TT[i] = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (i != j)
TR[i][j] = 0.0;
else
TR[i][j] = 1.0;
}
}
}

//Ëæ»úѡȡ¿ØÖƵã,²¢´æ´¢ÔÚcontPÖÐ
void ICP::sample()
{
std::cout<<"Ëæ»úѡȡ¿ØÖƵã,²¢´æ´¢ÔÚcontPÖÐ"<<std::endl;
int N = VarrP.size();
bool *flag = new bool[N];
assert(flag != NULL);
for (int i = 0; i < N; i++)
flag[i] = false;
//Ëæ»úÑ¡ÔñÒ»¸ö¿ØÖƵ㣬²¢¼Ç¼ÆäË÷Òý
srand((unsigned)time(NULL));
for (int i = 0; i < conNum; i++)
{
while (true)
{
int sam = rand() % N;
if (!flag[sam])
{
index[i] = sam;
flag[sam] = true;
break;
}
}
}
//cout<<"store control points into contP"<<endl;
for (int i = 0; i<conNum; i++)
{
Vertex v = VarrP[index[i]];//
for (int j = 0; j<3; j++)
{
contP[i].coord[j] = v.coord[j];
}
}
delete[] flag;
}
//ÕÒ³ö×î½üµã²¢¼ÆËãÎó²îÖ®ºÍ
double ICP::closest()
{
//find closest points and error
double error = 0.0;
for (int i = 0; i < conNum; i++)
{
double mindist = 100.0;
index[i] = 0;
for (unsigned int j = 0; j < VarrQ.size(); j++)
{
double dist = distance(contP[i], VarrQ[j]);
if (dist < mindist)
{
mindist = dist;
index[i] = j;
}
}
Vertex v = VarrQ[index[i]];
for (int j = 0; j < 3; j++)
{
contQ[i].coord[j] = v.coord[j];
}
error += mindist;
}
return error;
}
//ÇóÈ¡Á½¸öµãÔÆ¿ØÖƵãµÄÖØÐÄ
void ICP::getcenter()
{
//Ê×Ïȳõʼ»¯ÖØÐÄ×ø±ê0£¬0£¬0
for (int i = 0; i < 3; i++)
meanP.coord[i] = 0.0;
//Çóȡÿ¸ö·ÖÁ¿Ö®ºÍ
for (int i = 0; i < conNum; i++)
{
for (int j = 0; j < 3; j++)
{
meanP.coord[j] += contP[i].coord[j];
}
}
//Çóȡƽ¾ùÖµ
for (int i = 0; i < 3; i++)
meanP.coord[i] = meanP.coord[i] / conNum;
//
for (int i = 0; i < 3; i++)
meanQ.coord[i] = 0.0;
//Çóȡÿ¸ö·ÖÁ¿Ö®ºÍ
for (int i = 0; i < conNum; i++)
{
for (int j = 0; j < 3; j++)
{
meanQ.coord[j] += contQ[i].coord[j];
}
}
//Çóȡƽ¾ùÖµ
for (int i = 0; i < 3; i++)
meanQ.coord[i] = meanQ.coord[i] / conNum;
}
//µã¼¯ÖÐÐÄ»¯£¬Éú³ÉеĵãÔÆÊý¾Ý
void ICP::rmcontcenter()
{
std::cout << "µã¼¯ÖÐÐÄ»¯£¬Éú³ÉеĵãÔÆÊý¾Ý" << std::endl;
for (int i = 0; i < conNum; i++)
{
for (int j = 0; j < 3; j++)
{
rmcoP[i].coord[j] = contP[i].coord[j] - meanP.coord[j];
rmcoQ[i].coord[j] = contQ[i].coord[j] - meanQ.coord[j];
}
}
}
void ICP::transform()
{
std::cout << "»ñÈ¡±ä»»¾ØÕó" << std::endl;
Matrix B(4, 4);
B = 0;
double u[3];//di+di'
double d[3];//di-di'
//¼ÆËãЭ·½²î
for (int i = 0; i < conNum; i++)
{
for (int j = 0; j < 3; j++)
{
u[j] = rmcoP[i].coord[j] + rmcoQ[i].coord[j];
d[j] = rmcoP[i].coord[j] - rmcoQ[i].coord[j];
}
double uM[16] = {
0, -d[0], -d[1], -d[2],
d[0], 0, -u[2], -u[1],
d[1], -u[2], 0, u[0],
d[2], u[1], -u[0], 0 };
Matrix Ai(4, 4);
Ai << uM;
B += Ai * Ai.t();
}
Matrix U;
Matrix V;
DiagonalMatrix D;
SVD(B, D, U, V);
for (int i = 0; i < 4; i++)
{
quad[i] = V.element(i, 3);
}
B.Release();
U.Release();
V.Release();
D.Release();
}
void ICP::uprotate()
{
//¸ù¾ÝËÄÔªÊýÇó½âÑ¡Ôñ¾ØÕó
Rw[0][0] = quad[0] * quad[0] + quad[1] * quad[1]
- quad[2] * quad[2] - quad[3] * quad[3];
Rw[0][1] = 2 * (-quad[0] * quad[3] + quad[1] * quad[2]);
Rw[0][2] = 2 * (quad[0] * quad[2] + quad[1] * quad[3]);
Rw[1][0] = 2 * (quad[0] * quad[3] + quad[1] * quad[2]);
Rw[1][1] = quad[0] * quad[0] - quad[1] * quad[1] + quad[2]
* quad[2] - quad[3] * quad[3];
Rw[1][2] = 2 * (-quad[0] * quad[1] + quad[2] * quad[3]);
Rw[2][0] = 2 * (-quad[0] * quad[2] + quad[1] * quad[3]);
Rw[2][1] = 2 * (quad[0] * quad[1] + quad[2] * quad[3]);
Rw[2][2] = quad[0] * quad[0] - quad[1] * quad[1] - quad[2]
* quad[2] + quad[3] * quad[3];
//Rn+1 = R * Rn
double tmp[3][3];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
tmp[i][j] = 0;
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
tmp[i][j] += Rw[i][k] * TR[k][j];
}
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
TR[i][j] = tmp[i][j];
}
}
void ICP::uptranslate()
{
//Tw = P'-Rw * P
double tmp[3] = { 0, 0, 0 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
tmp[i] += Rw[i][j] * meanP.coord[j];
}
}
for (int i = 0; i < 3; i++)
{
Tw[i] = meanQ.coord[i] - tmp[i];
}
double temp[3] = { 0, 0, 0 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
temp[i] += Rw[i][j] * TT[j];
}
}
for (int i = 0; i < 3; i++)
{
TT[i] = temp[i] + Tw[i];
}
}
void ICP::updata()
{
for (int i = 0; i < conNum; i++)
{
double tmp[3] = { 0, 0, 0 };
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
tmp[j] += Rw[j][k] * contP[i].coord[k];
}
}
for (int j = 0; j < 3; j++)
contP[i].coord[j] = tmp[j] + Tw[j];
}
}
void ICP::applyall()
{
for (vector<Vertex>::iterator p = VarrP.begin();
p != VarrP.end(); p++)
{
Vertex v = *p;
double tmp[3] = { 0, 0, 0 };
for (int i = 0; i < 3; i++)
{
for (int k = 0; k < 3; k++)
{
tmp[i] += TR[i][k] * v.coord[k];
}
}
for (int i = 0; i < 3; i++)
{
v.coord[i] = tmp[i] + TT[i];
}
*p = v;
}
}
double ICP::distance(Vertex a, Vertex b)
{
double dist = 0.0;
for (int i = 0; i < 3; i++)
{
dist += (a.coord[i] - b.coord[i])*(a.coord[i] - b.coord[i]);
}
return dist;
}
void ICP::printTT()
{
std::cout << "Translate Matrix = " << std::endl;
for (int i = 0; i < 3; i++)
{
std::cout << TT[i] << " ";
}
std::cout << std::endl;
}
void ICP::printTR()
{
std::cout << "Rotate Matrix = " << std::endl;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
std::cout << TR[i][j] << " ";
}
std::cout << std::endl;
}
}
void ICP::showcloud(std::string firstname,
std::string secondname,std::string thirdname)
{
pcl::PointCloud<pcl::PointXYZ>::
Ptr cloud_Target(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::
Ptr cloud_Source(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::
Ptr cloudOut(new pcl::PointCloud<pcl::PointXYZ>);
std::cout << "ÏÔʾÁ½¸öµãÔÆ£º" << std::endl;
//µÚÒ»¸öµãÔÆÊý¾Ý
ifstream in;
in.open(firstname.c_str(), std::ios::in);
if (!in.is_open())
{
std::cout << "error open!" << std::endl;
system("pause");
}
vector<Point> points;
points.clear();
Point tmp;
while (in >> tmp.x >> tmp.y >> tmp.z)
{
points.push_back(tmp);
}
pcl::PointXYZ cltmp;
for (size_t i = 0; i != points.size();i++)
{
cltmp.x = points[i].x;
cltmp.y = points[i].y;
cltmp.z = points[i].z;
cloud_Target->points.push_back(cltmp);
}
std::cout << "µãÔÆAµÄ´óС£º" << cloud_Target->size()
<< std::endl;
in.close();
//µÚ¶þ¸öµãÔÆÊý¾Ý
in.open(secondname.c_str(), std::ios::in);
if (!in.is_open())
{
std::cout << "error open!" << std::endl;
system("pause");
}
points.clear();
while (in >> tmp.x >> tmp.y >> tmp.z)
{
points.push_back(tmp);
}
//pcl::PointXYZ cltmp;
for (size_t i = 0; i != points.size(); i++)
{
cltmp.x = points[i].x;
cltmp.y = points[i].y;
cltmp.z = points[i].z;
cloud_Source->points.push_back(cltmp);
}
std::cout << "µãÔÆBµÄ´óС£º" << cloud_Source->size()
<< std::endl;
in.close();
//µÚÈý¸öµãÔÆÊý¾Ý
in.open(thirdname.c_str(), std::ios::in);
if (!in.is_open())
{
std::cout << "error open!" << std::endl;
system("pause");
}
points.clear();
while (in >> tmp.x >> tmp.y >> tmp.z)
{
points.push_back(tmp);
}
//pcl::PointXYZ cltmp;
for (size_t i = 0; i != points.size(); i++)
{
cltmp.x = points[i].x;
cltmp.y = points[i].y;
cltmp.z = points[i].z;
cloudOut->points.push_back(cltmp);
}
std::cout << "µãÔÆCµÄ´óС£º" << cloudOut->size() << std::endl;
in.close();

//¿ÉÊÓ»¯³õʼ»¯
pcl::visualization::PCLVisualizer viewer;
viewer.setCameraFieldOfView(0.785398);//fov 45¡ã ÊÓ³¡½Ç
viewer.setBackgroundColor(0.2, 0.2, 0.2);
viewer.setCameraPosition(
0, 0, 0,
0, 0, -1,
0, 0, 0);
//µãÔÆ¿ÉÊÓ»¯
pcl::visualization::PointCloudColorHandlerCustom
<pcl::PointXYZ> TargetHandler(cloud_Target, 255, 0, 0);
pcl::visualization::PointCloudColorHandlerCustom
<pcl::PointXYZ> SourceHandler(cloud_Source, 0, 0, 255);
pcl::visualization::PointCloudColorHandlerCustom
<pcl::PointXYZ> OutHandler(cloudOut, 0, 255, 0);
viewer.addPointCloud(cloud_Target, TargetHandler, "cloud_Target");
viewer.addPointCloud(cloud_Source, SourceHandler, "cloud_Source");
viewer.addCoordinateSystem(0.1, "cloud", 0);

int v2 = 1;
viewer.createViewPort(0.5, 0, 1, 1, v2);
viewer.createViewPortCamera(v2);
viewer.setCameraFieldOfView(0.785398, v2);//fov 45¡ã
viewer.setBackgroundColor(0.2, 0.2, 0.2,v2);
viewer.setCameraPosition(
0, 0, 0,
0, 0, -1,
0, 0, 0,v2);
//µãÔÆ¿ÉÊÓ»¯
viewer.addPointCloud(cloud_Target, TargetHandler, "cloud222", v2);
viewer.addPointCloud(cloudOut, OutHandler, "cloudOut",v2);
viewer.addCoordinateSystem(0.1, "cloud1", v2);
while(!viewer.wasStopped())
{
viewer.spinOnce();
}
}

//Ö÷³ÌÐò
#include "stdafx.h"
#include <iostream>
#include <pcl\common\transforms.h>
#include <pcl\io\pcd_io.h>
#include <pcl\visualization\pcl_visualizer.h>
#include <pcl\registration\icp.h>
#include "ICP.h">
#include <iostream>
#include <time.h>
int main()
{
clock_t start, finish;
start = clock();
ICP myicp(1000, 0.00001, 50);
myicp.readfile("bunny_0.asc", "bunny_1.asc");
myicp.run();
myicp.writefile("out.asc");
finish = clock();
std::cout << "ÔËÐÐʱ¼ä£º" << (finish - start) / 1000 << "s" << std::endl;
myicp.showcloud("bunny_0.asc", "bunny_1.asc", "out.asc");
system("pause");
return 0;
}
   
3905 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]
 
×îÐÂÎÄÕÂ
.NET Core 3.0 Õýʽ¹«²¼£ºÐÂÌØÐÔÏêϸ½â¶Á
.NET Core²¿ÊðÖÐÄã²»Á˽âµÄ¿ò¼ÜÒÀÀµÓë¶ÀÁ¢²¿Êð
C# eventḬ̈߳²È«
¼òÎö .NET Core ¹¹³ÉÌåϵ
C#¼¼ÊõÂþ̸֮À¬»ø»ØÊÕ»úÖÆ(GC)
×îпγÌ
.NetÓ¦Óÿª·¢
C#¸ß¼¶¿ª·¢¼¼Êõ
.NET ¼Ü¹¹Éè¼ÆÓëµ÷ÊÔÓÅ»¯
ASP.NET Core Web ¿ª·¢
ASP.Net MVC¿ò¼ÜÔ­ÀíÓëÓ¦Óÿª·¢
³É¹¦°¸Àý
º½Ìì¿Æ¹¤¼¯ÍÅ×Ó¹«Ë¾ DotNetÆóÒµ¼¶Ó¦ÓÃÉè¼ÆÓ뿪·¢
ÈÕÕÕ¸Û¼¯ .NET Framewor
Éñ»ªÐÅ .NETµ¥Ôª²âÊÔ
̨´ïµç×Ó .NET³ÌÐòÉè¼ÆÓ뿪·¢
Éñ»ªÐÅÏ¢ .NETµ¥Ôª²âÊÔ