Commit 53a9dc28 张士柳

1 个父辈 a2f38dd2
......@@ -757,10 +757,10 @@ namespace eyemLib_Sharp
private static extern int eyemAchvModelByName(string ccTplName, IntPtr hModelID, ref EyemModelID tpModelID);
//插入模板
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemInsertModel(ref IntPtr hModelID, string ccTplName);
private static extern int eyemInsertModel(IntPtr hModelID, string ccTplName);
//通过名称移除模板
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemRemoveModelByName(ref IntPtr hModelID, string ccTplName);
private static extern int eyemRemoveModelByName(IntPtr hModelID, string ccTplName);
//释放模板内存
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemReleaseModel(ref IntPtr hModelID);
......@@ -772,7 +772,7 @@ namespace eyemLib_Sharp
private static extern bool eyemDetectAndDecodeFree(IntPtr hObject);
//背景变化跟踪
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, IntPtr tpArray, int iArraySize, IntPtr ipResults);
private static extern int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, IntPtr tpArray, int iArraySize, IntPtr ipResults, out EyemImage tpDstImg);
//插件机
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, IntPtr tpArray, int iArraySize);
......@@ -975,8 +975,8 @@ namespace eyemLib_Sharp
tpRoi2.iWidth = 28;
tpRoi2.iHeight = 9;
//double matchDeg = 0.80;
//flag = eyemCreateTemplateModel(tpDstImg, tpRoi2, matchDeg, "D:\\模板文件\\" + file.Replace(".png", ".tpl"));
double matchDeg = 0.80;
flag = eyemCreateTemplateModel(tpDstImg, tpRoi2, matchDeg, "D:\\模板文件\\" + file.Replace(".png", ".tpl"));
//加载模板到内存
IntPtr hModelID = IntPtr.Zero;
......@@ -987,7 +987,7 @@ namespace eyemLib_Sharp
flag = eyemMatchTemplateModel(tpDstImg, hModelID, ref selectModel);
//插入模板
flag = eyemInsertModel(ref hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
flag = eyemInsertModel(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//根据名称获取模板
EyemModelID tpModelID = new EyemModelID();
......@@ -1015,7 +1015,7 @@ namespace eyemLib_Sharp
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + /*file.Replace(".png", ".tpl")*/"74d571ed-9fd4-4959-85dd-3195261e4b48.tpl", ref pNumObj, out tpDstImg);
//移除模板
flag = eyemRemoveModelByName(ref hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
......@@ -1073,7 +1073,7 @@ namespace eyemLib_Sharp
flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
//测试插入模板
//eyemInsertModel(ref hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//eyemInsertModel(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
////测试获取模板
//EyemModelID tpModelID0 = new EyemModelID();
......@@ -1094,6 +1094,8 @@ namespace eyemLib_Sharp
Bitmap bitmap = eyemCvtToBitmap(tpModeImg);
bitmap.Dispose();
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
......@@ -1106,14 +1108,48 @@ namespace eyemLib_Sharp
eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), selectModel.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], hModelID, ref pNumObj, out tpDstImg);
//测试移除模板
//eyemRemoveModelByName(ref hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
//free image
eyemImageFree(ref tpDstImg);
eyemImageFree(ref image);
sw.Stop();
Console.WriteLine("耗时:" + sw.ElapsedMilliseconds.ToString() + ",结果:" + pNumObj);
Console.WriteLine("耗时:" + sw.ElapsedMilliseconds.ToString() + ",结果:" + pNumObj + ",所用模板:" + str);
}
public static void eyemReadProcssedImage(string fileName)
{
EyemImage image;
EyemImage tpDstImg = new EyemImage();
int flag = eyemImageRead(fileName, -1, out image);
if (flag != 0)
{
Console.WriteLine("读图失败!");
return;
}
EyemRect tpRoi = new EyemRect();
tpRoi.iXs = 200; tpRoi.iYs = 200;
tpRoi.iWidth = image.iWidth - 400;
tpRoi.iHeight = image.iHeight - 400;
//
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//获取用于制作模板的图像
flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null)
{
bitmap.Save("D:\\ResOut\\" + file);
}
//建议释放掉
bitmap.Dispose();
}
public static int eyemInitModelE(out IntPtr hModelID)
......@@ -1158,9 +1194,11 @@ namespace eyemLib_Sharp
//类似于实时采集的图像
for (int i = 1; i < ipNum; i++)
{
EyemImage tpDstImg;
//存放结果
int[] iArrRes = new int[tpRois.Count];
int iRet = eyemAOIForTSAV(tpImages[0], tpImages[i], hGlobal, tpRois.Count);
//int iRet = eyemAOIForTSAV(tpImages[0], tpImages[i], hGlobal, tpRois.Count);
int iRet = eyemTrackFeature(tpImages[0], tpImages[i], hGlobal, tpRois.Count, Marshal.UnsafeAddrOfPinnedArrayElement(iArrRes, 0), out tpDstImg);
//过滤出有效信号(连续存在数帧以上才算,防止误触发),或者直接用iArrRes的值作为信号
//toSingleFilter(iArrRes, ref bitSingle);
//for (int j = 0; j < bitSingle.Length; j++)
......@@ -1172,6 +1210,7 @@ namespace eyemLib_Sharp
// Console.WriteLine("检测到:" + j + "处有信号");
// }
//}
eyemImageFree(ref tpDstImg);
System.Threading.Thread.Sleep(80);
}
//释放资源
......
......@@ -28,31 +28,38 @@ namespace eyemLib_Sharp
// EyemLib.eyemReadImageTool(item);
//}
//for (int i = 0; i < 1; i++)
//{
// EyemLib.eyemTestVideoCapture("D:\\插件完成检测\\视频\\WeChat2.mp4");
//}
IntPtr hModelID;
EyemLib.eyemInitModelE(out hModelID);
for (int i = 0; i < 5000; i++)
for (int i = 0; i < 1; i++)
{
//for (int j = 0; j < fileNames.Length; j++)
//{
// EyemLib.eyemReadImageToolE(fileNames[j], hModelID);
//}
//并行测试
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = 3;
Parallel.ForEach(fileNames, po, fn =>
{
EyemLib.eyemReadImageToolE(fn, hModelID);
});
EyemLib.eyemTestVideoCapture("D:\\插件完成检测\\视频\\cap5.mp4");
}
EyemLib.eyemReleaseModelE(ref hModelID);
//IntPtr hModelID;
//EyemLib.eyemInitModelE(out hModelID);
//int sum = 0;
//for (int i = 0; i < 5000; i++)
//{
// //for (int j = 0; j < fileNames.Length; j++)
// //{
// // EyemLib.eyemReadImageToolE(fileNames[j], hModelID);
// //}
// sum++;
// //并行测试
// ParallelOptions po = new ParallelOptions();
// po.MaxDegreeOfParallelism = 3;
// Parallel.ForEach(fileNames, po, fn =>
// {
// EyemLib.eyemReadImageToolE(fn, hModelID);
// });
// if (sum > 50)
// {
// sum = 0;
// Console.Clear();
// }
//}
//EyemLib.eyemReleaseModelE(ref hModelID);
Console.Write("请按任意键继续。。。");
Console.ReadKey();
......
......@@ -853,10 +853,10 @@ extern "C" {
EXPORTS int eyemMatchTemplateModel(EyemImage tpImage, IntPtr hModelID, LPSTR *lpszTplName);
EXPORTS int eyemInitModel(const char *ccTplName, IntPtr *hModelID);
EXPORTS int eyemAchvModelByName(const char *ccTplName, IntPtr hModelID, EyemModelID &tpModelID);
EXPORTS int eyemInsertModel(IntPtr &hModelID, const char *ccTplName);
EXPORTS int eyemRemoveModelByName(IntPtr &hModelID, const char *ccTplName);
EXPORTS int eyemInsertModel(IntPtr hModelID, const char *ccTplName);
EXPORTS int eyemRemoveModelByName(IntPtr hModelID, const char *ccTplName);
EXPORTS int eyemReleaseModel(IntPtr &hModelID);
EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults);
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);
#ifdef __cplusplus
......
......@@ -277,7 +277,7 @@ static void loadTrackModel(const char *fileName, cv::OutputArray tplMat, cv::Poi
return;
//上锁
mtx.lock();
mtx_misc.lock();
FILE *fps = NULL;
fopen_s(&fps, fileName, "r");
......@@ -305,7 +305,7 @@ static void loadTrackModel(const char *fileName, cv::OutputArray tplMat, cv::Poi
fclose(fps);
//解锁
mtx.unlock();
mtx_misc.unlock();
//获取图像数据大小
unsigned char _SizeData[8];
......@@ -347,6 +347,15 @@ static void loadTrackModel(const char *fileName, cv::OutputArray tplMat, cv::Poi
_Data = NULL;
}
/** 十进制转二进制数
d 输入十进制数字
*/
static std::string DtoB(int d)
{
return "";
}
/** 获取文件夹内所有文件
filePath 输入文件夹
fileNames 输出文件
......@@ -506,7 +515,7 @@ static double getThreshVal_Otsu_8u(const cv::Mat& _src)
}
return max_val;
}
}
/** 计算元件尺寸
srcPrev 输入图像
......@@ -4680,8 +4689,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char
for (int j = 0; j < 4; j++)
{
cv::line(cc, ptsT[j], ptsT[(j + 1) % 4], cv::Scalar(0, 0, 255, 255), 1);
}
}
}
}
#endif
......@@ -4740,170 +4749,170 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char
//std::cout << "总体耗时:" << 1000 * (static_cast<double>(cv::getTickCount()) - begin0) / cv::getTickFrequency() << std::endl;
trackEnd = (!found);
} while (!trackEnd);
} while (!trackEnd);
}
}
#if OPTIMIZE_ON
,
[&]
,
[&]
#endif
{
///< 逆时针追踪
//追踪起点
cv::Point2f trackCenter(startCenter.x, startCenter.y);
//起始扫描角度、半径
double trackAngle = startAngle, trackRadius = startRadius;
//元件本身角度
double trackOffset = dOffset;
//元件间间距
double partDist = (2 * asin(dChordL / (2 * trackRadius))) * 180 / PI;
//外接矩形
cv::Point2f pts[4];
//开始追踪
bool trackEnd = true;
//
do
{
bool found = true;
std::vector<Track> vParts;
for (double t = trackAngle - (trackOffset / 3.0 + partDist + trackOffset / 2.0); t > trackAngle - \
(trackOffset / 3.0 + partDist + trackOffset / 2.0) - trackOffset / 3.0; t -= dMinorStep)
{
trackCenter.x = float(reelCenter.x + trackRadius*cos(t*c));
trackCenter.y = float(reelCenter.y + trackRadius*sin(t*c));
///< 逆时针追踪
//追踪起点
cv::Point2f trackCenter(startCenter.x, startCenter.y);
//起始扫描角度、半径
double trackAngle = startAngle, trackRadius = startRadius;
//元件本身角度
double trackOffset = dOffset;
//元件间间距
double partDist = (2 * asin(dChordL / (2 * trackRadius))) * 180 / PI;
//外接矩形
cv::Point2f pts[4];
//开始追踪
bool trackEnd = true;
//
do
{
bool found = true;
std::vector<Track> vParts;
for (double t = trackAngle - (trackOffset / 3.0 + partDist + trackOffset / 2.0); t > trackAngle - \
(trackOffset / 3.0 + partDist + trackOffset / 2.0) - trackOffset / 3.0; t -= dMinorStep)
{
trackCenter.x = float(reelCenter.x + trackRadius*cos(t*c));
trackCenter.y = float(reelCenter.y + trackRadius*sin(t*c));
//计算旋转矩形
calcRotateRect(trackCenter, (float)t, (float)trackLength, (float)trackWidth, pts);
//计算旋转矩形
calcRotateRect(trackCenter, (float)t, (float)trackLength, (float)trackWidth, pts);
//模板匹配
double maxyyu; cv::Point2f maxyyuloc;
findTrackModel(srcPrev, tplMat, 90.0 - (t + 180.0), trackWidth, pts, (255 - backT), false, maxyyu, maxyyuloc, cv::noArray());
//模板匹配
double maxyyu; cv::Point2f maxyyuloc;
findTrackModel(srcPrev, tplMat, 90.0 - (t + 180.0), trackWidth, pts, (255 - backT), false, maxyyu, maxyyuloc, cv::noArray());
//最小匹配结果
if (maxyyu > 0.15) {
//存放结果
vParts.push_back(Track(0, 0, maxyyu, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), std::vector<cv::Point2f>()));
}
//最小匹配结果
if (maxyyu > 0.15) {
//存放结果
vParts.push_back(Track(0, 0, maxyyu, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), std::vector<cv::Point2f>()));
}
//测试标记
//cv::drawMarker(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), cv::Scalar(0, 165, 255, 255), 0, 5);
}
if (vParts.size() == 0)
break;
//测试标记
//cv::drawMarker(cc, cv::Point(cvRound(trackCenter.x), cvRound(trackCenter.y)), cv::Scalar(0, 165, 255, 255), 0, 5);
}
if (vParts.size() == 0)
break;
//更新切线方向位置,由于这个方向是元件间隙不会有太大偏差
trackCenter = cv::Point2f((float)vParts[vParts.size() / 2].Pos.x, (float)vParts[vParts.size() / 2].Pos.y);
//更新切线方向位置,由于这个方向是元件间隙不会有太大偏差
trackCenter = cv::Point2f((float)vParts[vParts.size() / 2].Pos.x, (float)vParts[vParts.size() / 2].Pos.y);
//理论元件区域
cv::Point2f trackCenterT(trackCenter.x, trackCenter.y);
//理论元件区域
cv::Point2f trackCenterT(trackCenter.x, trackCenter.y);
//更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
///<开始离心/向心扫描(横向由于间隔固定所以一般不会出现偏离的情况,除非料盘本身严重变形或者中心定位出问题)
///<开始离心/向心扫描(横向由于间隔固定所以一般不会出现偏离的情况,除非料盘本身严重变形或者中心定位出问题)
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, pts);
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, pts);
//模板匹配/更新元件精确位置+判断
double maxyyu;
//findTrackModel(srcPrev, tplMat, 90.0 - (trackAngle + 180.0), trackWidth, pts, (255 - backT), false, maxyyu, trackCenter, cv::noArray());
//模板匹配/更新元件精确位置+判断
double maxyyu;
//findTrackModel(srcPrev, tplMat, 90.0 - (trackAngle + 180.0), trackWidth, pts, (255 - backT), false, maxyyu, trackCenter, cv::noArray());
//
bool trayEnd = false;
if (true) {
//考虑增加[-2,2]角度范围以应对料盘变形
trayEnd = findTrackModel(srcPrev, tplMat, 90.0 - (trackAngle + 180.0), trackWidth, pts, (255 - backT), true, maxyyu, trackCenter, binary);
}
//
bool trayEnd = false;
if (true) {
//考虑增加[-2,2]角度范围以应对料盘变形
trayEnd = findTrackModel(srcPrev, tplMat, 90.0 - (trackAngle + 180.0), trackWidth, pts, (255 - backT), true, maxyyu, trackCenter, binary);
}
//if (cvRound(trackCenter.x) == 1356 && cvRound(trackCenter.y) == 1812){
// std::cout << "xx" << std::endl;
//}
//if (cvRound(trackCenter.x) == 1356 && cvRound(trackCenter.y) == 1812){
// std::cout << "xx" << std::endl;
//}
//更新扫描半径
trackRadius = cv::norm(trackCenter - reelCenter);
//更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//更新偏移量
trackOffset = (2 * asin(2 * trackLength / (2 * trackRadius))) * 180 / PI;
//更新元件间角度
partDist = (2 * asin(dChordL / (2 * trackRadius))) * 180 / PI;
//更新扫描半径
trackRadius = cv::norm(trackCenter - reelCenter);
//更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//更新偏移量
trackOffset = (2 * asin(2 * trackLength / (2 * trackRadius))) * 180 / PI;
//更新元件间角度
partDist = (2 * asin(dChordL / (2 * trackRadius))) * 180 / PI;
//计算实际元件位置
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, pts);
//计算实际元件位置
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, pts);
#ifdef _DEBUG
cv::Point2f ptsT[4];
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, ptsT);
cv::Point2f ptsT[4];
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, ptsT);
if (!trayEnd)
{
//画出元件区域
for (int j = 0; j < 4; j++)
{
cv::line(cc, ptsT[j], ptsT[(j + 1) % 4], cv::Scalar(0, 0, 255, 255), 1);
}
}
if (!trayEnd)
{
//画出元件区域
for (int j = 0; j < 4; j++)
{
cv::line(cc, ptsT[j], ptsT[(j + 1) % 4], cv::Scalar(0, 0, 255, 255), 1);
}
}
#endif
//判断是否追踪终止
if (trayEnd)
{
//不再判断,大概率已经终止
found = false;
}
else if (trackMat.ptr<uint8_t>(cvRound(trackCenterT.y))[cvRound(trackCenterT.x)] == 255) {
//不再判断,大概率已经终止
found = false;
}
else if (trackMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] == 255) {
//判断是否追踪终止
if (trayEnd)
{
//不再判断,大概率已经终止
found = false;
}
else if (trackMat.ptr<uint8_t>(cvRound(trackCenterT.y))[cvRound(trackCenterT.x)] == 255) {
//不再判断,大概率已经终止
found = false;
}
else if (trackMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] == 255) {
//判断可能并未终止,遂采用理论位置作为下一个元件位置
trackCenter = trackCenterT;
//判断可能并未终止,遂采用理论位置作为下一个元件位置
trackCenter = trackCenterT;
///<更新追踪信息
//更新扫描半径
trackRadius = cv::norm(trackCenter - reelCenter);
//更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//更新偏移量
trackOffset = (2 * asin(2 * trackLength / (2 * trackRadius))) * 180 / PI;
//更新元件间角度
partDist = (2 * asin(dChordL / (2 * trackRadius))) * 180 / PI;
///<更新追踪信息
//更新扫描半径
trackRadius = cv::norm(trackCenter - reelCenter);
//更新扫描角度
trackAngle = atan2((double)trackCenter.y - reelCenter.y, (double)trackCenter.x - reelCenter.x) * 180 / PI;
//更新偏移量
trackOffset = (2 * asin(2 * trackLength / (2 * trackRadius))) * 180 / PI;
//更新元件间角度
partDist = (2 * asin(dChordL / (2 * trackRadius))) * 180 / PI;
//计算理论元件位置
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, pts);
//计算理论元件位置
calcRotateRect(trackCenter, (float)trackAngle, (float)trackLength, (float)trackWidth, pts);
//标记为已追踪过
std::vector<cv::Point> ptPoly = { cv::Point(pts[0]),cv::Point(pts[1]) ,cv::Point(pts[2]) ,cv::Point(pts[3]) };
cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255));
//标记为已追踪过
std::vector<cv::Point> ptPoly = { cv::Point(pts[0]),cv::Point(pts[1]) ,cv::Point(pts[2]) ,cv::Point(pts[3]) };
cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255));
//标记计数
lbMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] = 255;
//标记计数
lbMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] = 255;
//标记当前位置
cv::drawMarker(cc, trackCenter, cv::Scalar(0, 255, 0, 255), cv::MARKER_DIAMOND, 5);
//cv::drawMarker(cc, trackCenter, cv::Scalar(0, 0, 255, 255), 0, 5);
}
else
{
//标记为已追踪过
std::vector<cv::Point> ptPoly = { cv::Point(pts[0]),cv::Point(pts[1]) ,cv::Point(pts[2]) ,cv::Point(pts[3]) };
cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255));
//标记当前位置
cv::drawMarker(cc, trackCenter, cv::Scalar(0, 255, 0, 255), cv::MARKER_DIAMOND, 5);
//cv::drawMarker(cc, trackCenter, cv::Scalar(0, 0, 255, 255), 0, 5);
}
else
{
//标记为已追踪过
std::vector<cv::Point> ptPoly = { cv::Point(pts[0]),cv::Point(pts[1]) ,cv::Point(pts[2]) ,cv::Point(pts[3]) };
cv::fillConvexPoly(trackMat, ptPoly, cv::Scalar(255));
//标记计数
lbMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] = 255;
//标记计数
lbMat.ptr<uint8_t>(cvRound(trackCenter.y))[cvRound(trackCenter.x)] = 255;
//标记当前位置
cv::drawMarker(cc, trackCenter, cv::Scalar(0, 255, 0, 255), cv::MARKER_DIAMOND, 5);
//cv::drawMarker(cc, trackCenter, cv::Scalar(0, 0, 255, 255), 0, 5);
}
//标记当前位置
cv::drawMarker(cc, trackCenter, cv::Scalar(0, 255, 0, 255), cv::MARKER_DIAMOND, 5);
//cv::drawMarker(cc, trackCenter, cv::Scalar(0, 0, 255, 255), 0, 5);
}
trackEnd = (!found);
} while (!trackEnd);
trackEnd = (!found);
} while (!trackEnd);
}
#if OPTIMIZE_ON
);
);
#endif
}
......@@ -4969,6 +4978,8 @@ int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg
//去除局部量斑影响(默认亮斑尺寸不会大于15个像素)
cv::Mat srcTmp;
cv::morphologyEx(image, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
//去除局部黑斑影响
//图像增强
double min, max;
......@@ -5099,7 +5110,14 @@ int eyemInitModel(const char *ccTplName, IntPtr *hModelID)
std::string fileName = (*it);
cv::Mat tplMat; double matchDeg;
loadTrackModel(fileName.c_str(), tplMat, cv::Point(), matchDeg);
try
{
loadTrackModel(fileName.c_str(), tplMat, cv::Point(), matchDeg);
}
catch (...) {
return FUNC_CANNOT_CALC;
}
if (!tplMat.empty()) {
......@@ -5129,7 +5147,7 @@ int eyemInitModel(const char *ccTplName, IntPtr *hModelID)
//匹配分数
modelID.dMatchDeg = matchDeg;
//名称
//名称?会导致内存泄露吗
modelID.lpszName = (char *)CoTaskMemAlloc(128);
if (NULL != modelID.lpszName)
{
......@@ -5171,16 +5189,31 @@ int eyemAchvModelByName(const char *ccTplName, IntPtr hModelID, EyemModelID &tpM
return FUNC_OK;
}
int eyemInsertModel(IntPtr &hModelID, const char *ccTplName)
int eyemInsertModel(IntPtr hModelID, const char *ccTplName)
{
if (NULL == hModelID)
return FUNC_CANNOT_CALC;
std::vector<EyemModelID> *tpModelID = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
//判断是否重复
for (std::vector<EyemModelID>::iterator it = tpModelID->begin(); it != tpModelID->end(); ++it) {
if (std::strcmp((*it).lpszName, ccTplName) == 0) {
return FUNC_OK;
}
}
//加载指定模板
cv::Mat tplMat; double matchDeg;
loadTrackModel(ccTplName, tplMat, cv::Point(), matchDeg);
try
{
loadTrackModel(ccTplName, tplMat, cv::Point(), matchDeg);
}
catch (...) {
return FUNC_CANNOT_CALC;
}
//插到容器末尾
if (!tplMat.empty()) {
......@@ -5233,7 +5266,7 @@ int eyemInsertModel(IntPtr &hModelID, const char *ccTplName)
return FUNC_OK;
}
int eyemRemoveModelByName(IntPtr &hModelID, const char *ccTplName)
int eyemRemoveModelByName(IntPtr hModelID, const char *ccTplName)
{
if (NULL == hModelID)
return FUNC_CANNOT_CALC;
......@@ -5252,7 +5285,7 @@ int eyemRemoveModelByName(IntPtr &hModelID, const char *ccTplName)
CoTaskMemFree((LPVOID)modelID->lpszName);
free(modelID->vpImage);
//
modelID->vpImage = NULL;
modelID->vpImage = NULL; modelID->lpszName = NULL;
//删除
tpModelID->erase(it);
break;
......@@ -5377,6 +5410,93 @@ int eyemMatchTemplateModel(EyemImage tpImage, IntPtr hModelID, LPSTR *lpszTplNam
return FUNC_OK;
}
int eyemUpdateModel(const char *ccTplPath)
{
//获取文件路径
std::vector<std::string> fileNames;
cv::glob(ccTplPath, fileNames);
//判断文件
if (fileNames.size() <= 0)
return FUNC_CANNOT_CALC;
for (std::vector<std::string>::iterator it = fileNames.begin(); it != fileNames.end(); ++it) {
std::string fileName = (*it);
struct stat _Stat;
if (stat(fileName.c_str(), &_Stat) != 0)
return FUNC_CANNOT_CALC;
FILE *fps = NULL;
fopen_s(&fps, fileName.c_str(), "r");
//判断文件是否打开
if (NULL == fps)
return FUNC_CANNOT_CALC;
//获取文件大小
const int _Size = (int)_Stat.st_size;
//分配内存
unsigned char *_Data = (unsigned char *)malloc(_Size);
if (NULL == _Data)
return FUNC_CANNOT_CALC;
//初始化
memset(_Data, 0, _Size);
//读取数据
fread(_Data, sizeof(uint8_t), _Size, fps);
//关闭文件
fclose(fps);
////获取图像数据大小
//unsigned char _SizeData[8];
//memcpy(_SizeData, _Data, 8);
////有效信息长度
//const int valSize = std::atoi((const char *)_SizeData);
////文件信息
//const int tplSize = _Size - valSize - 8;
////拷贝文件信息
//char *tplInfo = new char[tplSize];
//memcpy(tplInfo, _Data + valSize + 8, tplSize);
////获取文件信息
//std::string line(tplInfo);
//std::vector<std::string> hints;
//split(line, ",", hints);
////宽,高,坐标,匹配度
//int X = std::atoi(hints[2].c_str()), Y = std::atoi(hints[3].c_str());
//double dMatchDeg = std::atof(hints[4].substr(0, 4).c_str()); pt = cv::Point(std::atoi(hints[0].c_str()), std::atoi(hints[1].c_str()));
//////创建图像文件
////cv::Mat tplMat= tplMat.create(Y, X, CV_8UC1, -1, true);
//////拷贝数据
////cv::Mat _tplMat = tplMat.getMat();
////memcpy(_tplMat.data, _Data + 8, valSize);
////释放内存
//delete[] tplInfo;
//tplInfo = NULL;
////释放文件内存
//free(_Data);
//_Data = NULL;
}
return FUNC_OK;
}
int eyemReleaseModel(IntPtr &hModelID)
{
if (NULL == hModelID)
......@@ -5404,7 +5524,7 @@ int eyemReleaseModel(IntPtr &hModelID)
return FUNC_OK;
}
int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults)
int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg)
{
cv::Mat refImg(tpRefImg.iHeight, tpRefImg.iWidth,
MAKETYPE(tpRefImg.iDepth, tpRefImg.iChannels), tpRefImg.vpImage);
......@@ -5415,6 +5535,11 @@ int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois,
if (refImg.empty() | nextImg.empty())
return FUNC_IMAGE_NOT_EXIST;
//显示图像
cv::Mat showMat;
showMat = nextImg.clone();
//转灰度图像
if (refImg.channels() != 1) {
cv::cvtColor(refImg, refImg, cv::COLOR_BGR2GRAY);
}
......@@ -5441,7 +5566,39 @@ int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois,
}
else
ipResults[i] = 0;
//寻找轮廓
std::vector<std::vector<cv::Point>> contours;
cv::findContours(binary(cv::Rect(tpRois[i].iXs, tpRois[i].iYs, tpRois[i].iWidth, tpRois[i].iHeight)), contours, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
//画图
for (int j = 0; j < contours.size(); j++)
{
cv::drawContours(showMat, contours, j, cv::Scalar(0, 0, 255), 3, 8, cv::noArray(), 2147483647, cv::Point(tpRois[i].iXs, tpRois[i].iYs));
}
}
cv::imshow("eyemLib", showMat);
cv::waitKey(1);
///<输出结果图像
{
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;
}
......
......@@ -14,7 +14,7 @@
constexpr double c = PI / 180.;
std::mutex mtx;
std::mutex mtx_misc;
#endif/* __EYEM_MISC_H */
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!