Commit 0871eb39 张士柳

1 个父辈 da2526be
...@@ -995,12 +995,28 @@ namespace eyemLib_Sharp ...@@ -995,12 +995,28 @@ namespace eyemLib_Sharp
private static extern int eyemInitNNDetector(string detectorConfigPath, string detectorModelPath, int iNetSizew, int iNetSizeh); private static extern int eyemInitNNDetector(string detectorConfigPath, string detectorModelPath, int iNetSizew, int iNetSizeh);
/// <summary> /// <summary>
/// 设置检测参数
/// </summary>
/// <param name="fConfidence">置信度</param>
/// <param name="fNMSThreshold">非极大值抑制阈值</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemNNDetectorParams(float fConfidence, float fNMSThreshold);
/// <summary>
/// 目标检测器 /// 目标检测器
/// </summary> /// </summary>
/// <param name="tpImage">输入图像</param> /// <param name="tpImage">输入图像</param>
/// <returns></returns> /// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemNNDetector(EyemImage tpImage, out int ipNum, ref BboxContainer container, out EyemImage tpDstImg); private static extern int eyemNNDetector(EyemImage tpImage, out int ipNum, ref BboxContainer container, out EyemImage tpDstImg);
/// <summary>
/// 初始化darknet分类器
/// </summary>
/// <param name="classifierConfigPath">配置地址</param>
/// <param name="classifierModelPath">模型地址</param>
/// <param name="ntype">0 检测网络,1 分类网络</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemInitClassifier(string classifierConfigPath, string classifierModelPath, int ntype); private static extern int eyemInitClassifier(string classifierConfigPath, string classifierModelPath, int ntype);
...@@ -1085,6 +1101,14 @@ namespace eyemLib_Sharp ...@@ -1085,6 +1101,14 @@ 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 eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, string funcName, double dThreshold, int iNumToIgnore, ref EyemOcsFXYR tpCircle, out EyemImage tpDstImg); private static extern int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, string funcName, double dThreshold, int iNumToIgnore, ref EyemOcsFXYR tpCircle, out EyemImage tpDstImg);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemDetectCircleUseHough(EyemImage tpImage, EyemRect tpRoi, EyemRect limRoi, out EyemOcsDXYR tpCircle, out EyemImage tpDstImg, double dp, double dMinDist, double dParam1, double dParam2, double dMinRadius, double dMaxRadius, int iMethod = 3, bool useValLimit = false);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern void loadImage2Mem(string key, EyemImage tpImage);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int setProcessLevel(double pl);
#endregion #endregion
#region 测试专用接口 #region 测试专用接口
...@@ -1094,6 +1118,8 @@ namespace eyemLib_Sharp ...@@ -1094,6 +1118,8 @@ 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
...@@ -1119,9 +1145,15 @@ namespace eyemLib_Sharp ...@@ -1119,9 +1145,15 @@ namespace eyemLib_Sharp
OnNewLogCallback += new TCallBack(EyemLib_OnNewLogCallback); OnNewLogCallback += new TCallBack(EyemLib_OnNewLogCallback);
eyemInitNNDataCodeModel(".\\darknet\\detect-tiny.cfg", ".\\darknet\\detect-tiny.weights", ".\\darknet\\sr.prototxt", ".\\darknet\\sr.caffemodel"); //setProcessLevel(2.0);
//EyemImage image_back = new EyemImage();
//eyemImageRead("D:\\Img20211028142015.png", -1, out image_back);
//loadImage2Mem("back", image_back);
eyemInitClassifier("D:\\detect-tiny-tray.cfg", "D:\\detect-tiny-tray.weights", 0); //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);
} }
public static void Free() public static void Free()
...@@ -1177,13 +1209,29 @@ namespace eyemLib_Sharp ...@@ -1177,13 +1209,29 @@ namespace eyemLib_Sharp
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(@"D:\训练数据集\点料机料盘识别\val_images", "*.png", 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");
//return;
//foreach (var item in fileNames)
//{
// eyemBuildTrainFile(item, "D:\\标签识别\\" + item.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[4]);
//}
//return;
//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++)
//{
// string item = fileNames[i];
// string[] items = item.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries);
// FileInfo fi = new FileInfo(item);
// fi.MoveTo(@"D:\日志\" + (i+83).ToString() + ".png");
//}
//return;
//StreamWriter swr = new StreamWriter("D:\\val.txt", true); //StreamWriter swr = new StreamWriter("D:\\val.txt", true);
//foreach (var item in random_shuffle) //foreach (var item in random_shuffle)
//{ //{
...@@ -1226,7 +1274,7 @@ namespace eyemLib_Sharp ...@@ -1226,7 +1274,7 @@ 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);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg); //Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null) //if (bitmap != null)
//{ //{
...@@ -1234,7 +1282,7 @@ namespace eyemLib_Sharp ...@@ -1234,7 +1282,7 @@ namespace eyemLib_Sharp
//} //}
//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);
...@@ -1454,9 +1502,14 @@ namespace eyemLib_Sharp ...@@ -1454,9 +1502,14 @@ namespace eyemLib_Sharp
tpRoi.iWidth = image.iWidth - 100; tpRoi.iWidth = image.iWidth - 100;
tpRoi.iHeight = image.iHeight - 100; tpRoi.iHeight = image.iHeight - 100;
//flag = eyemMulFuncTool(image, tpRoi, "__func1", 65, 75, ref tpCircle, out tpDstImg);
int[] ipReelNum = new int[4];
//flag = eyemAchvMatchMat(image, tpRoi, out tpDstImg); //flag = eyemAchvMatchMat(image, tpRoi, out tpDstImg);
//EyemOcsDXYR tpCircle = new EyemOcsDXYR();
//EyemRect limRoi = new EyemRect();
//limRoi.iXs = 222; limRoi.iYs = 222;
//limRoi.iWidth = 214;
//limRoi.iHeight = 214;
//flag = eyemDetectCircleUseHough(image, tpRoi, limRoi, out tpCircle, out tpDstImg, 1.0, 80, 100, 50, 28, 43, 3, true);
//////flag = eyemMulFuncTool(image, tpRoi, "__func1__", 65, 75, ref tpCircle, out tpDstImg);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg); //Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null) //if (bitmap != null)
//{ //{
...@@ -1521,20 +1574,21 @@ namespace eyemLib_Sharp ...@@ -1521,20 +1574,21 @@ namespace eyemLib_Sharp
//如果对象供其他接口使用要先释放 //如果对象供其他接口使用要先释放
//eyemImageFree(ref tpDstImg); //eyemImageFree(ref tpDstImg);
int[] ipReelNum = new int[4];
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",,IP_SQUARE_PARTS //"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",,IP_SQUARE_PARTS
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg); //eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_LARGE_PARTS", ipReelNum, out tpDstImg); //eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_LARGE_PARTS", ipReelNum, out tpDstImg);
//eyemCountObjectE(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg); eyemCountObjectE(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + "20210825095751-1.tpl", hModelID, ipReelNum, out tpDstImg); //eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + "20210825095751-1.tpl", hModelID, ipReelNum, out tpDstImg);
//移除模板 //移除模板
//flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl"); //flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg); Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null) if (bitmap != null)
//{ {
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file); bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//} }
//< 解码测试 //< 解码测试
//int ipNum; EyemBarCode* tpResults; //int ipNum; EyemBarCode* tpResults;
......
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eyemLib", "eyemLib\eyemLib.vcxproj", "{33D5F550-C799-4B05-8E14-ACA390DF5442}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eyemLib", "eyemLib\eyemLib.vcxproj", "{33D5F550-C799-4B05-8E14-ACA390DF5442}"
EndProject EndProject
......
...@@ -20,12 +20,23 @@ void setLogCallback(TCallback cb) ...@@ -20,12 +20,23 @@ void setLogCallback(TCallback cb)
} }
int killProcessID = -1; int killProcessID = -1;
void setSkipProcessID(int pid) void setSkipProcessID(int pid)
{ {
killProcessID = pid; killProcessID = pid;
} }
double processLevel = 2.0;
void setProcessLevel(double processLevel_)
{
processLevel = processLevel_;
}
std::map<std::string, EyemImage> imageMap;
void loadImage2Mem(const char *key, EyemImage tpImage)
{
imageMap.insert(std::pair<std::string, EyemImage>(std::string(key), tpImage));
}
Logger logger; Logger logger;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
......
...@@ -868,6 +868,7 @@ extern "C" { ...@@ -868,6 +868,7 @@ extern "C" {
// 函数接口 // 函数接口
EXPORTS int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModelPath, int iNetSizew, int iNetSizeh); EXPORTS int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModelPath, int iNetSizew, int iNetSizeh);
EXPORTS int eyemNNDetectorParams(float fConfidence, float fNMSThreshold);
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);
...@@ -925,11 +926,13 @@ extern "C" { ...@@ -925,11 +926,13 @@ extern "C" {
EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg); EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg);
EXPORTS int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum); EXPORTS int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum);
EXPORTS int eyemMarkerTracing(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg, bool bHighAccuracy = false); EXPORTS int eyemMarkerTracing(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg, bool bHighAccuracy = false);
EXPORTS int eyemDetectCircleUseHough(EyemImage tpImage, EyemRect tpRoi, EyemRect limRoi, EyemOcsDXYR *tpCircle, EyemImage *tpDstImg, double dp, double dMinDist, double dParam1, double dParam2, double dMinRadius, double dMaxRadius, int iMethod = 3, bool useValLimit = false);
EXPORTS int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg); EXPORTS int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg);
EXPORTS int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg); EXPORTS int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg);
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);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -938,6 +941,12 @@ extern "C" { ...@@ -938,6 +941,12 @@ 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 loadImage2Mem(const char *key, EyemImage tpImage);
// 日志回调定义 // 日志回调定义
typedef void(__stdcall*TCallback)(const char* msg); typedef void(__stdcall*TCallback)(const char* msg);
......
此文件类型无法预览
...@@ -83,8 +83,8 @@ ...@@ -83,8 +83,8 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\tbb2017_20170604oss\include;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;D:\darknet\include;D:\3rdparty\pthreads\include;$(IncludePath)</IncludePath> <IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\tbb2017_20170604oss\include;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;$(IncludePath)</IncludePath>
<LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\tbb2017_20170604oss\lib\intel64\vc14;D:\zxing-cpp-master\build\Release;D:\darknet\lib;D:\3rdparty\pthreads\lib;$(LibraryPath)</LibraryPath> <LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\tbb2017_20170604oss\lib\intel64\vc14;D:\zxing-cpp-master\build\Release;$(LibraryPath)</LibraryPath>
<TargetExt>.dll</TargetExt> <TargetExt>.dll</TargetExt>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
...@@ -161,7 +161,7 @@ ...@@ -161,7 +161,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libdmtx.lib;libzxing.lib;libdecode.lib;darknet.lib;pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libdmtx.lib;libzxing.lib;libdecode.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
......
...@@ -4514,7 +4514,9 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4514,7 +4514,9 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
} }
//图像裁剪 //图像裁剪
src = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone(); src = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
//image size //图像备份
cv::Mat me = src.clone();
//图像尺寸
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
//测试用,用于去除黑色坏点干扰 //测试用,用于去除黑色坏点干扰
cv::Mat medBlur; cv::Mat medBlur;
...@@ -4534,6 +4536,52 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4534,6 +4536,52 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
cv::Mat src8U; cv::Mat src8U;
src.convertTo(src8U, CV_8UC1, 1 / 255.); src.convertTo(src8U, CV_8UC1, 1 / 255.);
//判断是否是料盘,20211101修改测试用
auto item = imageMap.find("back");
if (item != imageMap.end()) {
auto image_back = item->second;
//相减判断是否存在料盘
cv::Mat image_back0 = cv::Mat(image_back.iHeight, image_back.iWidth, MAKETYPE(image_back.iDepth, image_back.iChannels),
image_back.vpImage)(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
if (image_back0.channels() != 1) {
cv::cvtColor(image_back0, image_back0, cv::COLOR_BGR2GRAY);
}
//转8位
me.convertTo(me, CV_8U, 1 / 255.); image_back0.convertTo(image_back0, CV_8U, 1 / 255.);
//判断背景
cv::Mat dst;
cv::absdiff(me, image_back0, dst);
//二值化
cv::Mat bin;
cv::threshold(dst, bin, 10, 255, cv::THRESH_BINARY);
//连接在一起
cv::morphologyEx(bin, bin, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45)));
//获取最大轮廓
std::vector<std::vector<cv::Point>> _contours;
cv::findContours(bin, _contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
if (_contours.empty()) {
return FUNC_CANNOT_CALC;
}
std::vector<cv::Point> contourMax = _contours[0];
for (int i = 1; i < _contours.size(); i++)
{
if (cv::contourArea(_contours[i]) > cv::contourArea(contourMax))
{
contourMax = _contours[i];
}
}
if (cv::contourArea(contourMax) < 100000)
return FUNC_CANNOT_CALC;
}
else {
//未发现图像则不进行判断
}
//显示结果图像 //显示结果图像
cv::Mat cc; cv::Mat cc;
cv::cvtColor(src8U, cc, cv::COLOR_GRAY2BGRA); cv::cvtColor(src8U, cc, cv::COLOR_GRAY2BGRA);
...@@ -4549,7 +4597,8 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4549,7 +4597,8 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
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 processLevel = processLevel > 2.0 ? processLevel : 2.0;
int backThresh = 15 * cvRound(((double)maxIdx[0] - processLevel));//正常-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++) {
...@@ -4568,14 +4617,16 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4568,14 +4617,16 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
cv::threshold(src8U, binary, (255 - backThresh), 255, cv::THRESH_BINARY); cv::threshold(src8U, binary, (255 - backThresh), 255, cv::THRESH_BINARY);
//连接在一起 //连接在一起
cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(45, 45))); cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(45, 45)));
//find the pallet //寻找料盘
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 image = 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) //根据尺寸判断是不是料盘
cv::Rect bbox = cv::boundingRect(contoursFilter[i]);
if (cv::contourArea(contoursFilter[i]) > 100000 && cv::min(bbox.height, bbox.width) > 300)//20211030修改,设置最小盘直径限制
{ {
cv::drawContours(image, contoursFilter, i, cv::Scalar(255), -1); cv::drawContours(image, contoursFilter, i, cv::Scalar(255), -1);
} }
...@@ -4603,7 +4654,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4603,7 +4654,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
//掩膜 //掩膜
cv::Mat trayMask = cv::Mat::zeros(Y, X, CV_8UC1); cv::Mat trayMask = cv::Mat::zeros(Y, X, CV_8UC1);
cv::drawContours(trayMask, contoursFilter, i, cv::Scalar(255), -1); cv::drawContours(trayMask, contoursFilter, i, cv::Scalar(255), -1);
// //拷贝料盘区域
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));
...@@ -4731,6 +4782,11 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4731,6 +4782,11 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
contourMax = contoursFilter[i]; contourMax = contoursFilter[i];
} }
} }
//20211029修改,测试用
cv::Rect _bboxx = cv::boundingRect(contourMax);
if (cv::contourArea(contourMax) < 65000 || cv::min(_bboxx.width, _bboxx.height) < 300)
continue;//不满足料盘大小,或者由于料盘颜色深影响到了定位
cv::Moments mu = cv::moments(contourMax); cv::Moments mu = cv::moments(contourMax);
cv::Point2f reelCenter(float(mu.m10 / mu.m00), float(mu.m01 / mu.m00)); cv::Point2f reelCenter(float(mu.m10 / mu.m00), float(mu.m01 / mu.m00));
//计算最大外接圆半径 //计算最大外接圆半径
...@@ -4922,7 +4978,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4922,7 +4978,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
} }
} }
//20210927测试用 //20210927测试用
//如果最大轮廓面积小于100000判断中间料盘影响到了定位 //如果最大轮廓面积小于85000判断中间料盘影响到了定位
if (cv::contourArea(contourMax) < 85000) { if (cv::contourArea(contourMax) < 85000) {
cv::findContours(srcPrevEx0, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); cv::findContours(srcPrevEx0, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
contourMax = contoursFilter[0]; contourMax = contoursFilter[0];
...@@ -5915,7 +5971,6 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -5915,7 +5971,6 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
} }
tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels(); 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); int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
...@@ -7789,17 +7844,13 @@ int eyemMarkerTracing(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemOcsFXYR *t ...@@ -7789,17 +7844,13 @@ int eyemMarkerTracing(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemOcsFXYR *t
return FUNC_OK; return FUNC_OK;
} }
int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg) int eyemDetectCircleUseHough(EyemImage tpImage, EyemRect tpRoi, EyemRect limRoi, EyemOcsDXYR *tpCircle, EyemImage *tpDstImg, double dp, double dMinDist, double dParam1, double dParam2, double dMinRadius, double dMaxRadius, int iMethod, bool useValLimit)
{ {
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone()( cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight));
if (image.empty()) if (image.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
const int X = image.cols; const int Y = image.rows;
if (strcmp(funcName, "__func1") == 0) {
int incn = image.channels(); int incn = image.channels();
if (incn > 3) { if (incn > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2GRAY); cv::cvtColor(image, image, cv::COLOR_BGRA2GRAY);
...@@ -7809,88 +7860,115 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou ...@@ -7809,88 +7860,115 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
} }
else if (incn == 1) { else if (incn == 1) {
} }
//裁剪
cv::Mat imageReduce = image(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
//高斯滤波 //高斯滤波
cv::Mat imagePrev; cv::Mat imagePrev;
cv::blur(image, imagePrev, cv::Size(15, 15)); cv::blur(imageReduce, imagePrev, cv::Size(3, 3));
//二值化 cv::Mat showMat;
cv::Mat binary; cv::cvtColor(image, showMat, cv::COLOR_GRAY2BGR);
if (dThreshold == 0.0) {
cv::threshold(imagePrev, binary, dThreshold, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);
}
else {
cv::threshold(imagePrev, binary, dThreshold, 255, cv::THRESH_BINARY_INV);
}
//去掉干扰 std::vector<cv::Vec3f> circles;
cv::Mat mask; cv::HoughCircles(imagePrev, circles, iMethod, dp, dMinDist, dParam1, dParam2, (int)dMinRadius, (int)dMaxRadius);
cv::morphologyEx(binary, mask, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45)));
//填充孔洞 //
std::vector<std::vector<cv::Point>> contours; for (auto&circle : circles) {
cv::findContours(mask, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); cv::Point center = cv::Point(cvRound(circle[0]) + tpRoi.iXs,
for (auto contourIdx = 0; contourIdx < contours.size(); contourIdx++) { cvRound(circle[1]) + tpRoi.iYs);
cv::drawContours(mask, contours, contourIdx, cv::Scalar(255), -1); float radius = circle[2];
if (useValLimit) {
//或许加个限制
if (cv::Rect(limRoi.iXs, limRoi.iYs, limRoi.iWidth, limRoi.iHeight).contains(center)) {
//输出
tpCircle->dX = center.x;
tpCircle->dY = center.y;
tpCircle->dR = radius;
//画图
cv::circle(showMat, center, (int)radius, cv::Scalar(0, 0, 255), 3, 8, 0);
cv::circle(showMat, center, 3, cv::Scalar(0, 255, 0), -1, 8, 0);
break;
} }
//计算最大连通域
cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(mask, labels, stats, centroids);
double maxVal;
cv::minMaxIdx(stats(cv::Range(1, stats.rows), cv::Range(4, 5)), NULL, &maxVal);
//过滤连通域面积<=maxVal的
std::vector<uchar> colors(nccomps + 1, 0);
for (int i = 1; i < nccomps; i++) {
colors[i] = 255;
if ((stats.ptr<int>(i)[cv::CC_STAT_AREA] < maxVal))
{
colors[i] = 0;
} }
else {
//输出
tpCircle->dX = center.x;
tpCircle->dY = center.y;
tpCircle->dR = radius;
//画图
cv::circle(showMat, center, (int)radius, cv::Scalar(0, 0, 255), 3, 8, 0);
cv::circle(showMat, center, 3, cv::Scalar(0, 255, 0), -1, 8, 0);
break;
} }
//过滤
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
for (int y = range.start; y < range.end; y++)
{
uint8_t *ptrRow = mask.ptr<uint8_t>(y);
for (int x = 0; x < X; x++)
{
int label = labels.ptr<int>(y)[x];
CV_Assert(0 <= label && label <= nccomps);
ptrRow[x] = colors[label];
} }
//输出结果图像
if (NULL != tpDstImg->vpImage) {
tpDstImg->iWidth = tpDstImg->iHeight = tpDstImg->iDepth = tpDstImg->iChannels = 0;
//释放
free(tpDstImg->vpImage);
tpDstImg->vpImage = NULL;
} }
}); tpDstImg->iWidth = showMat.cols; tpDstImg->iHeight = showMat.rows; tpDstImg->iDepth = showMat.depth(); tpDstImg->iChannels = showMat.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, showMat.data, _Size);
return FUNC_OK;
}
//定位 int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg)
cv::findContours(mask, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); {
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone()(
cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight));
std::vector<EyemOcsDXY> taPoints; if (image.empty())
for (auto&contour : contours) { return FUNC_IMAGE_NOT_EXIST;
for (int n = 0; n < contour.size(); n++) {
EyemOcsDXY taPoint; const int X = image.cols; const int Y = image.rows;
taPoint.dX = (double)contour[n].x;
taPoint.dY = (double)contour[n].y; if (strcmp(funcName, "__func1__") == 0) {
taPoints.push_back(taPoint); int incn = image.channels();
if (incn > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2GRAY);
} }
else if (incn == 3) {
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
} }
else if (incn == 1) {
}
//高斯滤波
cv::Mat imagePrev;
cv::blur(image, imagePrev, cv::Size(3, 3));
double min_err;
EyemOcsDXYR _tpCircle;
eyemFitCircle((int)taPoints.size(), &taPoints[0], iNumToIgnore, min_err, _tpCircle);
//画图
cv::Mat showMat; cv::Mat showMat;
cv::cvtColor(image, showMat, cv::COLOR_GRAY2RGB); cv::cvtColor(imagePrev, showMat, cv::COLOR_GRAY2BGR);
cv::circle(showMat, cv::Point(cvRound(_tpCircle.dX), cvRound(_tpCircle.dY)), cvRound(_tpCircle.dR), cv::Scalar(0, 255, 0), 2);
std::vector<cv::Vec3f> circles;
cv::HoughCircles(imagePrev, circles, cv::HOUGH_GRADIENT, 1, imagePrev.rows / 8, 100, 40, 30, 45);
// Draw the circles detected
for (size_t i = 0; i < circles.size(); i++)
{
cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// circle center
cv::circle(showMat, center, 3, cv::Scalar(0, 255, 0), -1, 8, 0);
// circle outline
circle(showMat, center, radius, cv::Scalar(0, 0, 255), 3, 8, 0);
}
//输出 //输出
tpCircle->fX = (float)_tpCircle.dX + (float)tpRoi.iXs; tpCircle->fX = /*(float)_tpCircle.dX +*/ (float)tpRoi.iXs;
tpCircle->fY = (float)_tpCircle.dY + (float)tpRoi.iYs; tpCircle->fY = /*(float)_tpCircle.dY +*/ (float)tpRoi.iYs;
tpCircle->fR = (float)_tpCircle.dR; tpCircle->fR = /*(float)_tpCircle.dR*/0;
//输出结果图像 //输出结果图像
{
if (NULL != tpDstImg->vpImage) { if (NULL != tpDstImg->vpImage) {
tpDstImg->iWidth = tpDstImg->iHeight = tpDstImg->iDepth = tpDstImg->iChannels = 0; tpDstImg->iWidth = tpDstImg->iHeight = tpDstImg->iDepth = tpDstImg->iChannels = 0;
//释放 //释放
...@@ -7898,7 +7976,7 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou ...@@ -7898,7 +7976,7 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
tpDstImg->vpImage = NULL; tpDstImg->vpImage = NULL;
} }
tpDstImg->iWidth = mask.cols; tpDstImg->iHeight = mask.rows; tpDstImg->iDepth = mask.depth(); tpDstImg->iChannels = mask.channels(); tpDstImg->iWidth = showMat.cols; tpDstImg->iHeight = showMat.rows; tpDstImg->iDepth = showMat.depth(); tpDstImg->iChannels = showMat.channels();
//内存尺寸 //内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t); int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
...@@ -7910,10 +7988,9 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou ...@@ -7910,10 +7988,9 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
memset(tpDstImg->vpImage, 0, _Size); memset(tpDstImg->vpImage, 0, _Size);
//拷贝数据 //拷贝数据
memcpy(tpDstImg->vpImage, mask.data, _Size); memcpy(tpDstImg->vpImage, showMat.data, _Size);
}
} }
else if (strcmp(funcName, "__func2") == 0) { else if (strcmp(funcName, "__func2__") == 0) {
} }
else { else {
...@@ -7923,8 +8000,58 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou ...@@ -7923,8 +8000,58 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
return FUNC_OK; return FUNC_OK;
} }
int eyemBuildTrainFile(const char *filePath, const char *fileName)
{
//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" #include "eyemStopwatch.h"
#include "yoloWrapper.h"
int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
{ {
CV_Assert(NULL != tpImage.vpImage); CV_Assert(NULL != tpImage.vpImage);
...@@ -7936,8 +8063,18 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -7936,8 +8063,18 @@ 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;
cv::Mat output = image.clone();
#pragma region darknet.lib #pragma region darknet.lib
//int topk = 5; //int topk = 5;
...@@ -7954,31 +8091,186 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -7954,31 +8091,186 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
//net.getResult(predicts, confidence, &bbox); //net.getResult(predicts, confidence, &bbox);
#pragma endregion #pragma endregion
#pragma region test new preprocess #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);
////图像裁剪 //图像裁剪
//cv::Mat src = image(cv::Rect(200, 200, image.cols - 400, image.rows - 400)).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::Mat medBlur;
//cv::medianBlur(src, medBlur, 3); cv::medianBlur(src, medBlur, 3);
////去除局部量斑影响(默认亮斑尺寸不会大于15个像素) //去除局部量斑影响(默认亮斑尺寸不会大于15个像素)
//cv::morphologyEx(medBlur, medBlur, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15))); cv::morphologyEx(medBlur, medBlur, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
////图像增强 //图像增强
//double min, max; double min, max;
//cv::minMaxLoc(medBlur, &min, &max, NULL); cv::minMaxLoc(medBlur, &min, &max, NULL);
//src.convertTo(src, CV_64FC1); src.convertTo(src, CV_64FC1);
//src -= min; src -= min;
//src /= (max - min); src /= (max - min);
//src *= 65535; src *= 65535;
//src.convertTo(src, CV_16UC1); src.convertTo(src, CV_16UC1);
//src.convertTo(output, CV_8UC1, 1 / 255.); cv::Mat src8U;
src.convertTo(src8U, CV_8UC1, 1 / 255.);
cv::Mat output = src8U.clone();
//显示结果图像
cv::Mat cc;
cv::cvtColor(src8U, cc, cv::COLOR_GRAY2BGRA);
//设置bins
const int histSize = 17;
//range of values
float range[] = { 0,255 };
const float* histRange = { range };
//计算直方图
cv::Mat hist;
cv::calcHist(&src8U, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);
//计算背景
int maxIdx[2] = { 255,255 };
cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx);
//背景阈值
int backThresh = 15 * cvRound(((double)maxIdx[0] - 2));//正常-2
//移除背景
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void {
for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < X; x++) {
if (src8U.ptr<uint8_t>(y)[x] >= backThresh) {
src8U.ptr<uint8_t>(y)[x] = backThresh;
}
}
}
});
//方便显示
cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh));
//inv
cv::bitwise_not(src8U, src8U);
cv::Mat binary;
cv::threshold(src8U, binary, (255 - backThresh), 255, cv::THRESH_BINARY);
//连接在一起
cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45)));
//find the pallet
std::vector<std::vector<cv::Point>> contoursFilter;
cv::findContours(binary, contoursFilter, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
//填充内部确定料盘
cv::Mat image2 = cv::Mat::zeros(src8U.size(), CV_8UC1);
for (int i = 0; i < contoursFilter.size(); i++)
{
if (cv::contourArea(contoursFilter[i]) > 100000)
{
cv::drawContours(image2, contoursFilter, i, cv::Scalar(255), -1);
}
}
cv::bitwise_not(src8U, src8U);
//剩下即料盘区域(面积大于100000均认为是料盘)
cv::findContours(image2, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
//区分多个料盘
struct TrayPos
{
int iDir = -1;//0左上1左下2右下3右上
double dBackThresh;
bool bSorted;
cv::Point2f Center;
cv::Mat Tray;
TrayPos() {};
TrayPos(cv::Point2f center, cv::Mat tray, bool bSorted, double dBackThresh) :Center(center), Tray(tray), bSorted(bSorted), dBackThresh(dBackThresh) {}
};
std::vector <TrayPos> trays;
for (int i = 0; i < contoursFilter.size(); i++)
{
//定位中心
cv::Moments mu = cv::moments(contoursFilter[i]);
cv::Point reelCenter(cvRound(mu.m10 / mu.m00), cvRound(mu.m01 / mu.m00));
//掩膜
cv::Mat trayMask = cv::Mat::zeros(Y, X, CV_8UC1);
cv::drawContours(trayMask, contoursFilter, i, cv::Scalar(255), -1);
//
cv::Mat tray = cv::Mat(Y, X, CV_8UC1, backThresh);
src8U.copyTo(tray, trayMask);
trays.push_back(TrayPos(reelCenter, tray, false, backThresh));
}
cv::Mat srcPrev, srcPrevB;
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::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 Offset(90, 90);
start += Offset; end += Offset;
cv::line(linesample, start, end, cv::Scalar(255), 1);
cv::line(cc, start, end, cv::Scalar(0, 255, 0, 255));
cv::LineIterator it(image2, start, end);
for (int r = 0; r < linesample.rows; r += 2)
{
cv::line(linesample, cv::Point(0, r), cv::Point(linesample.cols, r), cv::Scalar(0), 1);
}
cv::bitwise_and(linesample, sinParts, sinParts);
std::vector<cv::Point> idx;
cv::findNonZero(sinParts, idx);
int step = (idx.size() / 25);
if (step < 1)
{
step = 1;
}
std::vector<cv::Mat> mats;
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);
}
}
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++)
{
std::string filePath = "";
filePath += "D:\\ResOut";
//格式化文件名
char file[64 * 4] = { 0 };
sprintf_s(file, "%s\\%d_PID010.png", filePath.c_str(), i + 58);
cv::imwrite(file, mats[i]);
}
#pragma endregion #pragma endregion
...@@ -8143,19 +8435,19 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -8143,19 +8435,19 @@ int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
#pragma endregion #pragma endregion
if (!output.empty()) { //if (!output.empty()) {
//<输出结果图像 // //<输出结果图像
tpDstImg->iWidth = output.cols; tpDstImg->iHeight = output.rows; tpDstImg->iDepth = output.depth(); tpDstImg->iChannels = output.channels(); // tpDstImg->iWidth = output.cols; tpDstImg->iHeight = output.rows; tpDstImg->iDepth = output.depth(); tpDstImg->iChannels = output.channels();
//内存尺寸 // //内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t); // int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
//分配初始化内存 // //分配初始化内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size); // tpDstImg->vpImage = (uint8_t *)malloc(_Size);
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, _Size);
//拷贝数据 // //拷贝数据
memcpy(tpDstImg->vpImage, output.data, _Size); // memcpy(tpDstImg->vpImage, output.data, _Size);
} //}
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -13,5 +13,7 @@ constexpr double c = PI / 180.; ...@@ -13,5 +13,7 @@ constexpr double c = PI / 180.;
extern Logger logger; extern Logger logger;
extern int killProcessID; extern int killProcessID;
extern double processLevel;
extern std::map<std::string, EyemImage> imageMap;
#endif/* __EYEM_MISC_H */ #endif/* __EYEM_MISC_H */
...@@ -4,10 +4,13 @@ class NNDetector::Impl { ...@@ -4,10 +4,13 @@ class NNDetector::Impl {
public: public:
Impl() {} Impl() {}
~Impl() {} ~Impl() {}
//目标检测 //目标检测
std::vector<cv::Rect> detect(const cv::Mat& img); std::vector<cv::Rect> detect(const cv::Mat& img);
//目标检测器 //目标检测器
std::shared_ptr<YoloWrapper> detector_; std::shared_ptr<YoloWrapper> detector_;
//目标检测参数
float _fConfidence = 0.01f, _fNMSThreshold = 0.05f;
}; };
NNDetector::NNDetector(const std::string & detector_config_path, NNDetector::NNDetector(const std::string & detector_config_path,
...@@ -23,6 +26,11 @@ NNDetector::NNDetector(const std::string & detector_config_path, ...@@ -23,6 +26,11 @@ NNDetector::NNDetector(const std::string & detector_config_path,
} }
} }
void NNDetector::setInputParams(float fConfidence, float fNMSThreshold)
{
p->_fConfidence = fConfidence; p->_fNMSThreshold = fNMSThreshold;
}
std::vector<cv::Rect> NNDetector::detect(cv::InputArray img) std::vector<cv::Rect> NNDetector::detect(cv::InputArray img)
{ {
CV_Assert(!img.empty()); CV_Assert(!img.empty());
...@@ -41,6 +49,7 @@ std::vector<cv::Rect> NNDetector::detect(cv::InputArray img) ...@@ -41,6 +49,7 @@ std::vector<cv::Rect> NNDetector::detect(cv::InputArray img)
} }
std::vector<cv::Rect> NNDetector::Impl::detect(const cv::Mat& img) { std::vector<cv::Rect> NNDetector::Impl::detect(const cv::Mat& img) {
detector_->setPreferableParams(_fConfidence, _fNMSThreshold);
return detector_->forward(img); return detector_->forward(img);
} }
...@@ -56,6 +65,12 @@ int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModel ...@@ -56,6 +65,12 @@ int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModel
return FUNC_OK; return FUNC_OK;
} }
int eyemNNDetectorParams(float fConfidence, float fNMSThreshold)
{
pNNDetector->setInputParams(fConfidence, fNMSThreshold);
return FUNC_OK;
}
int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, EyemImage *tpDstImg) int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone(); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
...@@ -106,6 +121,7 @@ int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, Eyem ...@@ -106,6 +121,7 @@ int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, Eyem
return FUNC_OK; return FUNC_OK;
} }
#ifdef _DEBUG
int eyemInitClassifier(const char *classifierConfigPath, const char *classifierModelPath, int ntype) int eyemInitClassifier(const char *classifierConfigPath, const char *classifierModelPath, int ntype)
{ {
try { try {
...@@ -142,3 +158,4 @@ int eyemClassifier(EyemImage tpImage) ...@@ -142,3 +158,4 @@ int eyemClassifier(EyemImage tpImage)
return FUNC_OK; return FUNC_OK;
} }
#endif
\ No newline at end of file \ No newline at end of file
...@@ -13,7 +13,8 @@ public: ...@@ -13,7 +13,8 @@ public:
NNDetector(const std::string& detector_config_path, NNDetector(const std::string& detector_config_path,
const std::string& detector_model_path, const cv::Size& input_size); const std::string& detector_model_path, const cv::Size& input_size);
NNDetector() {}; NNDetector() {};
//ü
void setInputParams(float fConfidence, float fNMSThreshold);
std::vector<cv::Rect> detect(cv::InputArray img); std::vector<cv::Rect> detect(cv::InputArray img);
protected: protected:
...@@ -23,6 +24,8 @@ protected: ...@@ -23,6 +24,8 @@ protected:
cv::Ptr<NNDetector> pNNDetector; cv::Ptr<NNDetector> pNNDetector;
#ifdef _DEBUG
cv::Ptr<YoloDarknet> pClassifier; cv::Ptr<YoloDarknet> pClassifier;
#endif
#endif/* __EYEMNNDETECTOR_H */ #endif/* __EYEMNNDETECTOR_H */
\ No newline at end of file \ No newline at end of file
...@@ -13,6 +13,12 @@ int YoloWrapper::init(const std::string& detector_config_path, ...@@ -13,6 +13,12 @@ int YoloWrapper::init(const std::string& detector_config_path,
return 0; return 0;
} }
int YoloWrapper::setPreferableParams(float fConfidence, float fNMSThreshold)
{
this->confidence = fConfidence; this->NMSThreshold = fNMSThreshold;
return 0;
}
std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) { std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) {
//获取输出层名称 //获取输出层名称
auto layerNames = net_.getLayerNames(); auto layerNames = net_.getLayerNames();
...@@ -42,13 +48,11 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) { ...@@ -42,13 +48,11 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) {
//置信度 //置信度
cv::Mat prob = outputBlobs[n](cv::Range(row, row + 1), cv::Range(5, outputBlobs[n].cols)); cv::Mat prob = outputBlobs[n](cv::Range(row, row + 1), cv::Range(5, outputBlobs[n].cols));
double confidence;
cv::Point classIdPoint;
//取得最大分数值与索引 //取得最大分数值与索引
cv::minMaxLoc(prob, 0, &confidence, 0, &classIdPoint); double score = .0; cv::Point classIdPoint;
cv::minMaxLoc(prob, 0, &score, 0, &classIdPoint);
//把可能的区域都算作进去 //把可能的区域都算作进去
if (confidence > 0.01) { if (score > confidence) {
cv::Mat dt = outputBlobs[n](cv::Range(row, row + 1), cv::Range(0, 5)); cv::Mat dt = outputBlobs[n](cv::Range(row, row + 1), cv::Range(0, 5));
int cx = cvRound(dt.ptr<float>(0)[0] * (float)img.cols); int cx = cvRound(dt.ptr<float>(0)[0] * (float)img.cols);
...@@ -59,14 +63,14 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) { ...@@ -59,14 +63,14 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) {
int left = cx - w / 2; int left = cx - w / 2;
int top = cy - h / 2; int top = cy - h / 2;
confidences.push_back((float)confidence); confidences.push_back((float)score);
bboxes.push_back(cv::Rect(left, top, w, h)); bboxes.push_back(cv::Rect(left, top, w, h));
} }
} }
} }
std::vector<int> indices; std::vector<int> indices;
//非极大值抑制 //非极大值抑制
cv::dnn::NMSBoxes(bboxes, confidences, 0.01f, 0.05f, indices); cv::dnn::NMSBoxes(bboxes, confidences, confidence, NMSThreshold, indices);
//裁剪区域 //裁剪区域
auto points = std::vector<cv::Rect>(); auto points = std::vector<cv::Rect>();
for (int i = 0; i < indices.size(); i++) { for (int i = 0; i < indices.size(); i++) {
...@@ -77,6 +81,8 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) { ...@@ -77,6 +81,8 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) {
return points; return points;
} }
#ifdef _DEBUG
class YoloDarknet::Impl { class YoloDarknet::Impl {
public: public:
Impl() {} Impl() {}
...@@ -114,3 +120,4 @@ void YoloDarknet::forward(std::vector<int> &outputPredict, std::vector<float> &o ...@@ -114,3 +120,4 @@ void YoloDarknet::forward(std::vector<int> &outputPredict, std::vector<float> &o
} }
delete[] predicts; predicts = NULL; delete[] confidence; confidence = NULL; delete[] predicts; predicts = NULL; delete[] confidence; confidence = NULL;
} }
#endif
...@@ -8,20 +8,25 @@ ...@@ -8,20 +8,25 @@
#include "opencv2/dnn.hpp" #include "opencv2/dnn.hpp"
#include "opencv2/imgproc.hpp" #include "opencv2/imgproc.hpp"
#ifdef _DEBUG
#include <darknet.h> #include <darknet.h>
#include <yolo_class.h> #include <yolo_class.h>
#endif
class YoloWrapper class YoloWrapper
{ {
public: public:
YoloWrapper() {}; YoloWrapper() {};
int init(const std::string& config_path, const std::string& model_path, const cv::Size& input_size); int init(const std::string& config_path, const std::string& model_path, const cv::Size& input_size);
int setPreferableParams(float fConfidence, float fNMSThreshold);//置信度,非极大值抑制阈值
std::vector<cv::Rect> forward(cv::Mat img); std::vector<cv::Rect> forward(cv::Mat img);
private: private:
cv::Size Size_; cv::Size Size_;
float confidence = 0.01f, NMSThreshold = 0.05f;
cv::dnn::Net net_; cv::dnn::Net net_;
}; };
#ifdef _DEBUG
class YoloDarknet class YoloDarknet
{ {
public: public:
...@@ -36,6 +41,6 @@ protected: ...@@ -36,6 +41,6 @@ protected:
class Impl; class Impl;
cv::Ptr<Impl> p; cv::Ptr<Impl> p;
}; };
#endif
#endif/* __YOLOWRAPPER_H */ #endif/* __YOLOWRAPPER_H */
\ No newline at end of file \ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!