Commit d448a6d4 张士柳

1 个父辈 0871eb39
...@@ -7,7 +7,6 @@ using System.Drawing; ...@@ -7,7 +7,6 @@ using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Threading; using System.Threading;
using System.IO; using System.IO;
using System.Linq;
namespace eyemLib_Sharp namespace eyemLib_Sharp
{ {
...@@ -1022,6 +1021,22 @@ namespace eyemLib_Sharp ...@@ -1022,6 +1021,22 @@ namespace eyemLib_Sharp
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemClassifier(EyemImage tpImage); private static extern int eyemClassifier(EyemImage tpImage);
/// <summary>
/// 初始化ONNX模型(10.0)
/// </summary>
/// <param name="extractorModelPath">模型路径</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemInitONNXModel(string extractorModelPath);
/// <summary>
/// 特征提取器
/// </summary>
/// <param name="tpImage">图像(128X128)</param>
/// <param name="fFeatures">特征</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemExtractWithONNX(EyemImage tpImage, [MarshalAs(UnmanagedType.LPArray)]float[] fFeatures);
#endregion #endregion
#region 模板匹配 #region 模板匹配
...@@ -1109,6 +1124,21 @@ namespace eyemLib_Sharp ...@@ -1109,6 +1124,21 @@ namespace eyemLib_Sharp
private static extern void loadImage2Mem(string key, EyemImage tpImage); private static extern void loadImage2Mem(string key, EyemImage tpImage);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int setProcessLevel(double pl); private static extern int setProcessLevel(double pl);
/// <summary>
/// 对图像进行采样生成训练样本
/// </summary>
/// <param name="tpImage">图像</param>
/// <param name="iSize">尺寸128(最大224)</param>
/// <param name="ccClassName">类名</param>
/// <param name="ccToPath">保存路径</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemTrainImageSampler(EyemImage tpImage, int iSize, string ccClassName, string ccToPath, out EyemImage tpMatchImg, out EyemImage tpDstImg);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemBuildTrainFile(string filePath, string fileName, bool shuffle = true);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern float calcSimilarity([MarshalAs(UnmanagedType.LPArray)]float[] lhs, [MarshalAs(UnmanagedType.LPArray)]float[] rhs);
#endregion #endregion
#region 测试专用接口 #region 测试专用接口
...@@ -1118,9 +1148,6 @@ namespace eyemLib_Sharp ...@@ -1118,9 +1148,6 @@ namespace eyemLib_Sharp
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemEdge1dRidgeDetection(EyemImage tpImage); private static extern int eyemEdge1dRidgeDetection(EyemImage tpImage);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemBuildTrainFile(string filePath, string fileName);
#endregion #endregion
#region 日志功能 #region 日志功能
...@@ -1154,6 +1181,8 @@ namespace eyemLib_Sharp ...@@ -1154,6 +1181,8 @@ namespace eyemLib_Sharp
//eyemInitNNDataCodeModel(".\\darknet\\detect-tiny.cfg", ".\\darknet\\detect-tiny.weights", ".\\darknet\\sr.prototxt", ".\\darknet\\sr.caffemodel"); //eyemInitNNDataCodeModel(".\\darknet\\detect-tiny.cfg", ".\\darknet\\detect-tiny.weights", ".\\darknet\\sr.prototxt", ".\\darknet\\sr.caffemodel");
//eyemInitClassifier("D:\\detect-tiny-tray.cfg", "D:\\detect-tiny-tray.weights", 0); //eyemInitClassifier("D:\\detect-tiny-tray.cfg", "D:\\detect-tiny-tray.weights", 0);
//eyemInitONNXModel("D:\\训练数据集\\Parts-11\\backup\\ec_model.onnx");
} }
public static void Free() public static void Free()
...@@ -1208,7 +1237,6 @@ namespace eyemLib_Sharp ...@@ -1208,7 +1237,6 @@ namespace eyemLib_Sharp
Stopwatch sw = new Stopwatch(); Stopwatch sw = new Stopwatch();
sw.Restart(); sw.Restart();
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2]; string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//string[] fileNames = Directory.GetFiles(@"C:\Users\nzslw\PycharmProjects\pythonProject\venv\data\AntBee\test\ants", "*.jpg", SearchOption.AllDirectories); //string[] fileNames = Directory.GetFiles(@"C:\Users\nzslw\PycharmProjects\pythonProject\venv\data\AntBee\test\ants", "*.jpg", SearchOption.AllDirectories);
//eyemBuildTrainFile(@"D:\darknet-master\build\darknet\x64\data\val_images", "D:/val.txt"); //eyemBuildTrainFile(@"D:\darknet-master\build\darknet\x64\data\val_images", "D:/val.txt");
//return; //return;
...@@ -1221,7 +1249,6 @@ namespace eyemLib_Sharp ...@@ -1221,7 +1249,6 @@ namespace eyemLib_Sharp
//List<string> random_shuffle = new List<string>(fileNames); //List<string> random_shuffle = new List<string>(fileNames);
////随机打乱顺序 ////随机打乱顺序
//RandomShuffle(random_shuffle); //RandomShuffle(random_shuffle);
//bool HaveDuplicates = random_shuffle.GroupBy(i => i).Where(g => g.Count() > 1).Count() >= 1; //bool HaveDuplicates = random_shuffle.GroupBy(i => i).Where(g => g.Count() > 1).Count() >= 1;
//for (int i = 0; i < fileNames.Length; i++) //for (int i = 0; i < fileNames.Length; i++)
...@@ -1274,15 +1301,30 @@ namespace eyemLib_Sharp ...@@ -1274,15 +1301,30 @@ namespace eyemLib_Sharp
//tpHsvModel.dpRangeL = new double[] { 100, 43, 46 }; tpHsvModel.dpRangeU = new double[] { 124, 255, 255 }; //tpHsvModel.dpRangeL = new double[] { 100, 43, 46 }; tpHsvModel.dpRangeU = new double[] { 124, 255, 255 };
//tpHsvModel.dpRangeLExt = new double[] { 0, 0, 0 }; tpHsvModel.dpRangeUExt = new double[] { 0, 0, 0 }; //tpHsvModel.dpRangeLExt = new double[] { 0, 0, 0 }; tpHsvModel.dpRangeUExt = new double[] { 0, 0, 0 };
//eyemClassifier(image); //eyemClassifier(image);
flag = eyemLibImpl(image, out tpDstImg); //flag = eyemLibImpl(image, out tpDstImg);
//float[] fFeatures = new float[512];
//eyemExtractWithONNX(image, fFeatures);
//string ftrs = string.Join(" ", fFeatures).Trim();
//using (FileStream fs = new FileStream("D:\\Resout\\" + file.Replace("png", "txt"), FileMode.Create))
//{
// using (StreamWriter pr = new StreamWriter(fs))
// {
// pr.WriteLine(ftrs);
// pr.Flush();
// }
//}
//EyemImage tpMatchImg;
//eyemTrainImageSampler(image, 128, "PID012", "D:\\ResOut", out tpMatchImg, out tpDstImg);
//eyemBuildTrainFile("D:\\test", "");
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg); //Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null) //if (bitmap != null)
//{ //{
// bitmap.Save("D:\\ResOut\\" + file); // bitmap.Save("D:\\ResOut\\" + file);
//} //}
//eyemImageFree(ref tpMatchImg);
//eyemImageFree(ref tpDstImg); //eyemImageFree(ref tpDstImg);
//eyemImageFree(ref image); //eyemImageFree(ref image);
return; //return;
//EyemImage templ, search; //EyemImage templ, search;
//flag = eyemImageRead("D://批量测试图像//template.png", -1, out templ); //flag = eyemImageRead("D://批量测试图像//template.png", -1, out templ);
...@@ -1498,11 +1540,10 @@ namespace eyemLib_Sharp ...@@ -1498,11 +1540,10 @@ namespace eyemLib_Sharp
#endregion #endregion
EyemRect tpRoi = new EyemRect(); EyemRect tpRoi = new EyemRect();
tpRoi.iXs = 50; tpRoi.iYs = 50; tpRoi.iXs = 200; tpRoi.iYs = 200;
tpRoi.iWidth = image.iWidth - 100; tpRoi.iWidth = image.iWidth - 400;
tpRoi.iHeight = image.iHeight - 100; tpRoi.iHeight = image.iHeight - 400;
flag = eyemAchvMatchMat(image, tpRoi, out tpDstImg);
//flag = eyemAchvMatchMat(image, tpRoi, out tpDstImg);
//EyemOcsDXYR tpCircle = new EyemOcsDXYR(); //EyemOcsDXYR tpCircle = new EyemOcsDXYR();
//EyemRect limRoi = new EyemRect(); //EyemRect limRoi = new EyemRect();
//limRoi.iXs = 222; limRoi.iYs = 222; //limRoi.iXs = 222; limRoi.iYs = 222;
...@@ -1517,7 +1558,7 @@ namespace eyemLib_Sharp ...@@ -1517,7 +1558,7 @@ namespace eyemLib_Sharp
//} //}
//eyemImageFree(ref tpDstImg); //eyemImageFree(ref tpDstImg);
//eyemImageFree(ref image); //eyemImageFree(ref image);
//return; return;
//获取用于制作模板的图像 //获取用于制作模板的图像
//flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg); //flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
......
#include "azONNXWrapper.h"
int AZONNXWrapper::init(const std::string& model_path)
{
if (!model_path.empty()) {
//加载并初始化网络
net_ = cv::dnn::readNetFromONNX(model_path);
net_.setPreferableBackend(cv::dnn::Backend::DNN_BACKEND_OPENCV);
net_.setPreferableTarget(cv::dnn::Target::DNN_TARGET_CPU);
return 0;
}
return -1;
}
float* AZONNXWrapper::forward(cv::Mat img, cv::Scalar mean, cv::Scalar std)
{
CV_Assert(!img.empty());
//图像预处理,仅支持三通道
cv::Mat input;
int incn = img.channels();
if (incn < 3) {
cv::cvtColor(img, input, cv::COLOR_GRAY2RGB);
}
else if (incn > 3) {
cv::cvtColor(img, input, cv::COLOR_BGR2RGB);
}
else {
input = img.clone();
}
//转float类型
input.convertTo(input, CV_32F, 1 / 255.);
//预处理
cv::subtract(input, mean, input);
cv::divide(input, std, input);
//设定输出
cv::Mat blob = cv::dnn::blobFromImage(input);
net_.setInput(blob);
//推理
cv::Mat predicts = net_.forward();
//
for (int i = 0; i < 512; i++) predictions[i] = predicts.ptr<float>(0)[i];
return predictions;
}
AZONNXWrapper::AZONNXWrapper() {
}
AZONNXWrapper::~AZONNXWrapper()
{
delete[] predictions;
predictions = NULL;
}
\ No newline at end of file \ No newline at end of file
#pragma once
//
// azONNXWrapperͷ
//
#ifndef __AZONNXWRAPPER_H
#define __AZONNXWRAPPER_H
#include "opencv2/dnn.hpp"
#include "opencv2/imgproc.hpp"
class AZONNXWrapper
{
public:
AZONNXWrapper();
~AZONNXWrapper();
int init(const std::string& model_path);
float* forward(cv::Mat img, cv::Scalar mean, cv::Scalar std);
private:
float* predictions = new float[512];
cv::dnn::Net net_;
};
#endif/* __AZONNXWRAPPER_H */
#include "eyemFeatureExtractor.h"
class Extractor::Impl {
public:
Impl() {}
~Impl() {}
//ȡ
std::vector<float> forward(const cv::Mat& img, cv::Scalar mean, cv::Scalar std);
//ȡ
std::shared_ptr<AZONNXWrapper> extractor_;
};
Extractor::Extractor(const std::string& model_path)
{
p = cv::makePtr<Extractor::Impl>();
if (!model_path.empty()) {
p->extractor_ = std::make_shared<AZONNXWrapper>();
p->extractor_->init(model_path);
}
else {
p->extractor_ = NULL;
}
}
std::vector<float> Extractor::extract(cv::InputArray img)
{
return p->forward(img.getMat(), cv::Scalar(0.449, 0.449, 0.449), cv::Scalar(0.226, 0.226, 0.226));
}
std::vector<float> Extractor::Impl::forward(const cv::Mat& img, cv::Scalar mean, cv::Scalar std)
{
std::vector<float> predictions(512);
float* outputs = extractor_->forward(img, mean, std);
for (int i = 0; i < 512; i++) predictions[i] = outputs[i];
return predictions;
}
int eyemInitONNXModel(const char *extractorModelPath)
{
try {
pExtractor = cv::makePtr<Extractor>(extractorModelPath);
}
catch (const std::exception& e) {
std::cout << e.what() << std::endl;
return FUNC_CANNOT_CALC;
}
return FUNC_OK;
}
int eyemExtractWithONNX(EyemImage tpImage, float *fFeatures)
{
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
auto predicts = pExtractor->extract(src);
for (int i = 0; i < 512; i++) fFeatures[i] = predicts[i];
return FUNC_OK;
}
float getMold(float *vector)
{
float mold2 = .0f;
for (int i = 0; i < 512; i++) {
mold2 += vector[i] * vector[i];
}
return sqrt(mold2);
}
float calcSimilarity(float *lhs, float *rhs)
{
float ip = .0f;
for (int i = 0; i < 512; i++) {
ip += lhs[i] * rhs[i];
}
return ip / (getMold(lhs)*getMold(rhs));
}
\ No newline at end of file \ No newline at end of file
#pragma once
//
// eyemFeatureExtractorͷ
//
#ifndef __EYEMFEATUREEXTRACTOR_H
#define __EYEMFEATUREEXTRACTOR_H
#include "eyemLib.h"
#include "azONNXWrapper.h"
class Extractor {
public:
Extractor(const std::string& model_path);
Extractor() {};
//ü
std::vector<float> extract(cv::InputArray img);
protected:
class Impl;
cv::Ptr<Impl> p;
};
cv::Ptr<Extractor> pExtractor;
#endif/* __EYEMFEATUREEXTRACTOR_H */
...@@ -93,7 +93,6 @@ int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, ...@@ -93,7 +93,6 @@ int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth,
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
FILE *fp = fopen(filename, "rb+"); FILE *fp = fopen(filename, "rb+");
if (NULL != fp) if (NULL != fp)
{ {
switch (iDepth) switch (iDepth)
...@@ -122,7 +121,6 @@ int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, ...@@ -122,7 +121,6 @@ int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth,
//关闭文件 //关闭文件
fclose(fp); fclose(fp);
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -855,7 +855,7 @@ extern "C" { ...@@ -855,7 +855,7 @@ extern "C" {
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// 深度学习目标检测器(eyemNNDetector.cpp) // 深度学习目标检测/特征提取器(eyemNNDetector.cpp)
// //
typedef struct { typedef struct {
...@@ -872,6 +872,8 @@ extern "C" { ...@@ -872,6 +872,8 @@ extern "C" {
EXPORTS int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, EyemImage *tpDstImg); EXPORTS int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, EyemImage *tpDstImg);
EXPORTS int eyemInitClassifier(const char *classifierConfigPath, const char *classifierModelPath, int ntype); EXPORTS int eyemInitClassifier(const char *classifierConfigPath, const char *classifierModelPath, int ntype);
EXPORTS int eyemClassifier(EyemImage tpImage); EXPORTS int eyemClassifier(EyemImage tpImage);
EXPORTS int eyemInitONNXModel(const char *extractorModelPath);
EXPORTS int eyemExtractWithONNX(EyemImage tpImage, float *fFeatures);
#ifdef __cplusplus #ifdef __cplusplus
...@@ -932,7 +934,8 @@ extern "C" { ...@@ -932,7 +934,8 @@ extern "C" {
EXPORTS int eyemDrawLine(EyemImage tpImage, EyemOcsDABC tpLine); EXPORTS int eyemDrawLine(EyemImage tpImage, EyemOcsDABC tpLine);
EXPORTS int eyemDrawCircle(EyemImage tpImage, EyemOcsDXYR tpCircle); EXPORTS int eyemDrawCircle(EyemImage tpImage, EyemOcsDXYR tpCircle);
EXPORTS int eyemDrawRectangle(EyemImage tpImag, EyemRect tpRect); EXPORTS int eyemDrawRectangle(EyemImage tpImag, EyemRect tpRect);
EXPORTS int eyemBuildTrainFile(const char *filePath, const char *fileName); EXPORTS int eyemTrainImageSampler(EyemImage tpImage, int iSize, const char *ccClassName, const char *ccToPath, EyemImage *tpMatchImg, EyemImage *tpDstImg);
EXPORTS int eyemBuildTrainFile(const char *filePath, const char *fileName, bool shuffle = true);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -941,12 +944,15 @@ extern "C" { ...@@ -941,12 +944,15 @@ extern "C" {
// 跳过某接口执行 // 跳过某接口执行
extern "C" __declspec(dllexport) void setSkipProcessID(int pid); extern "C" __declspec(dllexport) void setSkipProcessID(int pid);
//设置全局参数 // 设置全局参数
extern "C" __declspec(dllexport) void setProcessLevel(double pl); extern "C" __declspec(dllexport) void setProcessLevel(double pl);
// 加载图像到内存 // 加载图像到内存
extern "C" __declspec(dllexport) void loadImage2Mem(const char *key, EyemImage tpImage); extern "C" __declspec(dllexport) void loadImage2Mem(const char *key, EyemImage tpImage);
// 计算余弦相似度
extern "C" __declspec(dllexport) float calcSimilarity(float *lhs, float *rhs);
// 日志回调定义 // 日志回调定义
typedef void(__stdcall*TCallback)(const char* msg); typedef void(__stdcall*TCallback)(const char* msg);
......
此文件类型无法预览
...@@ -165,6 +165,7 @@ ...@@ -165,6 +165,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="azONNXWrapper.h" />
<ClInclude Include="barcodeDetector.h" /> <ClInclude Include="barcodeDetector.h" />
<ClInclude Include="eyemDataCode.h" /> <ClInclude Include="eyemDataCode.h" />
<ClInclude Include="eyemBin.h" /> <ClInclude Include="eyemBin.h" />
...@@ -172,6 +173,7 @@ ...@@ -172,6 +173,7 @@
<ClInclude Include="eyemClp2d.h" /> <ClInclude Include="eyemClp2d.h" />
<ClInclude Include="eyemEdge.h" /> <ClInclude Include="eyemEdge.h" />
<ClInclude Include="eyemEdge1d.h" /> <ClInclude Include="eyemEdge1d.h" />
<ClInclude Include="eyemFeatureExtractor.h" />
<ClInclude Include="eyemFit.h" /> <ClInclude Include="eyemFit.h" />
<ClInclude Include="eyemGeneric.h" /> <ClInclude Include="eyemGeneric.h" />
<ClInclude Include="eyemLib.h" /> <ClInclude Include="eyemLib.h" />
...@@ -187,6 +189,7 @@ ...@@ -187,6 +189,7 @@
<ClInclude Include="yoloWrapper.h" /> <ClInclude Include="yoloWrapper.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="azONNXWrapper.cpp" />
<ClCompile Include="barcodeDetector.cpp" /> <ClCompile Include="barcodeDetector.cpp" />
<ClCompile Include="eyemDataCode.cpp" /> <ClCompile Include="eyemDataCode.cpp" />
<ClCompile Include="eyemBin.cpp" /> <ClCompile Include="eyemBin.cpp" />
...@@ -196,6 +199,7 @@ ...@@ -196,6 +199,7 @@
<ClCompile Include="eyemClp3d.cpp" /> <ClCompile Include="eyemClp3d.cpp" />
<ClCompile Include="eyemEdge.cpp" /> <ClCompile Include="eyemEdge.cpp" />
<ClCompile Include="eyemEdge1d.cpp" /> <ClCompile Include="eyemEdge1d.cpp" />
<ClCompile Include="eyemFeatureExtractor.cpp" />
<ClCompile Include="eyemFit.cpp" /> <ClCompile Include="eyemFit.cpp" />
<ClCompile Include="eyemGeneric.cpp" /> <ClCompile Include="eyemGeneric.cpp" />
<ClCompile Include="eyemLib.cpp" /> <ClCompile Include="eyemLib.cpp" />
......
...@@ -75,6 +75,12 @@ ...@@ -75,6 +75,12 @@
<ClInclude Include="eyemStopwatch.h"> <ClInclude Include="eyemStopwatch.h">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="azONNXWrapper.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemFeatureExtractor.h">
<Filter>源文件</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="eyemLib.cpp"> <ClCompile Include="eyemLib.cpp">
...@@ -146,6 +152,12 @@ ...@@ -146,6 +152,12 @@
<ClCompile Include="eyemStopwatch.cpp"> <ClCompile Include="eyemStopwatch.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="azONNXWrapper.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemFeatureExtractor.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="eyemLib.rc"> <ResourceCompile Include="eyemLib.rc">
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!