Commit ef64ee34 张士柳

1 个父辈 71f29f62
...@@ -719,7 +719,7 @@ namespace eyemLib_Sharp ...@@ -719,7 +719,7 @@ namespace eyemLib_Sharp
private static extern int eyemCountObjectE(EyemImage tpImage, string fileName, ref string pNumObj, out EyemImage tpDstImg); private static extern int eyemCountObjectE(EyemImage tpImage, string fileName, ref string pNumObj, out EyemImage tpDstImg);
//异型器件(新版本) //异型器件(新版本)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, string fileName, string ccTplName, double dMinScore, ref string pNumObj, out EyemImage tpDstImg); private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, string fileName, string ccTplName, ref string pNumObj, out EyemImage tpDstImg);
//创建模板匹配模型 //创建模板匹配模型
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, string ccTplName); private static extern int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, string ccTplName);
...@@ -910,40 +910,53 @@ namespace eyemLib_Sharp ...@@ -910,40 +910,53 @@ namespace eyemLib_Sharp
//eyemEdgesPixel(ucpImage, 15); //eyemEdgesPixel(ucpImage, 15);
#endregion #endregion
EyemRect tpRoi = new EyemRect(); EyemRect tpRoi = new EyemRect();
tpRoi.iXs = 1026; tpRoi.iYs = 513; tpRoi.iXs = 200; tpRoi.iYs = 200;
tpRoi.iWidth = 82; tpRoi.iWidth = image.iWidth - 400;
tpRoi.iHeight = 60; tpRoi.iHeight = image.iHeight - 400;
//EyemRect tpRoi = new EyemRect(); //
//tpRoi.iXs = 200; tpRoi.iYs = 200; string pNumObj = "";
//tpRoi.iWidth = image.iWidth - 400; string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//tpRoi.iHeight = image.iHeight - 400;
//获取用于制作模板的图像
flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
//Bitmap bmp = eyemCvtToBitmap(tpDstImg);
//if (bmp != null)
//{
// bmp.Save("D:\\模板文件原图\\" + file);
//}
//创建模板匹配模型 //创建模板匹配模型
double dMinScore = 0.75; EyemRect tpRoi2 = new EyemRect();
flag = eyemCreateTemplateModel(image, tpRoi, dMinScore, "D://模板文件//template.tpl"); tpRoi2.iXs = 1112; tpRoi2.iYs = 414;
tpRoi2.iWidth = 68;
tpRoi2.iHeight = 79;
//double matchDeg = 0.75;
//flag = eyemCreateTemplateModel(tpDstImg, tpRoi2, matchDeg, "D://模板文件//" + file.Replace(".png", ".tpl"));
string selectModel = ""; string selectModel = "";
flag = eyemMatchTemplateModel(image, "D:\\模板文件", ref selectModel); flag = eyemMatchTemplateModel(tpDstImg, "D:\\模板文件", ref selectModel);
//flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg); //最好释放掉
eyemImageFree(ref tpDstImg);
//
string pNumObj = "";
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","" //"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",""
//eyemCountObject(image, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg); //eyemCountObject(image, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularParts(image, file.Replace(".png", ""), 0.1, "IP_LARGE_PARTS", 100, 7, ref pNumObj, out tpDstImg); //eyemCountObjectIrregularParts(image, file.Replace(".png", ""), 0.1, "IP_LARGE_PARTS", 100, 7, ref pNumObj, out tpDstImg);
//eyemCountObjectE(image, fileName, ref pNumObj, out tpDstImg); //eyemCountObjectE(image, fileName, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), "D://批量测试图像模板文件//" + file.Replace(".png", "") + "_tpl.png", 0.75, ref pNumObj, out tpDstImg); eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), selectModel, ref pNumObj, out tpDstImg);
//Bitmap bmp = eyemCvtToBitmap(tpDstImg); Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bmp != null) if (bitmap != null)
//{ {
// bmp.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;
...@@ -1128,17 +1141,16 @@ namespace eyemLib_Sharp ...@@ -1128,17 +1141,16 @@ namespace eyemLib_Sharp
BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, tpImage.iWidth, tpImage.iHeight), BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, tpImage.iWidth, tpImage.iHeight),
ImageLockMode.WriteOnly, format); ImageLockMode.WriteOnly, format);
int srcStep = tpImage.iWidth * tpImage.iChannels; try
int dstStep = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4; {
int pd = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4;
long bytesToCopy = tpImage.iWidth * tpImage.iChannels; long bytesToCopy = tpImage.iWidth * tpImage.iChannels;
try
{
for (int y = 0; y < tpImage.iHeight; y++) for (int y = 0; y < tpImage.iHeight; y++)
{ {
long offsetSrc = (y * srcStep); long offsetSrc = (y * tpImage.iWidth * tpImage.iChannels);
long offsetDst = (y * dstStep); long offsetDst = (y * pd);
Buffer.MemoryCopy((byte*)(tpImage.vpImage.ToPointer()) + offsetSrc, (byte*)(bd.Scan0.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy); Buffer.MemoryCopy((byte*)(tpImage.vpImage.ToPointer()) + offsetSrc, (byte*)(bd.Scan0.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy);
} }
......
...@@ -594,10 +594,25 @@ namespace eyemLib_Sharp ...@@ -594,10 +594,25 @@ namespace eyemLib_Sharp
#region 项目 #region 项目
//普通器件 //普通器件
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObject(EyemImage tpImage, string fileName, ref string pNumObj, out EyemImage tpDstImg); private static extern int eyemCountObject(EyemImage tpImage, string fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, ref string pNumObj, out EyemImage tpDstImg);
//异型器件 //异型器件
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectIrregularParts(EyemImage tpImage, string fileName, string strType, string tplName, double dMinScore, ref string pNumObj, out EyemImage tpDstImg); private static extern int eyemCountObjectIrregularParts(EyemImage tpImage, string fileName, double dOffset, string strType, int iMaxArea, int iWinSize, ref string pNumObj, out EyemImage tpDstImg);
//普通器件(新版本)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectE(EyemImage tpImage, string fileName, ref string pNumObj, out EyemImage tpDstImg);
//异型器件(新版本)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, string fileName, string ccTplName, 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, string ccTplNames, ref string lpszTplName);
//读码程序 //读码程序
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [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); 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);
...@@ -665,7 +680,77 @@ namespace eyemLib_Sharp ...@@ -665,7 +680,77 @@ namespace eyemLib_Sharp
#endregion #endregion
//点料算法例程
public static void eyeyTestTemplateModelMethod(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 bmp = eyemCvtToBitmap(tpDstImg);
if (bmp != null)
{
bmp.Save("D:\\模板文件原图\\" + file);
}
//创建模板匹配模型
EyemRect tpRoi2 = new EyemRect();
tpRoi2.iXs = 1112; tpRoi2.iYs = 414;
tpRoi2.iWidth = 68;
tpRoi2.iHeight = 79;
//匹配分数
double matchDeg = 0.75;
flag = eyemCreateTemplateModel(tpDstImg, tpRoi2, matchDeg, "D://模板文件//" + file.Replace(".png", ".tpl"));
//可以选择使用自动匹配或者指定模板文件
string selectModel = "";
flag = eyemMatchTemplateModel(tpDstImg, "D:\\模板文件", ref selectModel);
//最好释放掉,点料会用到,或者重新创建一个供不同函数使用
eyemImageFree(ref tpDstImg);
string pNumObj = "";
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",""
//eyemCountObject(image, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularParts(image, file.Replace(".png", ""), 0.1, "IP_LARGE_PARTS", 100, 7, ref pNumObj, out tpDstImg);
//eyemCountObjectE(image, fileName, ref pNumObj, out tpDstImg);
eyemCountObjectIrregularPartsE(image, file.Replace(".png", ""), selectModel, ref pNumObj, out tpDstImg);
Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null)
{
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
}
//free image
eyemImageFree(ref tpDstImg);
eyemImageFree(ref image);
}
//背景变化追踪例程
public static void eyemTestVideoCapture(string fileName) public static void eyemTestVideoCapture(string fileName)
{ {
List<EyemRect3> tpRois = new List<EyemRect3>(); List<EyemRect3> tpRois = new List<EyemRect3>();
...@@ -735,6 +820,71 @@ namespace eyemLib_Sharp ...@@ -735,6 +820,71 @@ namespace eyemLib_Sharp
} }
} }
#region EyemImage转换成Bitmap
public static Bitmap eyemCvtToBitmap(EyemImage tpImage)
{
if (tpImage.vpImage == IntPtr.Zero)
throw new ArgumentNullException("图像不存在");
if (tpImage.iDepth != 0)
throw new ArgumentException("图像必须是8位无符号整型");
PixelFormat format;
switch (tpImage.iChannels)
{
case 1:
format = PixelFormat.Format8bppIndexed;
break;
case 3:
format = PixelFormat.Format24bppRgb;
break;
case 4:
format = PixelFormat.Format32bppArgb;
break;
default:
return null;
}
Bitmap bitmap = new Bitmap(tpImage.iWidth, tpImage.iHeight, format);
//对于输出灰度图像
if (format == PixelFormat.Format8bppIndexed)
{
ColorPalette palette = bitmap.Palette;
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
bitmap.Palette = palette;
}
//锁定数据区
BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, tpImage.iWidth, tpImage.iHeight),
ImageLockMode.WriteOnly, format);
try
{
int pd = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4;
long bytesToCopy = tpImage.iWidth * tpImage.iChannels;
for (int y = 0; y < tpImage.iHeight; y++)
{
long offsetSrc = (y * tpImage.iWidth * tpImage.iChannels);
long offsetDst = (y * pd);
Buffer.MemoryCopy((byte*)(tpImage.vpImage.ToPointer()) + offsetSrc, (byte*)(bd.Scan0.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy);
}
}
finally
{
bitmap.UnlockBits(bd);
}
return bitmap;
}
#endregion
#region 结构体转内存指针 #region 结构体转内存指针
public static IntPtr eyemStructArray2IntPtr<T>(T[] tpArray) public static IntPtr eyemStructArray2IntPtr<T>(T[] tpArray)
{ {
......
...@@ -323,6 +323,9 @@ int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, ...@@ -323,6 +323,9 @@ int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth,
else else
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
//关闭文件
fclose(fp);
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
int main() int main()
{ {
//char* filename = "D:\\Matlabͼ\\circle_plate_04.png"; char* filename = "D:\\Matlabͼ\\circle_plate_04.png";
//cv::Mat src = cv::imread(filename, cv::IMREAD_GRAYSCALE); cv::Mat src = cv::imread(filename, cv::IMREAD_UNCHANGED);
//EyemImage tpImage; //EyemImage tpImage;
//tpImage.iHeight = src.rows; //tpImage.iHeight = src.rows;
//tpImage.iWidth = src.cols; //tpImage.iWidth = src.cols;
......
...@@ -835,7 +835,7 @@ extern "C" { ...@@ -835,7 +835,7 @@ extern "C" {
EXPORTS int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectE(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObjectE(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char * ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char * ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, const char *ccTplName, double dMinScore, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, const char *ccTplName, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, 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 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, const char *ccTplNames, LPSTR *lpszTplName);
......
...@@ -112,7 +112,7 @@ static cv::Mat getTplMat(cv::Mat &tplMat, double t, int val) ...@@ -112,7 +112,7 @@ static cv::Mat getTplMat(cv::Mat &tplMat, double t, int val)
} }
/** 获取旋转后的图像 /** 获取旋转后的图像
trackMat输入图像 trackMat 输入图像
t 输入角度 t 输入角度
val 填充内容 val 填充内容
matx 转换矩阵 matx 转换矩阵
...@@ -144,7 +144,18 @@ static cv::Mat getTrackMat(cv::Mat &trackMat, double t, int val, float *matx) ...@@ -144,7 +144,18 @@ static cv::Mat getTrackMat(cv::Mat &trackMat, double t, int val, float *matx)
return tplMatD; return tplMatD;
} }
/** 模板追踪匹配
image 输入图像
tplMat 输入模板
t 方位角
trackWidth 扩充宽度
pts 矩形顶点
val 填充像素
bFinal 是否进行精确位置定位
maxVal 输出最大匹配分数
maxLoc 输出最大匹配坐标
mask 掩膜
*/
static bool findTrackModel(cv::Mat& image, cv::Mat &tplMat, double t, double trackWidth, cv::Point2f *pts, int val, bool bFinal, double &maxVal, cv::Point2f &maxLoc, cv::InputArray mask = cv::noArray()) static bool findTrackModel(cv::Mat& image, cv::Mat &tplMat, double t, double trackWidth, cv::Point2f *pts, int val, bool bFinal, double &maxVal, cv::Point2f &maxLoc, cv::InputArray mask = cv::noArray())
{ {
//图像尺寸 //图像尺寸
...@@ -224,6 +235,66 @@ static bool findTrackModel(cv::Mat& image, cv::Mat &tplMat, double t, double tra ...@@ -224,6 +235,66 @@ static bool findTrackModel(cv::Mat& image, cv::Mat &tplMat, double t, double tra
return false; return false;
} }
/** 分割字符串
cStrText 输入文本
cStrDelim 输入分隔符
vStrs 输出分割后内容
*/
static void split(const std::string &cStrText, const std::string &cStrDelim, std::vector<std::string> &vStrs)
{
char *cpStr = new char[strlen(cStrText.c_str()) + 1];
strcpy(cpStr, cStrText.c_str());
//分割
char *token = NULL, *ptr = NULL;
token = strtok_s(cpStr, cStrDelim.c_str(), &ptr);
while (NULL != token)
{
vStrs.push_back(token);
token = strtok_s(NULL, cStrDelim.c_str(), &ptr);
}
delete[] cpStr;
cpStr = NULL;
}
/** 载入模板
trackMat 输入文件名
*/
static void loadTrackModel(const char *fileName, cv::OutputArray tplMat, cv::Point &pt, double &dMatchDeg)
{
//读取测试用
std::ifstream istream(fileName, std::ios::in | std::ios::binary);
std::string line;
while (std::getline(istream, line));
istream.close();
//获取文件信息
std::vector<std::string> hints;
split(line, ",", hints);
int X = std::atoi(hints[2].c_str()), Y = std::atoi(hints[3].c_str());
dMatchDeg = std::atof(hints[4].c_str()); pt = cv::Point(std::atoi(hints[0].c_str()), std::atoi(hints[1].c_str()));
//读取文件
FILE *fp = fopen(fileName, "rb+");
tplMat.create(Y, X, CV_8UC1, -1, true);
if (NULL != fp)
{
cv::Mat _tplMat = tplMat.getMat();
fread(_tplMat.data, sizeof(uint8_t), X*Y, fp);
}
//关闭文件
fclose(fp);
}
/** 获取文件夹内所有文件
filePath 输入文件夹
fileNames 输出文件
*/
static void getFiles(std::string filePath, std::vector<std::string>& fileNames) static void getFiles(std::string filePath, std::vector<std::string>& fileNames)
{ {
//文件句柄 //文件句柄
...@@ -248,22 +319,9 @@ static void getFiles(std::string filePath, std::vector<std::string>& fileNames) ...@@ -248,22 +319,9 @@ static void getFiles(std::string filePath, std::vector<std::string>& fileNames)
} }
} }
static void split(const std::string &cStrText, const std::string &cStrDelim, std::vector<std::string> &vStrs) /** 计算Otsu阈值
{ hist 输入直方图
char *cpStr = new char[strlen(cStrText.c_str()) + 1]; */
strcpy(cpStr, cStrText.c_str());
//分割
char *token = NULL, *ptr = NULL;
token = strtok_s(cpStr, cStrDelim.c_str(), &ptr);
while (NULL != token)
{
vStrs.push_back(token);
token = strtok_s(NULL, cStrDelim.c_str(), &ptr);
}
delete[] cpStr;
cpStr = NULL;
}
static int Otsu(int hist[]) static int Otsu(int hist[])
{ {
// Otsu's threshold algorithm // Otsu's threshold algorithm
...@@ -315,6 +373,9 @@ static int Otsu(int hist[]) ...@@ -315,6 +373,9 @@ static int Otsu(int hist[])
return kStar; return kStar;
} }
/** 计算Otsu阈值
_src 输入图像
*/
static double getThreshVal_Otsu_8u(const cv::Mat& _src) static double getThreshVal_Otsu_8u(const cv::Mat& _src)
{ {
cv::Size size = _src.size(); cv::Size size = _src.size();
...@@ -391,6 +452,11 @@ static double getThreshVal_Otsu_8u(const cv::Mat& _src) ...@@ -391,6 +452,11 @@ static double getThreshVal_Otsu_8u(const cv::Mat& _src)
return max_val; return max_val;
} }
/** 计算元件尺寸
srcPrev 输入图像
mask 输入掩膜
partSize 输出元件尺寸
*/
static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize) static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize)
{ {
int X = srcPrev.cols, Y = srcPrev.rows; int X = srcPrev.cols, Y = srcPrev.rows;
...@@ -3986,9 +4052,11 @@ int eyemCountObjectE(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj, ...@@ -3986,9 +4052,11 @@ int eyemCountObjectE(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj,
return FUNC_OK; return FUNC_OK;
} }
int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, const char *tplName, double dMinScore, LPSTR *lpszNumObj, EyemImage *tpDstImg) int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, const char *tplName, LPSTR *lpszNumObj, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
//判断文件是否存在
if (src.empty()) { if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
...@@ -4005,7 +4073,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4005,7 +4073,8 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
//加载模板 //加载模板
cv::Mat tplMat = cv::imread(tplName, -1); cv::Mat tplMat; double matchDeg = 0.0;
loadTrackModel(tplName, tplMat, cv::Point(), matchDeg);
//模板文件不存在 //模板文件不存在
if (tplMat.empty()) if (tplMat.empty())
...@@ -4071,8 +4140,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4071,8 +4140,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::Mat binary, srcPrev; cv::Mat binary, srcPrev;
cv::bitwise_not(src8U, srcPrev); cv::bitwise_not(src8U, srcPrev);
//创建模板图像
//计数图像 //计数图像
cv::Mat lbMat(Y, X, CV_8UC1, cv::Scalar(0)); cv::Mat lbMat(Y, X, CV_8UC1, cv::Scalar(0));
...@@ -4170,7 +4237,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4170,7 +4237,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
cv::matchTemplate(srcPrev(cv::Rect(tl, br)), getTplMat(tplMat, t, (255 - backThresh)), tplResult0, cv::TM_CCOEFF_NORMED); cv::matchTemplate(srcPrev(cv::Rect(tl, br)), getTplMat(tplMat, t, (255 - backThresh)), tplResult0, cv::TM_CCOEFF_NORMED);
//分数大于一定分数才当作元件处理 //分数大于一定分数才当作元件处理
tplResult0 = cv::Mat(tplResult0 > dMinScore); tplResult0 = cv::Mat(tplResult0 > matchDeg);
cv::Point quard[4]{ cv::Point(tplResult0.cols,0),cv::Point(0,0),cv::Point(0,tplResult0.rows),cv::Point(tplResult0.cols,tplResult0.rows) }; cv::Point quard[4]{ cv::Point(tplResult0.cols,0),cv::Point(0,0),cv::Point(0,tplResult0.rows),cv::Point(tplResult0.cols,tplResult0.rows) };
...@@ -4273,14 +4340,14 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4273,14 +4340,14 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
findTrackModel(srcPrev, tplMat, 90.0 - (t + 180.0), trackWidth, pts, (255 - backThresh), false, maxyyu, trackCentert, cv::noArray()); findTrackModel(srcPrev, tplMat, 90.0 - (t + 180.0), trackWidth, pts, (255 - backThresh), false, maxyyu, trackCentert, cv::noArray());
//匹配阈值 //匹配阈值
if (maxyyu > dMinScore) if (maxyyu > matchDeg)
{ {
track4ChordL.push_back(Track(0, 0, maxyyu, (cv::Point)trackCentert, std::vector<cv::Point2f>())); track4ChordL.push_back(Track(0, 0, maxyyu, (cv::Point)trackCentert, std::vector<cv::Point2f>()));
if (!expect) if (!expect)
expect = true; expect = true;
} }
if ((maxyyu < dMinScore) && expect) if ((maxyyu < matchDeg) && expect)
break; break;
} }
...@@ -4809,8 +4876,12 @@ int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg ...@@ -4809,8 +4876,12 @@ int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg
int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, const char *ccTplName) int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, const char *ccTplName)
{ {
cv::Mat tplMat = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage)\ cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
if (image.empty())
return FUNC_IMAGE_NOT_EXIST;
cv::Mat tplMat = image(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
//模板信息 //模板信息
std::string hint = std::to_string(tpRoi.iXs) + "," + std::to_string(tpRoi.iYs) + "," \ std::string hint = std::to_string(tpRoi.iXs) + "," + std::to_string(tpRoi.iYs) + "," \
...@@ -4819,27 +4890,16 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, ...@@ -4819,27 +4890,16 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
//内存尺寸(将信息添加到图像后面) //内存尺寸(将信息添加到图像后面)
int _Size = tplMat.cols*tplMat.rows*tplMat.channels() * sizeof(uint8_t); int _Size = tplMat.cols*tplMat.rows*tplMat.channels() * sizeof(uint8_t);
unsigned char *_Dst = new unsigned char[_Size];
//拷贝图像
memcpy(_Dst, tplMat.data, _Size);
//写入本地 //写入本地
std::ofstream outFile(ccTplName, std::ios::binary); std::ofstream ostream(ccTplName, std::ios::binary);
ostream.write(reinterpret_cast<const char *>(tplMat.data), _Size);
//写入图像 //换行写入信息
outFile.write(reinterpret_cast<const char *>(tplMat.data), _Size); ostream << std::endl;
ostream.write(hint.c_str(), hint.size());
//写入信息
outFile << std::endl;
outFile.write(hint.c_str(), hint.size());
//关闭流 //关闭流
outFile.close(); ostream.close();
//释放资源
delete _Dst;
_Dst = NULL;
return FUNC_OK; return FUNC_OK;
} }
...@@ -4852,72 +4912,79 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps ...@@ -4852,72 +4912,79 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps
if (image.empty()) if (image.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
const float icvDirections[4] = { 0 , 90 , 180 , -90 }; //获取文件路径
std::vector<std::string> fileNames;
getFiles(std::string(ccTplNames), fileNames);
struct Track { struct Track {
double dMatchDeg; double dMatchDeg;
cv::Point Pos; std::string tplName;
cv::Mat tplMat; cv::Mat tplMat;
Track() {}; Track() {};
Track(double dMatchDeg, cv::Point Pos, cv::Mat tplMat) :dMatchDeg(dMatchDeg), Pos(Pos), tplMat(tplMat) {}; Track(double dMatchDeg, std::string tplName, cv::Mat tplMat) :dMatchDeg(dMatchDeg), tplName(tplName), tplMat(tplMat) {};
};
//获取文件路径 bool operator >(const Track &te)const
std::vector<std::string> fileNames; {
getFiles(std::string(ccTplNames), fileNames); return dMatchDeg > te.dMatchDeg;
}
};
//载入所有模板 //载入所有模板
std::vector<Track> tckMats; std::vector<Track> tplMats;
for (int i = 0; i < (int)fileNames.size(); i++) for (int i = 0; i < (int)fileNames.size(); i++)
{ {
cv::Mat tckMat; double matchDeg;
//读取测试用
std::ifstream inFile(fileNames[i], std::ios::in | std::ios::binary);
std::string line; cv::Mat tplMat;
while (std::getline(inFile, line)); loadTrackModel(fileNames[i].c_str(), tplMat, cv::Point(), matchDeg);
inFile.close();
//获取文件信息 tplMats.push_back(Track(matchDeg, fileNames[i], tplMat));
std::vector<std::string> hints; }
split(line, ",", hints);
int X = std::atoi(hints[2].c_str()), Y = std::atoi(hints[3].c_str()); //模板文件不存在
if (tplMats.size() <= 0)
return FUNC_CANNOT_CALC;
double dMatchDeg = std::atof(hints[4].c_str()); cv::Point pt(std::atoi(hints[0].c_str()), std::atoi(hints[1].c_str())); const float icvDirections[4] = { 0 , 90 , 180 , -90 };
//读取文件 //遍历所有模板选择最佳匹配模板
FILE *fp = fopen(fileNames[i].c_str(), "rb+"); cv::parallel_for_(cv::Range(0, (int)tplMats.size()), [&](const cv::Range& range)->void {
for (int tpl = range.start; tpl < range.end; tpl++)
{
double sumMatchDeg = 0.0;
for (int i = 0; i < 4; i++)
{
//模板匹配(仅处理料盘区域以提高速度)
cv::Mat tplResult;
cv::matchTemplate(image, getTplMat(tplMats[tpl].tplMat, icvDirections[i], 0), tplResult, cv::TM_CCOEFF_NORMED);
if (NULL != fp) //分数大于一定分数才当作元件处理
cv::Mat tplResult0 = cv::Mat(tplResult > tplMats[tpl].dMatchDeg);
//连通域分析
std::vector<cv::Point> locations;
cv::findNonZero(tplResult0, locations);
for (int j = 0; j < (int)locations.size(); j++)
{ {
tckMat = cv::Mat(Y, X, CV_8UC1); sumMatchDeg += tplResult.ptr<float>(locations[j].y)[locations[j].x];
fread(tckMat.data, sizeof(uint8_t), X*Y, fp);
} }
else
return FUNC_IMAGE_NOT_EXIST;
tckMats.push_back(Track(dMatchDeg, pt, tckMat));
} }
tplMats[tpl].dMatchDeg = sumMatchDeg;
////遍历所有模板 }
//cv::parallel_for_(cv::Range(0, (int)tckMats.size()), [&](const cv::Range& range)->void { });
// for (int tpl = range.start; tpl < range.end; tpl++)
// {
// cv::Mat tplMat = tckMats[tpl].tplMat;
// for (int d = 0; d < 4; d++)
// {
// //模板匹配
// cv::matchTemplate(image, tplMat, cv::noArray(), cv::TM_CCOEFF_NORMED);
// }
// }
//});
//计算最佳匹配模板 //计算最佳匹配模板
std::sort(tplMats.begin(), tplMats.end(), std::greater<Track>());
//输出结果
*lpszTplName = (char *)CoTaskMemAlloc(tplMats[0].tplName.size());
if (NULL != lpszTplName)
{
strcpy(*lpszTplName, tplMats[0].tplName.c_str());
}
return FUNC_OK; return FUNC_OK;
} }
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!