Commit 71f29f62 张士柳

1 个父辈 9e0af8f7
...@@ -722,7 +722,13 @@ namespace eyemLib_Sharp ...@@ -722,7 +722,13 @@ namespace eyemLib_Sharp
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, double dMinScore, 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, string ccTplName); 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);
...@@ -904,18 +910,24 @@ namespace eyemLib_Sharp ...@@ -904,18 +910,24 @@ namespace eyemLib_Sharp
//eyemEdgesPixel(ucpImage, 15); //eyemEdgesPixel(ucpImage, 15);
#endregion #endregion
////EyemRect tpRoi = new EyemRect();
////tpRoi.iXs = 1231; tpRoi.iYs = 433;
////tpRoi.iWidth = 41;
////tpRoi.iHeight = 14;
EyemRect tpRoi = new EyemRect(); EyemRect tpRoi = new EyemRect();
tpRoi.iXs = 0; tpRoi.iYs = 0; tpRoi.iXs = 1026; tpRoi.iYs = 513;
tpRoi.iWidth = image.iWidth; tpRoi.iWidth = 82;
tpRoi.iHeight = image.iHeight; tpRoi.iHeight = 60;
//EyemRect tpRoi = new EyemRect();
//tpRoi.iXs = 200; tpRoi.iYs = 200;
//tpRoi.iWidth = image.iWidth - 400;
//tpRoi.iHeight = image.iHeight - 400;
//创建模板匹配模型 //创建模板匹配模型
//flag = eyemCreateTemplateModel(image, tpRoi, "D://批量测试图像2//template.tpl"); double dMinScore = 0.75;
flag = eyemCreateTemplateModel(image, tpRoi, dMinScore, "D://模板文件//template.tpl");
string selectModel = "";
flag = eyemMatchTemplateModel(image, "D:\\模板文件", ref selectModel);
//flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
// //
string pNumObj = ""; string pNumObj = "";
...@@ -924,14 +936,14 @@ namespace eyemLib_Sharp ...@@ -924,14 +936,14 @@ namespace eyemLib_Sharp
//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", ""), "D://批量测试图像模板文件//" + file.Replace(".png", "") + "_tpl.png", 0.75, ref pNumObj, out tpDstImg);
Bitmap bmp = eyemCvtToBitmap(tpDstImg); //Bitmap bmp = eyemCvtToBitmap(tpDstImg);
if (bmp != null) //if (bmp != null)
{ //{
bmp.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file); // bmp.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
} //}
////<解码测试 ////<解码测试
//int ipNum; EyemBarCode* tpResults; //int ipNum; EyemBarCode* tpResults;
...@@ -952,7 +964,6 @@ namespace eyemLib_Sharp ...@@ -952,7 +964,6 @@ namespace eyemLib_Sharp
} }
public static void eyemTestVideoCapture(string fileName) public static void eyemTestVideoCapture(string fileName)
{ {
List<EyemRect3> tpRois = new List<EyemRect3>(); List<EyemRect3> tpRois = new List<EyemRect3>();
...@@ -979,6 +990,13 @@ namespace eyemLib_Sharp ...@@ -979,6 +990,13 @@ namespace eyemLib_Sharp
//信号值,用于后续处理 //信号值,用于后续处理
int[] bitSingle = new int[tpRois.Count]; int[] bitSingle = new int[tpRois.Count];
//测试用
EyemImage tpRefImg, tpNextImg;
eyemImageRead("D:\\x.bmp", -1, out tpRefImg);
eyemImageRead("D:\\y.bmp", -1, out tpNextImg);
int iRets = eyemTrackFeature(tpRefImg, tpNextImg, hGlobal, tpRois.Count, Marshal.UnsafeAddrOfPinnedArrayElement(bitSingle, 0)/* new IntPtr((void*)ipResults)*/);
//类似于实时采集的图像 //类似于实时采集的图像
for (int i = 1; i < ipNum; i++) for (int i = 1; i < ipNum; i++)
{ {
...@@ -1070,6 +1088,12 @@ namespace eyemLib_Sharp ...@@ -1070,6 +1088,12 @@ namespace eyemLib_Sharp
#region EyemImage转换成Bitmap #region EyemImage转换成Bitmap
public static Bitmap eyemCvtToBitmap(EyemImage tpImage) public static Bitmap eyemCvtToBitmap(EyemImage tpImage)
{ {
if (tpImage.vpImage == IntPtr.Zero)
throw new ArgumentNullException("图像不存在");
if (tpImage.iDepth != 0)
throw new ArgumentException("图像必须是8位无符号整型");
PixelFormat format; PixelFormat format;
switch (tpImage.iChannels) switch (tpImage.iChannels)
...@@ -1086,9 +1110,10 @@ namespace eyemLib_Sharp ...@@ -1086,9 +1110,10 @@ namespace eyemLib_Sharp
default: default:
return null; return null;
} }
//所有算法输出结果图均为8位
Bitmap bitmap = new Bitmap(tpImage.iWidth, tpImage.iHeight, tpImage.iWidth * tpImage.iChannels, format, tpImage.vpImage);
Bitmap bitmap = new Bitmap(tpImage.iWidth, tpImage.iHeight, format);
//对于输出灰度图像
if (format == PixelFormat.Format8bppIndexed) if (format == PixelFormat.Format8bppIndexed)
{ {
ColorPalette palette = bitmap.Palette; ColorPalette palette = bitmap.Palette;
...@@ -1099,6 +1124,29 @@ namespace eyemLib_Sharp ...@@ -1099,6 +1124,29 @@ namespace eyemLib_Sharp
bitmap.Palette = palette; bitmap.Palette = palette;
} }
//锁定数据区
BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, tpImage.iWidth, tpImage.iHeight),
ImageLockMode.WriteOnly, format);
int srcStep = tpImage.iWidth * tpImage.iChannels;
int dstStep = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4;
long bytesToCopy = tpImage.iWidth * tpImage.iChannels;
try
{
for (int y = 0; y < tpImage.iHeight; y++)
{
long offsetSrc = (y * srcStep);
long offsetDst = (y * dstStep);
Buffer.MemoryCopy((byte*)(tpImage.vpImage.ToPointer()) + offsetSrc, (byte*)(bd.Scan0.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy);
}
}
finally
{
bitmap.UnlockBits(bd);
}
return bitmap; return bitmap;
} }
#endregion #endregion
......
...@@ -836,7 +836,7 @@ extern "C" { ...@@ -836,7 +836,7 @@ extern "C" {
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, double dMinScore, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCalcTemplateImage(EyemImage tpImage, 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);
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);
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
#pragma region 内部使用的函数 #pragma region 内部使用的函数
/** 计算端点坐标
img 输入图像
*/
static void drawLine(cv::InputOutputArray img, cv::Point pt1, cv::Point pt2, const cv::Scalar& color, int thickness, double tipLength, double trackLength, std::vector<cv::Point> &trackLine) static void drawLine(cv::InputOutputArray img, cv::Point pt1, cv::Point pt2, const cv::Scalar& color, int thickness, double tipLength, double trackLength, std::vector<cv::Point> &trackLine)
{ {
const double angle = atan2((double)pt1.y - pt2.y, (double)pt1.x - pt2.x); const double angle = atan2((double)pt1.y - pt2.y, (double)pt1.x - pt2.x);
...@@ -31,11 +34,19 @@ static void drawLine(cv::InputOutputArray img, cv::Point pt1, cv::Point pt2, con ...@@ -31,11 +34,19 @@ static void drawLine(cv::InputOutputArray img, cv::Point pt1, cv::Point pt2, con
trackLine.push_back(p); trackLine.push_back(p);
} }
/** 判断坐标是否在矩形中
_Rect 输入矩形
pt 输入坐标
*/
static inline bool isInRect(std::vector<cv::Point2f> _Rect, cv::Point pt) static inline bool isInRect(std::vector<cv::Point2f> _Rect, cv::Point pt)
{ {
return cv::pointPolygonTest(_Rect, pt, false) > 0; return cv::pointPolygonTest(_Rect, pt, false) > 0;
} }
/** 计算矩形内坐标
_vRect 输入矩形
vPoints 输出坐标
*/
static void calcRotateRect(std::vector<cv::Point2f> &vRect, std::vector<cv::Point> &vPoints) static void calcRotateRect(std::vector<cv::Point2f> &vRect, std::vector<cv::Point> &vPoints)
{ {
cv::Rect _Rect = cv::RotatedRect(vRect[0], vRect[1], vRect[2]).boundingRect(); cv::Rect _Rect = cv::RotatedRect(vRect[0], vRect[1], vRect[2]).boundingRect();
...@@ -51,6 +62,13 @@ static void calcRotateRect(std::vector<cv::Point2f> &vRect, std::vector<cv::Poin ...@@ -51,6 +62,13 @@ static void calcRotateRect(std::vector<cv::Point2f> &vRect, std::vector<cv::Poin
} }
} }
/** 计算旋转矩形
pt 输入坐标
t 输入角度
length 输入长度
width 输入宽度
pts 输出坐标
*/
static void calcRotateRect(cv::Point2f pt, float t, float length, float width, cv::Point2f *pts) static void calcRotateRect(cv::Point2f pt, float t, float length, float width, cv::Point2f *pts)
{ {
float b = (float)cos(t*PI / 180.)*0.5f; float b = (float)cos(t*PI / 180.)*0.5f;
...@@ -66,6 +84,11 @@ static void calcRotateRect(cv::Point2f pt, float t, float length, float width, c ...@@ -66,6 +84,11 @@ static void calcRotateRect(cv::Point2f pt, float t, float length, float width, c
pts[3].y = (float)(2 * pt.y - pts[1].y); pts[3].y = (float)(2 * pt.y - pts[1].y);
} }
/** 获取旋转后的模板
_tplMat 输入图像
t 输入角度
val 填充内容
*/
static cv::Mat getTplMat(cv::Mat &tplMat, double t, int val) static cv::Mat getTplMat(cv::Mat &tplMat, double t, int val)
{ {
const int tplH = tplMat.rows, tplW = tplMat.cols; const int tplH = tplMat.rows, tplW = tplMat.cols;
...@@ -88,6 +111,12 @@ static cv::Mat getTplMat(cv::Mat &tplMat, double t, int val) ...@@ -88,6 +111,12 @@ static cv::Mat getTplMat(cv::Mat &tplMat, double t, int val)
return tplMatD; return tplMatD;
} }
/** 获取旋转后的图像
trackMat输入图像
t 输入角度
val 填充内容
matx 转换矩阵
*/
static cv::Mat getTrackMat(cv::Mat &trackMat, double t, int val, float *matx) static cv::Mat getTrackMat(cv::Mat &trackMat, double t, int val, float *matx)
{ {
const int tckH = trackMat.rows, tckW = trackMat.cols; const int tckH = trackMat.rows, tckW = trackMat.cols;
...@@ -115,6 +144,7 @@ static cv::Mat getTrackMat(cv::Mat &trackMat, double t, int val, float *matx) ...@@ -115,6 +144,7 @@ static cv::Mat getTrackMat(cv::Mat &trackMat, double t, int val, float *matx)
return tplMatD; return tplMatD;
} }
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())
{ {
//图像尺寸 //图像尺寸
...@@ -194,6 +224,46 @@ static bool findTrackModel(cv::Mat& image, cv::Mat &tplMat, double t, double tra ...@@ -194,6 +224,46 @@ static bool findTrackModel(cv::Mat& image, cv::Mat &tplMat, double t, double tra
return false; return false;
} }
static void getFiles(std::string filePath, std::vector<std::string>& fileNames)
{
//文件句柄
intptr_t hFile = 0;
//文件信息
struct _finddata_t fileinfo;
std::string p;
if ((hFile = _findfirst(p.assign(filePath).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
//如果是目录,迭代之,如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR)) {
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
getFiles(p.assign(filePath).append("\\").append(fileinfo.name), fileNames);
}
else {
fileNames.push_back(p.assign(filePath).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
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;
}
static int Otsu(int hist[]) static int Otsu(int hist[])
{ {
// Otsu's threshold algorithm // Otsu's threshold algorithm
...@@ -431,14 +501,6 @@ static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize) ...@@ -431,14 +501,6 @@ static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize)
return partSize >= 20; return partSize >= 20;
} }
void sumTest()
{
int a = 0;
for (int i = 0; i < 100000000; i++)
a++;
}
#pragma endregion #pragma endregion
int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg) int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg)
...@@ -2960,9 +3022,9 @@ int eyemCountObjectE(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj, ...@@ -2960,9 +3022,9 @@ int eyemCountObjectE(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj,
cv::Mat src8U; cv::Mat src8U;
//环鸿 //环鸿
//src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone(); src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone();
//其他设备 //其他设备
src = src(cv::Range(10, src.cols - 10), cv::Range(10, src.rows - 10)).clone(); //src = src(cv::Range(10, src.cols - 10), cv::Range(10, src.rows - 10)).clone();
//image size //image size
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
...@@ -3953,15 +4015,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -3953,15 +4015,6 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
int tplWidth, tplHeight; int tplWidth, tplHeight;
tplWidth = tplMat.cols, tplHeight = tplMat.rows; tplWidth = tplMat.cols, tplHeight = tplMat.rows;
// double begin0 = (double)cv::getTickCount();
// //并行计算测试用
////#pragma omp parallel for
// for (int i = 0; i < 100; i++)
// {
// sumTest();
// }
// std::cout << "总体耗时:" << 1000 * (static_cast<double>(cv::getTickCount()) - begin0) / cv::getTickFrequency() << std::endl;
//去除局部量斑影响(默认亮斑尺寸不会大于15个像素) //去除局部量斑影响(默认亮斑尺寸不会大于15个像素)
cv::Mat srcTmp; cv::Mat srcTmp;
cv::morphologyEx(src, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15))); cv::morphologyEx(src, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
...@@ -4667,7 +4720,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons ...@@ -4667,7 +4720,7 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, const char *fileName, cons
return FUNC_OK; return FUNC_OK;
} }
int eyemCalcTemplateImage(EyemImage tpImage, EyemImage *tpDstImg) int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
{ {
cv::Mat image = 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);
...@@ -4675,9 +4728,64 @@ int eyemCalcTemplateImage(EyemImage tpImage, EyemImage *tpDstImg) ...@@ -4675,9 +4728,64 @@ int eyemCalcTemplateImage(EyemImage tpImage, EyemImage *tpDstImg)
if (image.empty()) if (image.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
cv::Mat srcPrev; //转单通道图像
if (image.channels() != 1)
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
//范围
image = image(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight));
//图像尺寸
int X = image.cols, Y = image.rows;
//去除局部量斑影响(默认亮斑尺寸不会大于15个像素)
cv::Mat srcTmp;
cv::morphologyEx(image, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
//图像增强
double min, max;
cv::minMaxLoc(srcTmp, &min, &max);
image.convertTo(image, CV_64FC1);
image -= min;
image /= (max - min);
image *= 65535;
image.convertTo(image, CV_16UC1);
//转8位灰度图
cv::Mat src8U;
image.convertTo(src8U, CV_8UC1, 1 / 255.);
//设定bin数目
const int histSize = 17;
//设定取值范围
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 * (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)
{
src8U.ptr<uint8_t>(y)[x] = backThresh;
}
}
}
});
//预处理 //预处理
cv::Mat srcPrev;
cv::bitwise_not(src8U, srcPrev);
///<输出计数结果标记图像 ///<输出计数结果标记图像
{ {
...@@ -4705,29 +4813,29 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, ...@@ -4705,29 +4813,29 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone(); (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) + "," \
+ std::to_string(tpRoi.iWidth) + "," + std::to_string(tpRoi.iHeight) + "," + std::to_string(dMinScore); + std::to_string(tpRoi.iWidth) + "," + std::to_string(tpRoi.iHeight) + "," + std::to_string(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 + (int)hint.size()]; unsigned char *_Dst = new unsigned char[_Size];
//拷贝图像 //拷贝图像
memcpy(_Dst, tplMat.data, _Size); memcpy(_Dst, tplMat.data, _Size);
//拷贝信息
memcpy(_Dst + _Size, hint.c_str(), (int)hint.size());
//写入本地 //写入本地
std::ofstream fileStream(ccTplName, std::ios::binary); std::ofstream outFile(ccTplName, std::ios::binary);
fileStream.write(reinterpret_cast<const char *>(_Dst), _Size + (int)hint.size());
fileStream.close(); //写入图像
outFile.write(reinterpret_cast<const char *>(tplMat.data), _Size);
//测试用 //写入信息
outFile << std::endl;
outFile.write(hint.c_str(), hint.size());
//关闭流
outFile.close();
//释放资源 //释放资源
delete _Dst; delete _Dst;
...@@ -4736,30 +4844,6 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore, ...@@ -4736,30 +4844,6 @@ int eyemCreateTemplateModel(EyemImage tpImage, EyemRect tpRoi, double dMinScore,
return FUNC_OK; return FUNC_OK;
} }
static void getFiles(std::string filePath, std::vector<std::string>& fileNames)
{
//文件句柄
intptr_t hFile = 0;
//文件信息
struct _finddata_t fileinfo;
std::string p;
if ((hFile = _findfirst(p.assign(filePath).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
//如果是目录,迭代之,如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR)) {
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
getFiles(p.assign(filePath).append("\\").append(fileinfo.name), fileNames);
}
else {
fileNames.push_back(p.assign(filePath).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lpszTplName) int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lpszTplName)
{ {
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();
...@@ -4770,35 +4854,67 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps ...@@ -4770,35 +4854,67 @@ int eyemMatchTemplateModel(EyemImage tpImage, const char *ccTplNames, LPSTR *lps
const float icvDirections[4] = { 0 , 90 , 180 , -90 }; const float icvDirections[4] = { 0 , 90 , 180 , -90 };
struct Track {
double dMatchDeg;
cv::Point Pos;
cv::Mat tplMat;
Track() {};
Track(double dMatchDeg, cv::Point Pos, cv::Mat tplMat) :dMatchDeg(dMatchDeg), Pos(Pos), tplMat(tplMat) {};
};
//获取文件路径 //获取文件路径
std::vector<std::string> fileNames; std::vector<std::string> fileNames;
getFiles(std::string(ccTplNames), fileNames); getFiles(std::string(ccTplNames), fileNames);
//载入所有模板 //载入所有模板
std::vector<cv::Mat> tplMats; std::vector<Track> tckMats;
for (int i = 0; i < (int)fileNames.size(); i++) for (int i = 0; i < (int)fileNames.size(); i++)
{ {
cv::Mat tplMat; cv::Mat tckMat;
// //读取测试用
// std::ifstream inFile(fileNames[i], std::ios::in | std::ios::binary);
//
tplMats.push_back(tplMat); std::string line;
} while (std::getline(inFile, line));
inFile.close();
//遍历所有模板 //获取文件信息
cv::parallel_for_(cv::Range(0, tplMats.size()), [&](const cv::Range& range)->void { std::vector<std::string> hints;
for (int tpl = range.start; tpl < range.end; tpl++) split(line, ",", hints);
int X = std::atoi(hints[2].c_str()), Y = std::atoi(hints[3].c_str());
double dMatchDeg = std::atof(hints[4].c_str()); cv::Point pt(std::atoi(hints[0].c_str()), std::atoi(hints[1].c_str()));
//读取文件
FILE *fp = fopen(fileNames[i].c_str(), "rb+");
if (NULL != fp)
{ {
cv::Mat tplMat = tplMats[tpl]; tckMat = cv::Mat(Y, X, CV_8UC1);
for (int d = 0; d < 4; d++) fread(tckMat.data, sizeof(uint8_t), X*Y, fp);
{
//模板匹配
cv::matchTemplate(image, tplMat, cv::noArray(), cv::TM_CCOEFF_NORMED);
}
} }
}); else
return FUNC_IMAGE_NOT_EXIST;
tckMats.push_back(Track(dMatchDeg, pt, tckMat));
}
////遍历所有模板
//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);
// }
// }
//});
//计算最佳匹配模板 //计算最佳匹配模板
...@@ -4817,9 +4933,13 @@ int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, ...@@ -4817,9 +4933,13 @@ int eyemTrackFeature(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois,
if (refImg.empty() | nextImg.empty()) if (refImg.empty() | nextImg.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
cv::cvtColor(refImg, refImg, cv::COLOR_BGR2GRAY); if (refImg.channels() != 1) {
cv::cvtColor(refImg, refImg, cv::COLOR_BGR2GRAY);
}
cv::cvtColor(nextImg, nextImg, cv::COLOR_BGR2GRAY); if (nextImg.channels() != 1) {
cv::cvtColor(nextImg, nextImg, cv::COLOR_BGR2GRAY);
}
cv::Mat dst; cv::Mat dst;
cv::absdiff(nextImg, refImg, dst); cv::absdiff(nextImg, refImg, dst);
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!