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">
......
...@@ -6910,37 +6910,32 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char ...@@ -6910,37 +6910,32 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char
int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg) int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone(); CV_Assert(NULL != tpImage.vpImage);
if (src.empty()) {
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (image.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
if (image.channels() > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2BGR);
} }
//转单通道 //转单通道
if (src.channels() != 1) if (image.channels() != 1)
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY); cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
//跳过执行
if (killProcessID == 0) {
logger.t("eyemCountObjectIrregularPartsE 初始阶段被跳过执行...");
return FUNC_CANNOT_CALC;
}
//图像裁剪 //图像裁剪
src = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone(); cv::Mat src = image(cv::Rect(200, 200, image.cols - 400, image.rows - 400)).clone();
//image size //image size
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
//用于去除黑色坏点干扰
cv::Mat medBlur;
cv::medianBlur(src, medBlur, 3);
//去除局部量斑影响(默认亮斑尺寸不会大于15个像素) //去除局部量斑影响(默认亮斑尺寸不会大于15个像素)
cv::Mat srcTmp; cv::morphologyEx(medBlur, medBlur, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
cv::morphologyEx(src, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
//去除黑斑影响
int m = cvRound(cv::mean(src)[0]);
srcTmp.forEach<uint16_t>([&](uint16_t& pixel, const int *pos)->void {
pixel = pixel == 0 ? m : pixel;
});
//图像增强 //图像增强
double min, max; double min, max;
cv::Point maxId; cv::minMaxLoc(medBlur, &min, &max, NULL);
cv::minMaxLoc(srcTmp, &min, &max, NULL, &maxId);
src.convertTo(src, CV_64FC1); src.convertTo(src, CV_64FC1);
src -= min; src -= min;
...@@ -6950,6 +6945,8 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg) ...@@ -6950,6 +6945,8 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
cv::Mat src8U; cv::Mat src8U;
src.convertTo(src8U, CV_8UC1, 1 / 255.); src.convertTo(src8U, CV_8UC1, 1 / 255.);
cv::Mat output = src8U.clone();
//显示结果图像 //显示结果图像
cv::Mat cc; cv::Mat cc;
cv::cvtColor(src8U, cc, cv::COLOR_GRAY2BGRA); cv::cvtColor(src8U, cc, cv::COLOR_GRAY2BGRA);
...@@ -6965,7 +6962,7 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg) ...@@ -6965,7 +6962,7 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
int maxIdx[2] = { 255,255 }; int maxIdx[2] = { 255,255 };
cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx); cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx);
//背景阈值 //背景阈值
int backThresh = 15 * cvRound(((double)maxIdx[0] - 2));//正常-2 int backThresh = 15 * cvRound(((double)maxIdx[0] - 4));//正常-2
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void { cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void {
for (int y = range.start; y < range.end; y++) { for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < X; x++) { for (int x = 0; x < X; x++) {
...@@ -6987,17 +6984,17 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg) ...@@ -6987,17 +6984,17 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
std::vector<std::vector<cv::Point>> contoursFilter; std::vector<std::vector<cv::Point>> contoursFilter;
cv::findContours(binary, contoursFilter, cv::RETR_TREE, cv::CHAIN_APPROX_NONE); cv::findContours(binary, contoursFilter, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
//填充内部确定料盘 //填充内部确定料盘
cv::Mat image = cv::Mat::zeros(src8U.size(), CV_8UC1); cv::Mat image2 = cv::Mat::zeros(src8U.size(), CV_8UC1);
for (int i = 0; i < contoursFilter.size(); i++) for (int i = 0; i < contoursFilter.size(); i++)
{ {
if (cv::contourArea(contoursFilter[i]) > 100000) if (cv::contourArea(contoursFilter[i]) > 100000)
{ {
cv::drawContours(image, contoursFilter, i, cv::Scalar(255), -1); cv::drawContours(image2, contoursFilter, i, cv::Scalar(255), -1);
} }
} }
cv::bitwise_not(src8U, src8U); cv::bitwise_not(src8U, src8U);
//剩下即料盘区域(面积大于100000均认为是料盘) //剩下即料盘区域(面积大于100000均认为是料盘)
cv::findContours(image, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); cv::findContours(image2, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
//区分多个料盘 //区分多个料盘
struct TrayPos struct TrayPos
{ {
...@@ -7009,7 +7006,7 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg) ...@@ -7009,7 +7006,7 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
TrayPos() {}; TrayPos() {};
TrayPos(cv::Point2f center, cv::Mat tray, bool bSorted, double dBackThresh) :Center(center), Tray(tray), bSorted(bSorted), dBackThresh(dBackThresh) {} TrayPos(cv::Point2f center, cv::Mat tray, bool bSorted, double dBackThresh) :Center(center), Tray(tray), bSorted(bSorted), dBackThresh(dBackThresh) {}
}; };
std::vector <TrayPos> trays; std::vector<cv::Mat> matchMats; std::vector <TrayPos> trays;
for (int i = 0; i < contoursFilter.size(); i++) for (int i = 0; i < contoursFilter.size(); i++)
{ {
//定位中心 //定位中心
...@@ -7022,33 +7019,83 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg) ...@@ -7022,33 +7019,83 @@ int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
cv::Mat tray = cv::Mat(Y, X, CV_8UC1, backThresh); cv::Mat tray = cv::Mat(Y, X, CV_8UC1, backThresh);
src8U.copyTo(tray, trayMask); src8U.copyTo(tray, trayMask);
trays.push_back(TrayPos(reelCenter, tray, false, backThresh)); trays.push_back(TrayPos(reelCenter, tray, false, backThresh));
//获取局部图像
cv::Rect bbox = cv::boundingRect(contoursFilter[i]);
cv::Point pt(bbox.tl().x + bbox.width / 2, bbox.tl().y);
cv::Rect limit(cv::Point2i(pt.x - 112, pt.y), cv::Point2i(pt.x + 112, pt.y + 224));
matchMats.push_back(cc(limit).clone());
} }
if (matchMats.empty()) { if (trays.empty()) {
return FUNC_CANNOT_CALC; return FUNC_CANNOT_CALC;
} }
cv::Mat matchMat; cv::Mat srcPrev, srcPrevB;
cv::cvtColor(matchMats[0], matchMat, cv::COLOR_BGRA2BGR); cv::bitwise_not(trays[0].Tray, srcPrev);
//备份
srcPrevB = srcPrev.clone();
//二值化可以分别放在两个算法里
cv::Mat sinParts;
cv::threshold(srcPrev, sinParts, (255 - trays[0].dBackThresh), 255, cv::THRESH_BINARY);
//判断元件尺寸
int sinPartSize;
bool useTrackMethod = checkSize(srcPrev, sinParts, sinPartSize);
//连在一起
cv::morphologyEx(sinParts, sinParts, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45)));
//间隔采样,避免采样数量过大
cv::Point start = cv::Point((int)trays[0].Center.x, (int)trays[0].Center.y), end = cv::Point((int)trays[0].Center.x, 0);
//画中心
cv::drawMarker(cc, start, cv::Scalar(0, 0, 238, 255), 1, 35, 2);
//画标记
cv::putText(cc, "OK", cv::Point(170, 270), cv::FONT_HERSHEY_COMPLEX, 8, cv::Scalar(0, 100, 0, 255), 8);
//偏移两侧取更多样本
cv::Point Offset[3] = { cv::Point(-90,0),cv::Point(0,0),cv::Point(90,0) };
//返回中间一根线的中点位置图像
std::vector<cv::Mat> mats; cv::Mat templateMat;
for (auto&ofset : Offset)
{
cv::Point nstart = start + ofset; cv::Point nend = end + ofset;
//cv::line(cc, nstart, nend, cv::Scalar(0, 255, 0, 255));
//<输出结果图像 cv::Mat linesample(image2.rows, image2.cols, CV_8UC1, cv::Scalar(0));
tpDstImg->iWidth = matchMat.cols; tpDstImg->iHeight = matchMat.rows; tpDstImg->iDepth = matchMat.depth(); tpDstImg->iChannels = matchMat.channels(); cv::line(linesample, nstart, nend, cv::Scalar(255), 1);
cv::Mat sampleLine;
cv::bitwise_and(linesample, sinParts, sampleLine);
std::vector<cv::Point> idx;
cv::findNonZero(sampleLine, idx);
//
if (idx.empty())
{
return FUNC_CANNOT_CALC;
}
//保存中间图作为匹配
if (ofset.x == 0 && ofset.y == 0)
{
cv::Point mid = idx[idx.size() / 2];
templateMat = src8U(cv::Rect(cv::Point(mid.x - 64, mid.y - 64), cv::Point(mid.x + 64, mid.y + 64))&cv::Rect(0, 0, X, Y)).clone();
cv::cvtColor(templateMat, templateMat, cv::COLOR_GRAY2RGB);
}
int step = (idx.size() / 27);
if (step < 1) {
step = 1;
}
for (int i = 0; i < idx.size() - 1; i += step)
{
auto p = idx[i];
cv::Mat mat = src8U(cv::Rect(cv::Point(p.x - 64, p.y - 64), cv::Point(p.x + 64, p.y + 64))&cv::Rect(0, 0, X, Y)).clone();
if (mat.cols == mat.rows)
{
mats.push_back(mat);
}
}
}
//<输出匹配图像
tpDstImg->iWidth = templateMat.cols; tpDstImg->iHeight = templateMat.rows; tpDstImg->iDepth = templateMat.depth(); tpDstImg->iChannels = templateMat.channels();
//内存尺寸 //内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t); int _Size0 = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
//分配初始化内存 //分配初始化内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size); tpDstImg->vpImage = (uint8_t *)malloc(_Size0);
if (NULL == tpDstImg->vpImage) if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM; return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size); memset(tpDstImg->vpImage, 0, _Size0);
//拷贝数据 //拷贝数据
memcpy(tpDstImg->vpImage, matchMat.data, _Size); memcpy(tpDstImg->vpImage, templateMat.data, _Size0);
return FUNC_OK; return FUNC_OK;
} }
...@@ -7389,12 +7436,9 @@ int eyemRemoveModelByName(IntPtr hModelID, const char *ccTplName) ...@@ -7389,12 +7436,9 @@ int eyemRemoveModelByName(IntPtr hModelID, const char *ccTplName)
{ {
if (NULL == hModelID) if (NULL == hModelID)
return FUNC_CANNOT_CALC; return FUNC_CANNOT_CALC;
std::vector<EyemModelID> *tpModelID = reinterpret_cast<std::vector<EyemModelID>*>(hModelID); std::vector<EyemModelID> *tpModelID = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
//遍历移除 //遍历移除
for (std::vector<EyemModelID>::iterator it = tpModelID->begin(); it != tpModelID->end(); ++it) { for (std::vector<EyemModelID>::iterator it = tpModelID->begin(); it != tpModelID->end(); ++it) {
EyemModelID *modelID = &(*it); EyemModelID *modelID = &(*it);
if (std::strcmp((const char *)modelID->lpszName, ccTplName) == 0) { if (std::strcmp((const char *)modelID->lpszName, ccTplName) == 0) {
//释放资源 //释放资源
...@@ -7410,7 +7454,6 @@ int eyemRemoveModelByName(IntPtr hModelID, const char *ccTplName) ...@@ -7410,7 +7454,6 @@ int eyemRemoveModelByName(IntPtr hModelID, const char *ccTplName)
break; break;
} }
} }
return FUNC_OK; return FUNC_OK;
} }
...@@ -7541,11 +7584,8 @@ int eyemReleaseModel(IntPtr &hModelID) ...@@ -7541,11 +7584,8 @@ int eyemReleaseModel(IntPtr &hModelID)
return FUNC_OK; return FUNC_OK;
std::vector<EyemModelID> *tpModelID = reinterpret_cast<std::vector<EyemModelID>*>(hModelID); std::vector<EyemModelID> *tpModelID = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
for (std::vector<EyemModelID>::iterator it = tpModelID->begin(); it != tpModelID->end(); ++it) { for (std::vector<EyemModelID>::iterator it = tpModelID->begin(); it != tpModelID->end(); ++it) {
EyemModelID *modelID = &(*it); EyemModelID *modelID = &(*it);
modelID->dMatchDeg = modelID->iHeight = modelID->iWidth = modelID->iXs = modelID->iYs = 0; modelID->dMatchDeg = modelID->iHeight = modelID->iWidth = modelID->iXs = modelID->iYs = 0;
//释放内容 //释放内容
CoTaskMemFree((LPVOID)modelID->lpszName); CoTaskMemFree((LPVOID)modelID->lpszName);
free(modelID->vpImage); free(modelID->vpImage);
...@@ -7561,25 +7601,19 @@ int eyemReleaseModel(IntPtr &hModelID) ...@@ -7561,25 +7601,19 @@ int eyemReleaseModel(IntPtr &hModelID)
int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg) int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg)
{ {
cv::Mat refImg = cv::Mat(tpRefImg.iHeight, tpRefImg.iWidth, MAKETYPE(tpRefImg.iDepth, tpRefImg.iChannels), tpRefImg.vpImage).clone(); cv::Mat refImg = cv::Mat(tpRefImg.iHeight, tpRefImg.iWidth, MAKETYPE(tpRefImg.iDepth, tpRefImg.iChannels), tpRefImg.vpImage).clone();
cv::Mat nextImg = cv::Mat(tpNextImg.iHeight, tpNextImg.iWidth, MAKETYPE(tpNextImg.iDepth, tpNextImg.iChannels), tpNextImg.vpImage).clone(); cv::Mat nextImg = cv::Mat(tpNextImg.iHeight, tpNextImg.iWidth, MAKETYPE(tpNextImg.iDepth, tpNextImg.iChannels), tpNextImg.vpImage).clone();
if (refImg.empty() | nextImg.empty()) if (refImg.empty() | nextImg.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
//显示图像 //显示图像
cv::Mat showMat; cv::Mat showMat;
showMat = nextImg.clone(); showMat = nextImg.clone();
//转灰度图像 //转灰度图像
if (refImg.channels() != 1) { if (refImg.channels() != 1) {
cv::cvtColor(refImg, refImg, cv::COLOR_BGR2GRAY); cv::cvtColor(refImg, refImg, cv::COLOR_BGR2GRAY);
} }
if (nextImg.channels() != 1) { if (nextImg.channels() != 1) {
cv::cvtColor(nextImg, nextImg, cv::COLOR_BGR2GRAY); cv::cvtColor(nextImg, nextImg, cv::COLOR_BGR2GRAY);
} }
cv::Mat dst; cv::Mat dst;
cv::absdiff(nextImg, refImg, dst); cv::absdiff(nextImg, refImg, dst);
...@@ -8000,59 +8034,7 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou ...@@ -8000,59 +8034,7 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
return FUNC_OK; return FUNC_OK;
} }
int eyemBuildTrainFile(const char *filePath, const char *fileName) int eyemTrainImageSampler(EyemImage tpImage, int iSize, const char *ccClassName, const char *ccToPath, EyemImage *tpMatchImg, EyemImage *tpDstImg)
{
//cv::Mat img = cv::imread(filePath, cv::IMREAD_COLOR);
//if (!img.empty())
//{
// cv::imwrite(fileName, img);
//}
std::vector<std::string> fileNames;
cv::glob(filePath, fileNames);
//打乱顺序
std::random_shuffle(fileNames.begin(), fileNames.end());
//写入文件
std::ofstream sw(fileName, std::ios::trunc);
for (auto&item : fileNames) {
std::vector<std::string> items;
split(item, "\\", items);
//
std::vector<std::string> items2(2);
split(items[items.size() - 1], ".", items2);
if (strcmp(items2[3].c_str(), "png") == 0)
{
std::string line = "data/val_images/" + items[items.size() - 1] + "\n";
sw.write(line.c_str(), line.length());
sw.flush();
}
}
sw.close();
return FUNC_OK;
}
cv::Mat load_image_cv(const std::string& fileName, cv::Scalar mean, cv::Scalar std)
{
cv::Mat img = cv::imread(fileName, cv::IMREAD_ANYCOLOR);
if (img.empty()) {
return cv::Mat();
}
int incn = img.channels();
if (incn < 3) {
cv::cvtColor(img, img, cv::COLOR_GRAY2RGB);
}
else if (incn >= 3) {
cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
}
img.convertTo(img, CV_32F, 1 / 255.);
cv::subtract(img, mean, img);
cv::divide(img, std, img);
return img;
}
#include "eyemStopwatch.h"
int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
{ {
CV_Assert(NULL != tpImage.vpImage); CV_Assert(NULL != tpImage.vpImage);
...@@ -8063,36 +8045,7 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -8063,36 +8045,7 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
if (image.channels() > 3) { if (image.channels() > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2BGR); cv::cvtColor(image, image, cv::COLOR_BGRA2BGR);
} }
cv::Mat img = load_image_cv("D://Cifar//airplane_01.png", cv::Scalar(0.4914, 0.4822, 0.4465), cv::Scalar(0.2023, 0.1994, 0.2010));
cv::dnn::Net net = cv::dnn::readNetFromONNX("Cifar.onnx");
net.setPreferableBackend(cv::dnn::Backend::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::Target::DNN_TARGET_CPU);
cv::Mat input = cv::dnn::blobFromImage(img);
net.setInput(input);
cv::Mat predicted = net.forward();
cv::imwrite("pred.png", predicted);
return FUNC_OK;
#pragma region darknet.lib
//int topk = 5;
//DarkNet net;
//net.setPreferableParams(0.2, topk);
//if (net.init("D:/cifar_resnet50.cfg", "D:/cifar_resnet50.weights", 1) != 0)
//{
// std::cout << "net load failed" << std::endl;
// return FUNC_CANNOT_CALC;
//}
//net.forward(image);
////获取结果
//int predicts[5]; float confidence[5]; auto bbox = std::vector<cv::Rect>();
//net.getResult(predicts, confidence, &bbox);
#pragma endregion
#pragma region test new preprocess
//转单通道 //转单通道
if (image.channels() != 1) if (image.channels() != 1)
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY); cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
...@@ -8136,8 +8089,7 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -8136,8 +8089,7 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
int maxIdx[2] = { 255,255 }; int maxIdx[2] = { 255,255 };
cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx); cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx);
//背景阈值 //背景阈值
int backThresh = 15 * cvRound(((double)maxIdx[0] - 2));//正常-2 int backThresh = 15 * cvRound(((double)maxIdx[0] - 4));//正常-2
//移除背景
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void { cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void {
for (int y = range.start; y < range.end; y++) { for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < X; x++) { for (int x = 0; x < X; x++) {
...@@ -8195,6 +8147,9 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -8195,6 +8147,9 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
src8U.copyTo(tray, trayMask); src8U.copyTo(tray, trayMask);
trays.push_back(TrayPos(reelCenter, tray, false, backThresh)); trays.push_back(TrayPos(reelCenter, tray, false, backThresh));
} }
if (trays.empty()) {
return FUNC_CANNOT_CALC;
}
cv::Mat srcPrev, srcPrevB; cv::Mat srcPrev, srcPrevB;
cv::bitwise_not(trays[0].Tray, srcPrev); cv::bitwise_not(trays[0].Tray, srcPrev);
...@@ -8206,44 +8161,47 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -8206,44 +8161,47 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
//判断元件尺寸 //判断元件尺寸
int sinPartSize; int sinPartSize;
bool useTrackMethod = checkSize(srcPrev, sinParts, sinPartSize); bool useTrackMethod = checkSize(srcPrev, sinParts, sinPartSize);
//连在一起 //连在一起
cv::morphologyEx(sinParts, sinParts, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45))); cv::morphologyEx(sinParts, sinParts, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45)));
//间隔采样,避免采样数量过大 //间隔采样,避免采样数量过大
cv::Mat linesample(image2.rows, image2.cols, CV_8UC1, cv::Scalar(0));
cv::Point start = cv::Point((int)trays[0].Center.x, (int)trays[0].Center.y), end = cv::Point((int)trays[0].Center.x, 0); cv::Point start = cv::Point((int)trays[0].Center.x, (int)trays[0].Center.y), end = cv::Point((int)trays[0].Center.x, 0);
//画中心
cv::drawMarker(cc, start, cv::Scalar(0, 0, 238, 255), 1, 35, 2);
//画标记
cv::putText(cc, "OK", cv::Point(170, 270), cv::FONT_HERSHEY_COMPLEX, 8, cv::Scalar(0, 100, 0, 255), 8);
//偏移两侧取更多样本 //偏移两侧取更多样本
cv::Point Offset(90, 90); cv::Point Offset[3] = { cv::Point(-90,0),cv::Point(0,0),cv::Point(90,0) };
start += Offset; end += Offset; //返回中间一根线的中点位置图像
std::vector<cv::Mat> mats; cv::Mat templateMat;
cv::line(linesample, start, end, cv::Scalar(255), 1); for (auto&ofset : Offset)
{
cv::Point nstart = start + ofset; cv::Point nend = end + ofset;
//cv::line(cc, nstart, nend, cv::Scalar(0, 255, 0, 255));
cv::line(cc, start, end, cv::Scalar(0, 255, 0, 255)); cv::Mat linesample(image2.rows, image2.cols, CV_8UC1, cv::Scalar(0));
cv::line(linesample, nstart, nend, cv::Scalar(255), 1);
cv::LineIterator it(image2, start, end); cv::Mat sampleLine;
cv::bitwise_and(linesample, sinParts, sampleLine);
for (int r = 0; r < linesample.rows; r += 2) std::vector<cv::Point> idx;
cv::findNonZero(sampleLine, idx);
if (idx.empty())
{ {
cv::line(linesample, cv::Point(0, r), cv::Point(linesample.cols, r), cv::Scalar(0), 1); return FUNC_CANNOT_CALC;
} }
//保存中间图作为匹配
cv::bitwise_and(linesample, sinParts, sinParts); if (ofset.x == 0 && ofset.y == 0)
std::vector<cv::Point> idx;
cv::findNonZero(sinParts, idx);
int step = (idx.size() / 25);
if (step < 1)
{ {
cv::Point mid = idx[idx.size() / 2];
templateMat = src8U(cv::Rect(cv::Point(mid.x - 64, mid.y - 64), cv::Point(mid.x + 64, mid.y + 64))&cv::Rect(0, 0, X, Y)).clone();
cv::cvtColor(templateMat, templateMat, cv::COLOR_GRAY2RGB);
}
int step = (idx.size() / 27);
if (step < 1) {
step = 1; step = 1;
} }
std::vector<cv::Mat> mats;
for (int i = 0; i < idx.size() - 1; i += step) for (int i = 0; i < idx.size() - 1; i += step)
{ {
auto p = idx[i]; auto p = idx[i];
...@@ -8253,25 +8211,104 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -8253,25 +8211,104 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
mats.push_back(mat); mats.push_back(mat);
} }
} }
for (int i = 0; i < idx.size(); i += step)
{
cv::Point p = idx[i];
cc.at<cv::Vec4b>(p) = cv::Vec4b(0, 255, 0, 255);
//cv::rectangle(cc, cv::Rect(cv::Point(p.x - 64, p.y - 64), cv::Point(p.x + 64, p.y + 64)), cv::Scalar(0, 255, 255, 255), 1);
} }
//保存到训练图像 //保存到训练图像
for (int i = 0; i < mats.size(); i++) for (int i = 0; i < mats.size(); i++)
{ {
std::string filePath = ""; std::string filePath = "";
filePath += "D:\\ResOut"; filePath += std::string(ccToPath);
//格式化文件名 //格式化文件名
char file[64 * 4] = { 0 }; char file[64 * 4] = { 0 };
sprintf_s(file, "%s\\%d_PID010.png", filePath.c_str(), i + 58); sprintf_s(file, "%s\\%d_%s.png", filePath.c_str(), i, ccClassName);
cv::imwrite(file, mats[i]); cv::imwrite(file, mats[i]);
} }
//<输出匹配图像
tpMatchImg->iWidth = templateMat.cols; tpMatchImg->iHeight = templateMat.rows; tpMatchImg->iDepth = templateMat.depth(); tpMatchImg->iChannels = templateMat.channels();
//内存尺寸
int _Size0 = tpMatchImg->iWidth*tpMatchImg->iHeight*tpMatchImg->iChannels * sizeof(uint8_t);
//分配初始化内存
tpMatchImg->vpImage = (uint8_t *)malloc(_Size0);
if (NULL == tpMatchImg->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpMatchImg->vpImage, 0, _Size0);
//拷贝数据
memcpy(tpMatchImg->vpImage, templateMat.data, _Size0);
//<输出结果图像
tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
//内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
//分配初始化内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size);
//拷贝数据
memcpy(tpDstImg->vpImage, cc.data, _Size);
return FUNC_OK;
}
int eyemBuildTrainFile(const char *filePath, const char *fileName, bool shuffle)
{
std::vector<std::string> fileNames;
cv::glob(filePath, fileNames);
//打乱顺序
std::random_shuffle(fileNames.begin(), fileNames.end());
//写入文件
std::ofstream sw(fileName, std::ios::trunc);
for (auto&item : fileNames) {
std::vector<std::string> items;
split(item, "\\", items);
//
std::vector<std::string> items2(2);
split(items[items.size() - 1], ".", items2);
if (strcmp(items2[3].c_str(), "png") == 0)
{
std::string line = "data/val_images/" + items[items.size() - 1] + "\n";
sw.write(line.c_str(), line.length());
sw.flush();
}
}
sw.close();
return FUNC_OK;
}
#include "eyemStopwatch.h"
int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
{
CV_Assert(NULL != tpImage.vpImage);
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (image.empty())
return FUNC_IMAGE_NOT_EXIST;
return FUNC_OK;
#pragma region
//AZONNXWrapper net;
//net.init("D:\\训练数据集\\Parts-11\\backup\\ec_model.onnx");
//float* predicts = net.forward(img, cv::Scalar(0.449, 0.449, 0.449), cv::Scalar(0.226, 0.226, 0.226));
//for (int i = 0; i < 512; i++)
//{
// std::cout << predicts[i] << std::endl;
//}
#pragma endregion
#pragma region darknet.lib
//int topk = 5;
//DarkNet net;
//net.setPreferableParams(0.2, topk);
//if (net.init("D:/cifar_resnet50.cfg", "D:/cifar_resnet50.weights", 1) != 0)
//{
// std::cout << "net load failed" << std::endl;
// return FUNC_CANNOT_CALC;
//}
//net.forward(image);
////获取结果
//int predicts[5]; float confidence[5]; auto bbox = std::vector<cv::Rect>();
//net.getResult(predicts, confidence, &bbox);
#pragma endregion #pragma endregion
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!