Commit 56be4c30 张士柳

1 个父辈 8123f16e
......@@ -6,6 +6,7 @@ using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
namespace eyemLib_Sharp
{
......@@ -589,6 +590,18 @@ namespace eyemLib_Sharp
public IntPtr hType; // 码类型
public IntPtr hText; // 码内容
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemModelID
{
public IntPtr vpImage; // 地址
public int iXs; // 图像X坐标
public int iYs; // 图像Y坐标
public int iWidth; // 图像内存X方向大小
public int iHeight; // 图像内存Y方向大小
public double dMatchDeg; // 匹配度
public IntPtr lpszName; // 名称
}
#endregion
#region 通用
......@@ -726,20 +739,29 @@ namespace eyemLib_Sharp
private static extern int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, string fileName, ref string pNumObj, out EyemImage tpDstImg);
//异型器件(新版本)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, string fileName, string ccTplName, ref string pNumObj, out EyemImage tpDstImg);
private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, string fileName, string ccTplName, IntPtr hModelID, ref string pNumObj, out EyemImage tpDstImg);
//创建模板匹配模型
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, string ccTplName);
//获取模板图像
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, out EyemImage tpDstImg);
//选取模板
//选取最匹配模板
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMatchTemplateModel(EyemImage tpImage, IntPtr hModelID, ref string lpszTplName);
//加载模板到内存
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMatchTemplateModel(EyemImage tpImage, string ccTplNames, ref string lpszTplName);
private static extern int eyemInitModel(string ccTplName, out IntPtr hModelID);
//通过名称获取模板
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
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 eyemReleaseModel(ref IntPtr hModelID);
//读码程序
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, string fileName, string strCodeType, out DataCodeHandle hObject, out EyemBarCode* tpResults, out int ipNum, bool bUseNiBlack, int iBlockSize, int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0);
//释放工具所使用句柄
//释放解码句柄
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern bool eyemDetectAndDecodeFree(IntPtr hObject);
//背景变化跟踪
......@@ -750,6 +772,7 @@ namespace eyemLib_Sharp
private static extern int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, IntPtr tpArray, int iArraySize);
#endregion
public static void eyemReadImageTool(string fileName)
{
Stopwatch sw = new Stopwatch();
......@@ -949,17 +972,26 @@ namespace eyemLib_Sharp
//double matchDeg = 0.80;
//flag = eyemCreateTemplateModel(tpDstImg, tpRoi2, matchDeg, "D:\\模板文件\\" + file.Replace(".png", ".tpl"));
//加载模板到内存
IntPtr hModelIDs = IntPtr.Zero;
flag = eyemInitModel("D:\\模板文件", out hModelIDs);
string selectModel = "";
flag = eyemMatchTemplateModel(tpDstImg, "D:\\模板文件", ref selectModel);
flag = eyemMatchTemplateModel(tpDstImg, hModelIDs, ref selectModel);
//根据名称获取模板
EyemModelID tpModelID = new EyemModelID();
eyemAchvModelByName(selectModel.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], hModelIDs, ref tpModelID);
//最好释放掉
//最好释放掉,如果对象供其他接口使用要先释放
eyemImageFree(ref tpDstImg);
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",""
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), 0.1, "IP_LARGE_PARTS", 100, 7, ref pNumObj, out tpDstImg);
//eyemCountObjectE(image, tpRoi, fileName, ref pNumObj, out tpDstImg);
eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), selectModel.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], ref pNumObj, out tpDstImg);
eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), selectModel.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], hModelIDs, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + /*file.Replace(".png", ".tpl")*/"74d571ed-9fd4-4959-85dd-3195261e4b48.tpl", ref pNumObj, out tpDstImg);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
......@@ -982,11 +1014,82 @@ namespace eyemLib_Sharp
sw.Stop();
Console.WriteLine("耗时:" + sw.ElapsedMilliseconds.ToString() + ",结果:" + pNumObj);
//在关闭程序时释放
eyemReleaseModel(ref hModelIDs);
//free image
eyemImageFree(ref tpDstImg);
eyemImageFree(ref image);
}
public static void eyemReadImageToolE(string fileName, IntPtr hModelID)
{
Stopwatch sw = new Stopwatch();
sw.Restart();
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 = 50; tpRoi.iYs = 50;
tpRoi.iWidth = image.iWidth - 100;
tpRoi.iHeight = image.iHeight - 100;
//
string pNumObj = "";
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//获取用于制作模板的图像
flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
string selectModel = "";
flag = eyemMatchTemplateModel(tpDstImg, hModelID, ref selectModel);
//根据名称获取模板
EyemModelID tpModelID = new EyemModelID();
eyemAchvModelByName(selectModel.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], hModelID, ref tpModelID);
//EyemImage tpModeImg = new EyemImage();
//tpModeImg.iChannels = 1; tpModeImg.iDepth = 0;
//tpModeImg.iWidth = tpModelID.iWidth; tpModeImg.iHeight = tpModelID.iHeight; tpModeImg.vpImage = tpModelID.vpImage;
//Bitmap bitmap = eyemCvtToBitmap(tpModeImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//最好释放掉,如果对象供其他接口使用要先释放
eyemImageFree(ref tpDstImg);
//点料
eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), selectModel.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0], hModelID, ref pNumObj, out tpDstImg);
//free image
eyemImageFree(ref tpDstImg);
eyemImageFree(ref image);
sw.Stop();
Console.WriteLine("耗时:" + sw.ElapsedMilliseconds.ToString() + ",结果:" + pNumObj);
}
public static int eyemInitModelE(out IntPtr hModelID)
{
return eyemInitModel("D:\\模板文件", out hModelID);
}
public static int eyemReleaseModelE(ref IntPtr hModelID)
{
return eyemReleaseModel(ref hModelID);
}
public static void eyemTestVideoCapture(string fileName)
{
......
......@@ -11,10 +11,10 @@ namespace eyemLib_Sharp
static void Main(string[] args)
{
string[] fileNames = Directory.GetFiles(@"D:\批量测试图像\", "*.*", SearchOption.AllDirectories);
//for (int j = 0; j < 100; j++)
//for (int j = 0; j < 250; j++)
//{
// ParallelOptions po = new ParallelOptions();
// po.MaxDegreeOfParallelism = 6;
// po.MaxDegreeOfParallelism = 3;
// Parallel.ForEach(fileNames, po, fn =>
// {
// EyemLib.eyemReadImageTool(fn);
......@@ -23,25 +23,23 @@ namespace eyemLib_Sharp
//}
//EyemLib.eyemTest2(fileNames);
for (int i = 0; i < 1000; i++)
//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++)
{
foreach (var item in fileNames)
for (int j = 0; j < fileNames.Length; j++)
{
EyemLib.eyemReadImageTool(item);
EyemLib.eyemReadImageToolE(fileNames[j], hModelID);
}
}
//for (int i = 0; i < 1; i++)
//{
// EyemLib.eyemTestVideoCapture("D:\\插件完成检测\\视频\\WeChat2.mp4");
//}
EyemLib.eyemReleaseModelE(ref hModelID);
//for (int i = 0; i < 5000; i++)
//{
// //EyemLib.eyemTest(fileNames);
// //EyemLib.eyemReadImageTool(fileNames);
// //Thread.Sleep(2);
//}
Console.Write("请按任意键继续。。。");
Console.ReadKey();
}
......
......@@ -441,7 +441,7 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string>
{
//创建解码器
Ref<Reader> reader_;
reader_.reset(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(DecodeHints::CODE_128_HINT | DecodeHints::CODE_39_HINT|DecodeHints::CODE_93_HINT)));
reader_.reset(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(DecodeHints::CODE_128_HINT | DecodeHints::CODE_39_HINT | DecodeHints::CODE_93_HINT)));
//一维码识别
for (int ii = 0; ii < waitAreas[i].oneDMats.size(); ii++)
{
......@@ -460,7 +460,7 @@ static void decodeMul(std::vector<WaitArea> &waitAreas, std::vector<std::string>
Ref<Binarizer> binarizer(new GlobalHistogramBinarizer(source));
Ref<BinaryBitmap> bitmap(new BinaryBitmap(binarizer));
//解码
Ref<Result> result(reader_->decode(bitmap, DecodeHints::CODE_128_HINT | DecodeHints::CODE_39_HINT|DecodeHints::CODE_93_HINT));
Ref<Result> result(reader_->decode(bitmap, DecodeHints::CODE_128_HINT | DecodeHints::CODE_39_HINT | DecodeHints::CODE_93_HINT));
if (!result.empty())
{
bDecode = true;
......@@ -1225,7 +1225,12 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
bool eyemDetectAndDecodeFree(IntPtr hObject)
{
std::vector<EyemBarCode> *tpResults = reinterpret_cast<std::vector<EyemBarCode>*>(hObject);
//清空容器
tpResults->clear();
//释放
delete tpResults;
tpResults = NULL;
return true;
}
\ No newline at end of file
......@@ -879,12 +879,17 @@ void eyemCloseWindow(const char *winname)
void eyemImageFree(EyemImage &tpImage)
{
tpImage.iWidth = tpImage.iHeight = tpImage.iDepth = tpImage.iChannels = 0;
//释放
free(tpImage.vpImage);
tpImage.vpImage = NULL;
}
bool eyemVideoCaptureFree(IntPtr hObject)
{
if (NULL == hObject)
return true;
std::vector<EyemImage> *tpImages = reinterpret_cast<std::vector<EyemImage>*>(hObject);
for (std::vector<EyemImage>::iterator it = tpImages->begin(); it != tpImages->end(); ++it)
......@@ -892,7 +897,9 @@ bool eyemVideoCaptureFree(IntPtr hObject)
(*it).iWidth = (*it).iHeight = (*it).iDepth = (*it).iChannels = 0;
free((*it).vpImage), (*it).vpImage = NULL;
}
//释放
delete tpImages;
tpImages = NULL;
return true;
}
\ No newline at end of file
......@@ -512,16 +512,16 @@ extern "C" {
// 线交叉状态
enum {
EYEM_CG_NOT_INTERSECTION, // 未相交
EYEM_CG_INTERSECTION, // 相交(彼此交叉)
EYEM_CG_NOT_INTERSECTION, // 未相交
EYEM_CG_INTERSECTION, // 相交(彼此交叉)
};
// 点位置状态
enum {
EYEM_CG_OUTER, // 在外部
EYEM_CG_INNER, // 在内部
EYEM_CG_BORDER // 在边界上
EYEM_CG_OUTER, // 在外部
EYEM_CG_INNER, // 在内部
EYEM_CG_BORDER // 在边界上
};
......@@ -549,8 +549,8 @@ extern "C" {
// 2 值 blob 分析(eyemBin.cpp)
//
enum {
EYEM_BIN_BLACK, // 黒
EYEM_BIN_WHITE // 白
EYEM_BIN_BLACK, // 黒
EYEM_BIN_WHITE // 白
};
//全局阈值2值化方法
......@@ -590,20 +590,20 @@ enum
// Blob 分析结果
typedef struct {
int iLabel; // 标签
int iArea; // 面积
double dCenterX; // 重心x坐标
double dCenterY; // 重心y坐标
int iXs, iYs, iXe, iYe; // 外接矩形(始点,终点)
int iWidth, iHeight; // 外接矩形(x 方向大小(宽度),y 方向大小(高度))
double dTheta; // 主轴倾斜角(rad)
int iLabel; // 标签
int iArea; // 面积
double dCenterX; // 重心x坐标
double dCenterY; // 重心y坐标
int iXs, iYs, iXe, iYe; // 外接矩形(始点,终点)
int iWidth, iHeight; // 外接矩形(x 方向大小(宽度),y 方向大小(高度))
double dTheta; // 主轴倾斜角(rad)
} EyemBinBlob;
typedef struct {
int iLabel; // 标签
double dX; // x坐标
double dY; // y坐标
double dVx, dVy; // 向量
int iLabel; // 标签
double dX; // x坐标
double dY; // y坐标
double dVx, dVy; // 向量
} EyemChainCode;
......@@ -678,12 +678,12 @@ extern "C" {
// 处理类型
enum {
EYEM_MATCH_LSQ, // 最小二乗法
EYEM_MATCH_LSQ_S, // 加权最小二乗法
EYEM_MATCH_ROBUST, // 稳健估计・无比例估计
EYEM_MATCH_ROBUST_S, // 稳健估计・带比例估计
EYEM_MATCH_MINMAX, // MINMAX方法・无比例估计
EYEM_MATCH_MINMAX_S // MINMAX方法・带比例估计
EYEM_MATCH_LSQ, // 最小二乗法
EYEM_MATCH_LSQ_S, // 加权最小二乗法
EYEM_MATCH_ROBUST, // 稳健估计・无比例估计
EYEM_MATCH_ROBUST_S, // 稳健估计・带比例估计
EYEM_MATCH_MINMAX, // MINMAX方法・无比例估计
EYEM_MATCH_MINMAX_S // MINMAX方法・带比例估计
};
......@@ -707,33 +707,33 @@ extern "C" {
// 模式数据
typedef struct {
int iPtnRefN; // 图案参考点数
EyemOcsDXY *tpObjPt; // 阵列参考点的实际坐标(単位:mm)
EyemOcsDXY *tpImgPt; // 图案参考点的图像坐标(単位:像素)
int iPtnRefN; // 图案参考点数
EyemOcsDXY *tpObjPt; // 阵列参考点的实际坐标(単位:mm)
EyemOcsDXY *tpImgPt; // 图案参考点的图像坐标(単位:像素)
} EyemCalibPtn;
// 同源矩阵
typedef struct {
double daH[3][3]; // 同源矩阵 H
double daInvH[3][3]; // 矩阵 H 的逆矩阵
double daH[3][3]; // 同源矩阵 H
double daInvH[3][3]; // 矩阵 H 的逆矩阵
} EyemCalibHom;
// 摄像机的内参数(intrinsic parameter)
typedef struct {
double daA[3][3]; // 内参数矩阵
double dK1, dK2; // 径向失真系数
double dK3, dK4, dK5; // 径向失真系数
double daInvA[3][3]; // 内参数矩阵的逆矩阵
double daA[3][3]; // 内参数矩阵
double dK1, dK2; // 径向失真系数
double dK3, dK4, dK5; // 径向失真系数
double daInvA[3][3]; // 内参数矩阵的逆矩阵
} EyemCalibInt;
// 摄像机外部参数(extrinsic parameter)
typedef struct {
double daR[3][3]; // 旋转矩阵
double daT[3]; // 平移矢量
double daRdr[3]; // 旋转矢量(罗德里格斯表示)
double daR[3][3]; // 旋转矩阵
double daT[3]; // 平移矢量
double daRdr[3]; // 旋转矢量(罗德里格斯表示)
} EyemCalibExt;
......@@ -821,13 +821,23 @@ extern "C" {
// 条码 解码结果
typedef struct {
double dAngle; // 角度
int iCenterX; // y坐标
int iCenterY; // y坐标
LPSTR lpszType; // 码类型
LPSTR lpszText; // 码内容
double dAngle; // 角度
int iCenterX; // y坐标
int iCenterY; // y坐标
LPSTR lpszType; // 码类型
LPSTR lpszText; // 码内容
} EyemBarCode;
typedef struct {
void *vpImage; // 地址
int iXs; // 图像X坐标
int iYs; // 图像Y坐标
int iWidth; // 图像内存X方向大小
int iHeight; // 图像内存Y方向大小
double dMatchDeg; // 匹配度
LPSTR lpszName; // 名称
} EyemModelID;
#ifdef __cplusplus
extern "C" {
......@@ -837,10 +847,15 @@ extern "C" {
EXPORTS int eyemCountObject(EyemImage tpImage, EyemRect tpRoi, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char *fileName, double dOffset, const char * ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char *ccTplName, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char *ccTplName, IntPtr hModelID, LPSTR *lpszReelNum, EyemImage *tpDstImg);
EXPORTS int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg);
EXPORTS int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, const char *ccTplName);
EXPORTS int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lpszTplName);
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(const char *ccTplName, IntPtr hModelID, EyemModelID &tpModelID);
EXPORTS int eyemInsertModel(const char *ccTplName, IntPtr hModelID, EyemModelID &tpModelID);
EXPORTS int eyemReleaseModel(IntPtr &hModelID);
EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults);
EXPORTS int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum);
......
此文件类型无法预览
......@@ -149,9 +149,10 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<OpenMPSupport>true</OpenMPSupport>
<OpenMPSupport>false</OpenMPSupport>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
......
......@@ -276,7 +276,7 @@ static void loadTrackModel(const char *fileName, cv::OutputArray tplMat, cv::Poi
if (stat(fileName, &_Stat) != 0)
return;
FILE *fps = fopen(fileName, "rb+");
FILE *fps = fopen(fileName, "r");
if (NULL == fps)
return;
......@@ -318,7 +318,7 @@ static void loadTrackModel(const char *fileName, cv::OutputArray tplMat, cv::Poi
split(line, ",", hints);
//释放内存
delete bitInfo;
delete[] bitInfo;
bitInfo = NULL;
//宽,高,坐标,匹配度
......@@ -4096,12 +4096,12 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, LP
return FUNC_OK;
}
int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char *tplName, LPSTR *lpszReelNum, EyemImage *tpDstImg)
int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char *ccTplName, IntPtr hModelID, LPSTR *lpszReelNum, EyemImage *tpDstImg)
{
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
//判断文件是否存在
if (src.empty()) {
if (src.empty() || NULL == hModelID) {
return FUNC_IMAGE_NOT_EXIST;
}
double begin0 = (double)cv::getTickCount();
......@@ -4117,13 +4117,29 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char
int X = src.cols, Y = src.rows;
//加载模板
cv::Mat tplMat; double matchDeg = 0.0;
loadTrackModel(tplName, tplMat, cv::Point(), matchDeg);
std::vector<EyemModelID> *tpModelIDs = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
cv::Mat _tplMat; double matchDeg = 0.0;
//
for (std::vector<EyemModelID>::iterator it = tpModelIDs->begin(); it != tpModelIDs->end(); ++it) {
if (std::strcmp((*it).lpszName, ccTplName) == 0)
{
EyemModelID tpModelID = (*it);
matchDeg = tpModelID.dMatchDeg;
_tplMat = cv::Mat(tpModelID.iHeight, tpModelID.iWidth, CV_8UC1, tpModelID.vpImage);
break;
}
}
//模板文件不存在
if (tplMat.empty())
if (_tplMat.empty())
return FUNC_CANNOT_CALC;
//模板反转
cv::Mat tplMat;
cv::bitwise_not(_tplMat, tplMat);
//模板尺寸
int tplWidth, tplHeight;
tplWidth = tplMat.cols, tplHeight = tplMat.rows;
......@@ -4957,8 +4973,8 @@ int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg
image.convertTo(image, CV_16UC1);
//转8位灰度图
cv::Mat src8U;
image.convertTo(src8U, CV_8UC1, 1 / 255.);
cv::Mat srcPrev;
image.convertTo(srcPrev, CV_8UC1, 1 / 255.);
//设定bin数目
const int histSize = 17;
......@@ -4967,30 +4983,26 @@ int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg
const float* histRange = { range };
//计算直方图
cv::Mat hist;
cv::calcHist(&src8U, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);
cv::calcHist(&srcPrev, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);
//计算背景像素
int maxIdx[2] = { 255,255 };
cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx);
//背景阈值
int backThresh = 15 * (maxIdx[0] - 2);
int backT = 15 * (maxIdx[0] - 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)
if (srcPrev.ptr<uint8_t>(y)[x] >= backT)
{
src8U.ptr<uint8_t>(y)[x] = backThresh;
srcPrev.ptr<uint8_t>(y)[x] = backT;
}
}
}
});
//预处理
cv::Mat srcPrev;
cv::bitwise_not(src8U, srcPrev);
///<输出计数结果标记图像
{
tpDstImg->iWidth = srcPrev.cols; tpDstImg->iHeight = srcPrev.rows; tpDstImg->iDepth = srcPrev.depth(); tpDstImg->iChannels = srcPrev.channels();
......@@ -5020,6 +5032,9 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
cv::Mat tplMat = image(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
//反转
cv::bitwise_not(tplMat, tplMat);
//内存尺寸(将信息添加到图像后面)
int _Size = tplMat.cols*tplMat.rows*tplMat.channels() * sizeof(uint8_t);
......@@ -5033,6 +5048,9 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
unsigned char *_Data = new unsigned char[_Size + hint.size() + 8];
if (NULL == _Data)
return FUNC_NOT_ENOUGH_MEM;
//拷贝头数据
memcpy(_Data, head.c_str(), 8);
......@@ -5047,7 +5065,7 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
ostream.write(reinterpret_cast<const char *>(_Data), _Size + hint.size() + 8);
//释放资源
delete _Data;
delete[] _Data;
_Data = NULL;
//关闭流
......@@ -5056,17 +5074,16 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
return FUNC_OK;
}
int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lpszTplName)
int eyemMatchTemplateModel(EyemImage tpImage, IntPtr hModelID, LPSTR *lpszTplName)
{
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
//判断图像是否存在
if (image.empty())
if (image.empty() || NULL == hModelID)
return FUNC_IMAGE_NOT_EXIST;
//获取文件路径
std::vector<std::string> fileNames;
getFiles(std::string(ccTplNames), fileNames);
//反转
cv::bitwise_not(image, image);
struct Track {
double dMatchDeg;
......@@ -5082,18 +5099,24 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps
return dMatchDeg > te.dMatchDeg;
}
};
//模板文件
std::vector<EyemModelID> *tpModelIDs = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
//载入所有模板
std::vector<Track> tplMats;
for (int i = 0; i < (int)fileNames.size(); i++)
for (std::vector<EyemModelID>::iterator it = tpModelIDs->begin(); it != tpModelIDs->end(); ++it)
{
double matchDeg;
EyemModelID tpModelID = (*it);
cv::Mat tplMat;
loadTrackModel(fileNames[i].c_str(), tplMat, cv::Point(), matchDeg);
cv::Mat tplMat; double matchDeg;
tplMat = cv::Mat(tpModelID.iHeight, tpModelID.iWidth, CV_8UC1, tpModelID.vpImage);
//模板取反
cv::Mat _tplMat;
cv::bitwise_not(tplMat, _tplMat);
if (!tplMat.empty())
tplMats.push_back(Track(matchDeg, fileNames[i], tplMat));
tplMats.push_back(Track(tpModelID.dMatchDeg, tpModelID.lpszName, _tplMat));
}
//模板文件不存在
......@@ -5107,30 +5130,28 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps
for (int tpl = range.start; tpl < range.end; tpl++)
{
double sumMatchDeg = 0.0; int sumMatchNum = 0;
//for (int i = 0; i < 4; i++)
{
//模板匹配(仅处理料盘区域以提高速度)
cv::Mat tplMat = tplMats[tpl].tplMat;
cv::Mat tplResult;
cv::matchTemplate(image, getTplMat(tplMats[tpl].tplMat, icvDirections[0], 0), tplResult, cv::TM_CCOEFF_NORMED);
//分数大于一定分数才当作元件处理
cv::Mat tplResult0 = cv::Mat(tplResult > tplMats[tpl].dMatchDeg);
//连通域分析
cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(tplResult0, labels, stats, centroids);
if (nccomps > 1) {
//累加分数
double maxVal = 0.;
for (int i = 1; i < nccomps; i++) {
sumMatchNum++;
cv::minMaxLoc(tplResult(cv::Rect(stats.ptr<int>(i)[cv::CC_STAT_LEFT], stats.ptr<int>(i)[cv::CC_STAT_TOP], \
stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT])), NULL, &maxVal, NULL, NULL);
sumMatchDeg += maxVal;
}
//模板匹配(仅处理料盘区域以提高速度)
cv::Mat tplMat = tplMats[tpl].tplMat;
cv::Mat tplResult;
cv::matchTemplate(image, getTplMat(tplMats[tpl].tplMat, icvDirections[0], 0), tplResult, cv::TM_CCOEFF_NORMED);
//分数大于一定分数才当作元件处理
cv::Mat tplResult0 = cv::Mat(tplResult > tplMats[tpl].dMatchDeg);
//连通域分析
cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(tplResult0, labels, stats, centroids);
if (nccomps > 1) {
//累加分数
double maxVal = 0.;
for (int i = 1; i < nccomps; i++) {
sumMatchNum++;
cv::minMaxLoc(tplResult(cv::Rect(stats.ptr<int>(i)[cv::CC_STAT_LEFT], stats.ptr<int>(i)[cv::CC_STAT_TOP], \
stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT])), NULL, &maxVal, NULL, NULL);
sumMatchDeg += maxVal;
}
}
if (sumMatchNum != 0) {
......@@ -5161,6 +5182,114 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps
{
strcpy(*lpszTplName, bestMatch.c_str());
}
else return FUNC_NOT_ENOUGH_MEM;
return FUNC_OK;
}
int eyemInitModel(const char *ccTplName, IntPtr *hModelID)
{
//获取文件路径
std::vector<std::string> fileNames;
cv::glob(ccTplName, fileNames);
//载入所有模板
std::vector<EyemModelID> *tpModelIDs = new std::vector<EyemModelID>();
for (std::vector<std::string>::iterator it = fileNames.begin(); it != fileNames.end(); ++it)
{
std::string fileName = (*it);
cv::Mat tplMat; double matchDeg;
loadTrackModel(fileName.c_str(), tplMat, cv::Point(), matchDeg);
if (!tplMat.empty()) {
cv::Mat _tplMat;
cv::bitwise_not(tplMat, _tplMat);
//载入模板
EyemModelID modelID;
int _Size = tplMat.cols*tplMat.rows * sizeof(unsigned char);
//数据
modelID.vpImage = (unsigned char *)malloc(_Size);
if (NULL == modelID.vpImage)
return FUNC_NOT_ENOUGH_MEM;
//拷贝数据
memcpy(modelID.vpImage, _tplMat.data, _Size);
//位置
modelID.iXs = modelID.iYs = 0;
//宽、高
modelID.iWidth = tplMat.cols; modelID.iHeight = tplMat.rows;
//匹配分数
modelID.dMatchDeg = matchDeg;
//名称
modelID.lpszName = (char *)CoTaskMemAlloc(128);
if (NULL != modelID.lpszName)
{
char file[128] = { 0 };
sprintf_s(file, "%s", fileName.c_str());
strcpy(modelID.lpszName, file);
}
else return FUNC_NOT_ENOUGH_MEM;
//压入堆栈
tpModelIDs->push_back(modelID);
}
}
//输出
*hModelID = reinterpret_cast<IntPtr>(tpModelIDs);
return FUNC_OK;
}
int eyemAchvModelByName(const char *ccTplName, IntPtr hModelID, EyemModelID &tpModelID)
{
std::vector<EyemModelID> *tpModelIDs = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
for (std::vector<EyemModelID>::iterator it = tpModelIDs->begin(); it != tpModelIDs->end(); ++it) {
if (std::strcmp((*it).lpszName, ccTplName) == 0) {
EyemModelID modelID = (*it);
tpModelID.dMatchDeg = modelID.dMatchDeg; tpModelID.iHeight = modelID.iHeight; tpModelID.iWidth = modelID.iWidth;
tpModelID.iXs = tpModelID.iYs = 0;
tpModelID.lpszName = modelID.lpszName;
tpModelID.vpImage = modelID.vpImage;
break;
}
}
return FUNC_OK;
}
int eyemReleaseModel(IntPtr &hModelID)
{
if (NULL == hModelID)
return FUNC_OK;
std::vector<EyemModelID> *tpResults = reinterpret_cast<std::vector<EyemModelID>*>(hModelID);
for (std::vector<EyemModelID>::iterator it = tpResults->begin(); it != tpResults->end(); ++it)
{
(*it).dMatchDeg = (*it).iHeight = (*it).iWidth = (*it).iXs = (*it).iYs = 0;
//释放内容
CoTaskMemFree((LPVOID)(*it).lpszName);
free((*it).vpImage);
}
//清空容器
tpResults->clear();
//释放容器
delete tpResults;
tpResults = NULL; hModelID = NULL;
return FUNC_OK;
}
......
......@@ -14,5 +14,7 @@
constexpr double c = PI / 180.;
//std::mutex mtx;
#endif/* __EYEM_MISC_H */
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!