Commit 17d157dc 张士柳

1 个父辈 30d336d2
...@@ -723,6 +723,17 @@ namespace eyemLib_Sharp ...@@ -723,6 +723,17 @@ namespace eyemLib_Sharp
private static extern int eyemBinThreshold(EyemImage tpSrcImg, int iLightDark, double dThresh, double dMaxVal, out EyemImage tpDstImg); private static extern int eyemBinThreshold(EyemImage tpSrcImg, int iLightDark, double dThresh, double dMaxVal, out EyemImage tpDstImg);
/// <summary> /// <summary>
/// 彩色图像分割
/// </summary>
/// <param name="tpImage">图像</param>
/// <param name="ipRangeL">下限[0,0,0]</param>
/// <param name="ipRangeU">上限[255,255,255]</param>
/// <param name="tpDstImg">结果</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemBinThresholdC(EyemImage tpImage, [MarshalAs(UnmanagedType.LPArray)]int[] ipRangeL, [MarshalAs(UnmanagedType.LPArray)]int[] ipRangeU, out EyemImage tpDstImg);
/// <summary>
/// 局部自适应二值化 /// 局部自适应二值化
/// </summary> /// </summary>
/// <param name="tpSrcImg">图像</param> /// <param name="tpSrcImg">图像</param>
...@@ -822,7 +833,7 @@ namespace eyemLib_Sharp ...@@ -822,7 +833,7 @@ namespace eyemLib_Sharp
/// <param name="tpDstImg">结果图像</param> /// <param name="tpDstImg">结果图像</param>
/// <returns></returns> /// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCvtColor(EyemImage tpImage, ColorConversionCodes iCCodes, ref EyemImage tpDstImg); private static extern int eyemCvtImageColor(EyemImage tpImage, ColorConversionCodes iCCodes, ref EyemImage tpDstImg);
/// <summary> /// <summary>
/// 图像数据格式转换 /// 图像数据格式转换
/// </summary> /// </summary>
...@@ -833,7 +844,7 @@ namespace eyemLib_Sharp ...@@ -833,7 +844,7 @@ namespace eyemLib_Sharp
/// <param name="tpDstImg">结果图像</param> /// <param name="tpDstImg">结果图像</param>
/// <returns></returns> /// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCvtType(EyemImage tpImage, string ccSubType, double alpha, double beta, ref EyemImage tpDstImg); private static extern int eyemCvtImageType(EyemImage tpImage, string ccSubType, double alpha, double beta, ref EyemImage tpDstImg);
/// <summary> /// <summary>
/// 图像除运算 /// 图像除运算
/// </summary> /// </summary>
...@@ -843,10 +854,16 @@ namespace eyemLib_Sharp ...@@ -843,10 +854,16 @@ namespace eyemLib_Sharp
/// <returns></returns> /// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMatDiv(EyemImage tpImage1, EyemImage tpImage2, ref EyemImage tpDstImg); private static extern int eyemMatDiv(EyemImage tpImage1, EyemImage tpImage2, ref EyemImage tpDstImg);
//图像归一化
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemNormalize(ref EyemImage tpImage);
//通道分离
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemDecompose(EyemImage tpImage, out EyemImage tpDstImgR, out EyemImage tpDstImgG, out EyemImage tpDstImgB);
#endregion #endregion
#region 一维边缘测量 #region 一维边缘测量
//边缘测量 //边缘测量
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, string strSubType, int iTransition, double dSigma, double dAmpThresh, out MeasureHandle hObject); private static extern int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, string strSubType, int iTransition, double dSigma, double dAmpThresh, out MeasureHandle hObject);
...@@ -854,22 +871,40 @@ namespace eyemLib_Sharp ...@@ -854,22 +871,40 @@ namespace eyemLib_Sharp
//边缘查找 //边缘查找
private static extern int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, double dSigma, double dAmpThresh, out MeasureHandle hObject); private static extern int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, double dSigma, double dAmpThresh, out MeasureHandle hObject);
/// <summary> /// <summary>
/// 寻找边缘 /// 边缘查找工具
/// </summary> /// </summary>
/// <param name="tpImage">图像</param> /// <param name="tpImage">图像</param>
/// <param name="tpLineSt">卡尺起点</param> /// <param name="tpLineSt">卡尺起点</param>
/// <param name="tpLineEd">卡尺终点</param> /// <param name="tpLineEd">卡尺终点</param>
/// <param name="iWhRoi">卡尺宽度</param> /// <param name="iCapLength">卡尺长度</param>
/// <param name="iCapWidth">卡尺宽度</param>
/// <param name="nCalipers">卡尺数量</param> /// <param name="nCalipers">卡尺数量</param>
/// <param name="iSearchDirec">搜索方向(起点到终点方向的垂直方向)</param> /// <param name="nFilterSize">滤波尺寸(默认为2,如果边缘较窄可以设置为1,建议范围[1,5])</param>
/// <param name="dAmpThreshold">最小边缘幅度</param> /// <param name="iSearchDirec">搜索方向</param>
/// <param name="ccTransition">灰度值过渡的类型以确定边缘'all', 'negative', 'positive'</param> /// <param name="dAmpThreshold">边缘阈值</param>
/// <param name="ccTransition">提取模式("all","positive","negative")</param>
/// <param name="hObject">结果</param> /// <param name="hObject">结果</param>
/// <returns></returns> /// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int nCalipers, int iSearchDirec, double dAmpThreshold, string ccTransition, out MeasureHandle hObject); private static extern int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, int iSearchDirec, double dAmpThreshold, string ccTransition, out MeasureHandle hObject);
/// <summary>
/// 圆形边缘查找工具
/// </summary>
/// <param name="tpImage">图像</param>
/// <param name="tpPoint">位置坐标</param>
/// <param name="iRadius">半径</param>
/// <param name="iCapLength">卡尺长度</param>
/// <param name="iCapWidth">卡尺宽度</param>
/// <param name="nCalipers">卡尺数量</param>
/// <param name="nFilterSize">滤波尺寸</param>
/// <param name="iSearchDirec">交换搜索方向</param>
/// <param name="dAmpThreshold">边缘阈值</param>
/// <param name="ccTransition">提取模式("all","positive","negative")</param>
/// <param name="hObject">结果</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemSkeleton(EyemImage tpImage); public static extern int eyemEdge1dFindCircle(EyemImage tpImage, EyemOcsDXY tpPoint, int iRadius, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, int iSearchDirec, double dAmpThreshold, string ccTransition, out MeasureHandle hObject);
//边缘 //边缘
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemEdgesPixel(EyemImage tpImage, double dThreshold, out IntPtr hObject, out int ipNum, out EyemOcsDXY* hResults); private static extern int eyemEdgesPixel(EyemImage tpImage, double dThreshold, out IntPtr hObject, out int ipNum, out EyemOcsDXY* hResults);
...@@ -1137,6 +1172,9 @@ namespace eyemLib_Sharp ...@@ -1137,6 +1172,9 @@ namespace eyemLib_Sharp
//异型器件(新版本模板匹配) //异型器件(新版本模板匹配)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, string fileName, string ccTplName, IntPtr hModelID, [MarshalAs(UnmanagedType.LPArray)]int[] ipReelNum, out EyemImage tpDstImg); private static extern int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, string fileName, string ccTplName, IntPtr hModelID, [MarshalAs(UnmanagedType.LPArray)]int[] ipReelNum, out EyemImage tpDstImg);
//匹配元件
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, 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);
...@@ -1250,7 +1288,6 @@ namespace eyemLib_Sharp ...@@ -1250,7 +1288,6 @@ namespace eyemLib_Sharp
EyemImage image; EyemImage image;
EyemImage tpDstImg = new EyemImage(); EyemImage tpDstImg = new EyemImage();
EyemOcsFXYR tpCircle = new EyemOcsFXYR(); EyemOcsFXYR tpCircle = new EyemOcsFXYR();
//int flag = eyemImageReadRaw(fileName, 3072, 3072, 2, out ucpImage);
int flag = eyemImageRead(fileName, -1, out image); int flag = eyemImageRead(fileName, -1, out image);
if (flag != 0) if (flag != 0)
{ {
...@@ -1281,35 +1318,55 @@ namespace eyemLib_Sharp ...@@ -1281,35 +1318,55 @@ namespace eyemLib_Sharp
//flag = eyemLibImpl(image, out tpDstImg); //flag = eyemLibImpl(image, out tpDstImg);
//flag = eyemNormalize(ref image);
//EyemImage image1 = new EyemImage(); EyemImage image2 = new EyemImage(); EyemImage image3 = new EyemImage();
//eyemDecompose(image, out image1, out image2, out image3);
//flag = eyemBinThresholdC(image, new int[] { 55, 0, 0 }, new int[] { 135, 225, 225 }, out tpDstImg);
//sw.Restart();
//flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg, true);
flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg); //Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//eyemImageFree(ref tpDstImg);
//sw.Stop();
//Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString());
//return;
#region Test Blob
sw.Restart();
int ipNum;
BlobHandle hObject;
EyemBinBlob* tpResults;
eyemBinBlob(image, out hObject, 100, out tpResults, out ipNum, out tpDstImg);
sw.Stop();
for (int i = 0; i < ipNum; i++)
{
Console.WriteLine(tpResults[i].iArea);
}
Bitmap bitmap = eyemCvtToBitmap(tpDstImg); Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null) if (bitmap != null)
{ {
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file); bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
} }
eyemImageFree(ref tpDstImg);
hObject.Dispose();
eyemImageFree(ref tpDstImg);
eyemImageFree(ref image);
Console.WriteLine("时间-:" + sw.ElapsedMilliseconds.ToString());
return; return;
#region Test Blob
//int ipNum;
//BlobHandle hObject;
//EyemBinBlob* eyemBlob;
//eyemBinBlob(image, out hObject, 100, out eyemBlob, out ipNum, out tpDstImg);
//for (int i = 0; i < ipNum; i++)
//{
// //tpResult.Add(eyemBlob[i]);
//}
//hObject.Dispose();
#endregion #endregion
#region Test 1DEdge #region Test 1DEdge
//EyemOcsDXY tpLineSt = new EyemOcsDXY(); //EyemOcsDXY tpLineSt = new EyemOcsDXY();
//tpLineSt.dX = 386.5; //tpLineSt.dX = 62;
//tpLineSt.dY = 136.5; //tpLineSt.dY = 62;
//EyemOcsDXY tpLineEd = new EyemOcsDXY(); //EyemOcsDXY tpLineEd = new EyemOcsDXY();
//tpLineEd.dX = 323.5; //tpLineEd.dX = 323.5;
//tpLineEd.dY = 40.5; //tpLineEd.dY = 40.5;
...@@ -1318,11 +1375,11 @@ namespace eyemLib_Sharp ...@@ -1318,11 +1375,11 @@ namespace eyemLib_Sharp
////eyemEdge1dGenMeasureRect(image, tpLineSt, tpLineEd, 10, "all", 0, 0.9, 30, out hObject); ////eyemEdge1dGenMeasureRect(image, tpLineSt, tpLineEd, 10, "all", 0, 0.9, 30, out hObject);
////eyemEdge1dGenPosRect(image, tpLineSt, tpLineEd, 50, 0, 0.9, 30, out hObject); ////eyemEdge1dGenPosRect(image, tpLineSt, tpLineEd, 50, 0, 0.9, 30, out hObject);
//sw.Restart(); //sw.Restart();
//eyemEdge1dFindLine(image, tpLineSt, tpLineEd, 15, 3500, -1, 15, "all", out hObject); ////eyemEdge1dFindLine(image, tpLineSt, tpLineEd, 15, 5, 10, 2, 1, 35, "all", out hObject);
////eyemEdge1dFindCircle(image, tpLineSt, 21, 12, 3, 10, 1, -1, 35, "negative", out hObject);
//sw.Stop(); //sw.Stop();
//Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString()); //Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString());
//return; //return;
//hObject.Dispose();
#endregion #endregion
#region Test Matrix #region Test Matrix
...@@ -1508,16 +1565,26 @@ namespace eyemLib_Sharp ...@@ -1508,16 +1565,26 @@ namespace eyemLib_Sharp
//eyemNNDetector(image, out ipNum, ref container); //eyemNNDetector(image, out ipNum, ref container);
#endregion #endregion
EyemRect tpRoi = new EyemRect(); EyemRect tpRoi = new EyemRect();
tpRoi.iXs = 200; tpRoi.iYs = 150; tpRoi.iXs = 250; tpRoi.iYs = 250;
tpRoi.iWidth = image.iWidth - 400; tpRoi.iWidth = image.iWidth - 500;
tpRoi.iHeight = image.iHeight - 300; tpRoi.iHeight = image.iHeight - 500;
//flag = eyemMulFuncTool(image, tpRoi, "__func1", 65, 75, ref tpCircle, out tpDstImg); //flag = eyemMulFuncTool(image, tpRoi, "__func1", 65, 75, ref tpCircle, out tpDstImg);
int[] ipReelNum = new int[4]; int[] ipReelNum = new int[4];
//flag = eyemAchvMatchMat(image, tpRoi, out tpDstImg);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//eyemImageFree(ref tpDstImg);
//eyemImageFree(ref image);
//return;
//获取用于制作模板的图像 //获取用于制作模板的图像
//flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg); //flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
......
...@@ -1243,6 +1243,53 @@ int eyemBinAutoThreshold(EyemImage tpImage, double dSigma, int iLightDark, int b ...@@ -1243,6 +1243,53 @@ int eyemBinAutoThreshold(EyemImage tpImage, double dSigma, int iLightDark, int b
return FUNC_OK; return FUNC_OK;
} }
int eyemBinThresholdC(EyemImage tpImage, int ipRangeL[3], int ipRangeU[3], EyemImage *tpDstImg)
{
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (image.empty())
return FUNC_IMAGE_NOT_EXIST;
int incn = image.channels();
if (incn > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2BGR);
}
else if (incn == 1) {
cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
}
//转hsv空间
cv::Mat imghsv;
cv::cvtColor(image, imghsv, cv::COLOR_BGR2HSV);
//分割
cv::Mat mask;
cv::inRange(imghsv, cv::Scalar(ipRangeL[0], ipRangeL[1], ipRangeL[2]), cv::Scalar(ipRangeU[0], ipRangeU[1], ipRangeU[2]), mask);
//输出结果图像
if (NULL != tpDstImg->vpImage) {
tpDstImg->iWidth = tpDstImg->iHeight = tpDstImg->iDepth = tpDstImg->iChannels = 0;
//释放
free(tpDstImg->vpImage);
tpDstImg->vpImage = NULL;
}
tpDstImg->iWidth = mask.cols; tpDstImg->iHeight = mask.rows; tpDstImg->iDepth = mask.depth(); tpDstImg->iChannels = mask.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, mask.data, _Size);
return FUNC_OK;
}
int eyemBinDilation(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg) int eyemBinDilation(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg)
{ {
...@@ -1267,404 +1314,202 @@ int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDst ...@@ -1267,404 +1314,202 @@ int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDst
int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg) int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg)
{ {
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();
if (image.empty()) { if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
//必须是二值图像 //判断图像
if (image.channels() != 1) if (image.type() != CV_8UC1 || image.channels() != 1) {
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY); return FUNC_CANNOT_CALC;
}
const int X = image.cols, Y = image.rows;
cv::Mat lbImage;
lbImage = cv::Mat::zeros(image.rows, image.cols, CV_32FC1);
unsigned int numPixels = 0;
CvBlobs blobs;
CvLabel label = 0;
cvReleaseBlobs(blobs);
CvLabel lastLabel = 0;
CvBlob *lastBlob = NULL;
for (int y = 0; y < Y; y++)
{
for (int x = 0; x < X; x++)
{
if (image.ptr<uint8_t>(y)[x])
{
bool labeled = lbImage.ptr<int32_t>(y)[x];
if ((!lbImage.ptr<int32_t>(y)[x]) && ((y == 0) || (!image.ptr<uint8_t>(y - 1)[x])))
{
labeled = true;
// Label contour.
label++;
CV_Assert(label != UINT_MAX);
lbImage.ptr<int32_t>(y)[x] = label;
numPixels++;
if (y > 0)
lbImage.ptr<int32_t>(y - 1)[x] = UINT_MAX;
CvBlob *blob = new CvBlob;
blob->label = label;
blob->area = 1;
blob->minx = x; blob->maxx = x;
blob->miny = y; blob->maxy = y;
blob->m10 = x; blob->m01 = y;
blob->m11 = x*y;
blob->m20 = x*x; blob->m02 = y*y;
blob->internalContours.clear();
blobs.insert(CvLabelBlob(label, blob));
lastLabel = label;
lastBlob = blob;
blob->contour.startingPoint = cv::Point(x, y);
unsigned char direction = 1;
unsigned int xx = x;
unsigned int yy = y;
bool contourEnd = false;
do
{
for (unsigned int numAttempts = 0; numAttempts < 3; numAttempts++)
{
bool found = false;
for (unsigned char i = 0; i < 3; i++)
{
int nx = xx + movesE[direction][i][0];
int ny = yy + movesE[direction][i][1];
if ((nx < X) && (nx >= 0) && (ny < Y) && (ny >= 0))
{
if (image.ptr<uint8_t>(ny)[nx])
{
found = true;
blob->contour.chainCode.push_back(movesE[direction][i][3]);
xx = nx;
yy = ny;
direction = movesE[direction][i][2];
break;
}
else
{
lbImage.ptr<int32_t>(ny)[nx] = UINT_MAX;
}
}
}
if (!found)
direction = (direction + 1) % 4;
else
{
if (lbImage.ptr<int32_t>(yy)[xx] != label)
{
lbImage.ptr<int32_t>(yy)[xx] = label;
numPixels++;
if (xx < blob->minx) blob->minx = xx;
else if (xx > blob->maxx) blob->maxx = xx;
if (yy < blob->miny) blob->miny = yy;
else if (yy > blob->maxy) blob->maxy = yy;
blob->area++;
blob->m10 += xx; blob->m01 += yy;
blob->m11 += xx*yy;
blob->m20 += xx*xx; blob->m02 += yy*yy;
}
break;
}
if (contourEnd = ((xx == x) && (yy == y) && (direction == 1)))
break;
}
} while (!contourEnd);
} cv::threshold(image, image, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);
if ((y + 1 < Y) && (!image.ptr<uint8_t>(y + 1)[x]) && (!lbImage.ptr<int32_t>(y + 1)[x])) //显示图像
{ cv::Mat showMat;
labeled = true; cv::cvtColor(image, showMat, cv::COLOR_GRAY2RGB);
//图像尺寸
// Label internal contour const int X = image.cols, Y = image.rows;
CvLabel l;
CvBlob *blob = NULL;
if (!lbImage.ptr<int32_t>(y)[x])
{
l = lbImage.ptr<int32_t>(y)[x - 1];
lbImage.ptr<int32_t>(y)[x] = l;
numPixels++;
if (l == lastLabel)
blob = lastBlob;
else
{
blob = blobs.find(l)->second;
lastLabel = l;
lastBlob = blob;
}
blob->area++;
blob->m10 += x; blob->m01 += y;
blob->m11 += x*y;
blob->m20 += x*x; blob->m02 += y*y;
}
else
{
l = lbImage.ptr<int32_t>(y)[x];
if (l == lastLabel)
blob = lastBlob;
else
{
blob = blobs.find(l)->second;
lastLabel = l;
lastBlob = blob;
}
}
// XXX This is not necessary (I believe). I only do this for consistency.
lbImage.ptr<int32_t>(y + 1)[x] = UINT_MAX;
CvContourChainCode *contour = new CvContourChainCode;
contour->startingPoint = cv::Point(x, y);
unsigned char direction = 3;
unsigned int xx = x;
unsigned int yy = y;
do
{
for (unsigned int numAttempts = 0; numAttempts < 3; numAttempts++)
{
bool found = false;
for (unsigned char i = 0; i < 3; i++)
{
int nx = xx + movesI[direction][i][0];
int ny = yy + movesI[direction][i][1];
if (image.ptr<uint8_t>(ny)[nx])
{
found = true;
contour->chainCode.push_back(movesI[direction][i][3]);
xx = nx;
yy = ny;
direction = movesI[direction][i][2];
break;
}
else
{
lbImage.ptr<int32_t>(ny)[nx] = UINT_MAX;
}
}
if (!found)
direction = (direction + 1) % 4;
else
{
if (!lbImage.ptr<int32_t>(yy)[xx])
{
lbImage.ptr<int32_t>(yy)[xx] = l;
numPixels++;
blob->area++;
blob->m10 += xx; blob->m01 += yy;
blob->m11 += xx*yy;
blob->m20 += xx*xx; blob->m02 += yy*yy;
}
break;
}
}
} while (!(xx == x && yy == y));
blob->internalContours.push_back(contour);
}
if (!labeled) //斑点大小限制
{ bool filterByArea = true;
// Internal pixel int minArea = 25, maxArea = 25000;
CvLabel l = lbImage.ptr<int32_t>(y)[x - 1];
//斑点圆度限制
lbImage.ptr<int32_t>(y)[x] = l; bool filterByCircularity = false;
numPixels++; float minCircularity = 0.8f, maxCircularity = std::numeric_limits<float>::max();
CvBlob *blob = NULL; //斑点的惯性率限制
if (l == lastLabel) bool filterByInertia = false;
blob = lastBlob; float minInertiaRatio = 0.1f, maxInertiaRatio = std::numeric_limits<float>::max();
else
{ //斑点凸度限制
blob = blobs.find(l)->second; bool filterByConvexity = false;
lastLabel = l; float minConvexity = 0.8f, maxConvexity = std::numeric_limits<float>::max();
lastBlob = blob;
} //斑点检测
blob->area++; cv::Mat labels, stats, centroids;
blob->m10 += x; blob->m01 += y; int nccomps = cv::connectedComponentsWithStats(image, labels, stats, centroids);
blob->m11 += x*y;
blob->m20 += x*x; blob->m02 += y*y; std::vector<uchar> colors(nccomps + 1, 0);
} //按面积过滤
if (filterByArea) {
//过滤连通域面积
for (int i = 0; i < nccomps; i++) {
colors[i] = 255;
double dArea = stats.ptr<int>(i)[cv::CC_STAT_AREA];
if (!(dArea >= minArea&&dArea <= maxArea)) {
colors[i] = 0;
} }
} }
} }
EyemBinBlob blob;
std::vector<EyemBinBlob> * eyemBlobs = new std::vector<EyemBinBlob>();
for (CvBlobs::iterator it = blobs.begin(); it != blobs.end(); ++it)
{
(*it).second->centroid = cv::Point2d((*it).second->m10 / (*it).second->area, (*it).second->m01 / (*it).second->area);
(*it).second->u11 = (*it).second->m11 - ((*it).second->m10*(*it).second->m01) / (*it).second->m00;
(*it).second->u20 = (*it).second->m20 - ((*it).second->m10*(*it).second->m10) / (*it).second->m00;
(*it).second->u02 = (*it).second->m02 - ((*it).second->m01*(*it).second->m01) / (*it).second->m00;
double m00_2 = (*it).second->m00 * (*it).second->m00;
(*it).second->n11 = (*it).second->u11 / m00_2;
(*it).second->n20 = (*it).second->u20 / m00_2;
(*it).second->n02 = (*it).second->u02 / m00_2;
(*it).second->p1 = (*it).second->n20 + (*it).second->n02;
double nn = (*it).second->n20 - (*it).second->n02;
(*it).second->p2 = nn*nn + 4.*((*it).second->n11*(*it).second->n11);
blob.iLabel = (*it).second->label;
blob.iArea = (*it).second->area;
blob.dCenterX = (*it).second->centroid.x;
blob.dCenterY = (*it).second->centroid.y;
blob.iXs = (*it).second->minx;
blob.iYs = (*it).second->miny;
blob.iXe = (*it).second->maxx;
blob.iYe = (*it).second->maxy;
blob.iWidth = blob.iXe - blob.iXs;
blob.iHeight = blob.iYe - blob.iYs;
blob.dTheta = .5*atan2(2.*(*it).second->u11, ((*it).second->u20 - (*it).second->u02));
eyemBlobs->push_back(blob);
}
//输出结果
*hObject = reinterpret_cast<IntPtr>(eyemBlobs);
*tpResult = eyemBlobs->data();
*ipNum = (int)eyemBlobs->size();
//释放资源
cvReleaseBlobs(blobs);
return FUNC_OK;
}
int eyemBinBlobRender(EyemImage tpImage, IntPtr hObject, EyemImage *tpDstImg)
{
std::vector<EyemBinBlob> *tpResult = reinterpret_cast<std::vector<EyemBinBlob>*>(hObject);
cv::Mat showMat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
//转彩色图像 //斑点方位
if (showMat.channels() != 3) cv::Mat mOrientation(cv::Size(1, nccomps + 1), CV_64FC1, cv::Scalar(0));
cv::cvtColor(showMat, showMat, cv::COLOR_GRAY2BGR); //根据轮廓属性过滤
std::vector<std::vector<cv::Point>> contours;
int X = tpDstImg->iWidth = tpImage.iWidth, Y = tpDstImg->iHeight = tpImage.iHeight; tpDstImg->iDepth = 0; tpDstImg->iChannels = 3; cv::findContours(image, contours, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
for (auto&contour : contours)
//内存尺寸
int _Size = tpImage.iWidth*tpImage.iHeight * 3;
//输出结果
if (NULL != tpDstImg)
{ {
_Size *= sizeof(uint8_t); int label = labels.at<int>(contour[0]);
tpDstImg->vpImage = (uint8_t *)malloc(_Size); //计算轮廓矩
if (NULL == tpDstImg->vpImage) cv::Moments moms = cv::moments(contour);
return FUNC_NOT_ENOUGH_MEM; //主要方向计算
memset(tpDstImg->vpImage, 0, _Size); cv::Mat pts((int)contour.size(), 2, CV_64FC1);
for (int i = 0; i < pts.rows; i++)
const double alpha = 1.0;
Palete pal;
unsigned int colorCount = 0;
for (std::vector<EyemBinBlob>::iterator it = tpResult->begin(); it != tpResult->end(); ++it)
{ {
CvLabel label = (*it).iLabel; pts.ptr<double>(i)[0] = contour[i].x;
pts.ptr<double>(i)[1] = contour[i].y;
}
double r, g, b; if (pts.rows > 2) {
cv::PCA pca(pts, cv::Mat(), cv::PCA::DATA_AS_ROW);
_HSV2RGB_((double)((colorCount * 77) % 360), .5, 1., r, g, b); cv::Point pt((int)pca.mean.at<double>(0, 0), (int)pca.mean.at<double>(0, 1));
colorCount++; //特征值和特征向量
std::vector<cv::Point2d> eigvec(2);
std::vector<double> eigval(2);
for (int i = 0; i < 2; ++i)
{
eigvec[i] = cv::Point2d(pca.eigenvectors.at<double>(i, 0), pca.eigenvectors.at<double>(i, 1));
eigval[i] = pca.eigenvalues.at<double>(i, 0);
}
pal[label] = CV_RGB(r, g, b); mOrientation.ptr<float>(label)[0] = (float)atan2(eigvec[0].y, eigvec[0].x);
} }
for (std::vector<EyemBinBlob>::iterator it = tpResult->begin(); it != tpResult->end(); ++it) //按圆度过滤
{ if (filterByCircularity) {
double x1, y1, x2, y2; double perimeter = cv::arcLength(contour, true);
double lengthLine = MAX((*it).iXe - (*it).iXs, (*it).iYe - (*it).iYs) / 2.; double ratio = 4 * CV_PI * moms.m00 / (perimeter * perimeter);
if (ratio < minCircularity || ratio >= maxCircularity)
x1 = (*it).dCenterX - lengthLine*cos((*it).dTheta); colors[label] = 0;
y1 = (*it).dCenterY - lengthLine*sin((*it).dTheta); }
x2 = (*it).dCenterX + lengthLine*cos((*it).dTheta); //按惯性率过滤
y2 = (*it).dCenterY + lengthLine*sin((*it).dTheta); if (filterByInertia) {
cv::line(showMat, cv::Point(int(x1), int(y1)), cv::Point(int(x2), int(y2)), cv::Scalar(0, 255, 0)); double denominator = std::sqrt(std::pow(2 * moms.mu11, 2) + std::pow(moms.mu20 - moms.mu02, 2));
const double eps = 1e-2;
cv::rectangle(showMat, cv::Point((*it).iXs, (*it).iYs), cv::Point((*it).iXe, (*it).iYe), cv::Scalar(0, 0, 255)); double ratio;
if (denominator > eps) {
cv::line(showMat, cv::Point(int((*it).dCenterX) - 3, int((*it).dCenterY)), cv::Point(int((*it).dCenterX) + 3, int((*it).dCenterY)), cv::Scalar(255, 0, 0)); double cosmin = (moms.mu20 - moms.mu02) / denominator;
cv::line(showMat, cv::Point(int((*it).dCenterX), int((*it).dCenterY) - 3), cv::Point(int((*it).dCenterX), int((*it).dCenterY) + 3), cv::Scalar(255, 0, 0)); double sinmin = 2 * moms.mu11 / denominator;
double cosmax = -cosmin;
double sinmax = -sinmin;
double imin = 0.5 * (moms.mu20 + moms.mu02) - 0.5 * (moms.mu20 - moms.mu02) * cosmin - moms.mu11 * sinmin;
double imax = 0.5 * (moms.mu20 + moms.mu02) - 0.5 * (moms.mu20 - moms.mu02) * cosmax - moms.mu11 * sinmax;
ratio = imin / imax;
}
else {
ratio = 1;
}
if (ratio < minInertiaRatio || ratio >= maxInertiaRatio)
colors[label] = 0;
}
//按凸度过滤
if (filterByConvexity) {
std::vector <cv::Point> hull;
cv::convexHull(contour, hull);
double area = cv::contourArea(contour);
double hullArea = contourArea(hull);
if (fabs(hullArea) < DBL_EPSILON)
colors[label] = 0;
double ratio = area / hullArea;
if (ratio < minConvexity || ratio >= maxConvexity)
colors[label] = 0;
} }
//拷贝数据
memcpy(tpDstImg->vpImage, showMat.data, _Size);
} }
cv::Mat showMat2(tpDstImg->iHeight, tpDstImg->iWidth, MAKETYPE(tpDstImg->iDepth, tpDstImg->iChannels), tpDstImg->vpImage); Palete pal;
unsigned int colorCount = 0;
return FUNC_OK; for (int i = 1; i < nccomps; i++)
}
int eyemBinBlobFilterByArea(IntPtr hObject, int iMinArea, int iMaxArea)
{
std::vector<EyemBinBlob> *tpResult = reinterpret_cast<std::vector<EyemBinBlob>*>(hObject);
std::vector<EyemBinBlob>::iterator it = tpResult->begin();
while (it != tpResult->end())
{ {
if ((*it).iArea < iMinArea || (*it).iArea > iMaxArea) CvLabel _label = i;
{ double r, g, b;
it = tpResult->erase(it); _HSV2RGB_((double)((colorCount * 77) % 360), .5, 1., r, g, b);
} colorCount++;
else pal[_label] = CV_RGB(r, g, b);
++it;
} }
return FUNC_OK; //过滤
} cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
for (int y = range.start; y < range.end; y++) {
uint8_t *ptrRow = image.ptr<uint8_t>(y);
for (int x = 0; x < X; x++) {
int label = labels.ptr<int>(y)[x];
CV_Assert(0 <= label && label <= nccomps);
ptrRow[x] = colors[label];
if (colors[label]) {
showMat.ptr<cv::Vec3b>(y)[x] = cv::Vec3b((uchar)pal[label].val[0], (uchar)pal[label].val[1], (uchar)pal[label].val[2]);
}
}
}
});
int eyemBinBlobFilterByLabel(IntPtr hObject, int iLabel) EyemBinBlob blob;
{ std::vector<EyemBinBlob> * tpResults = new std::vector<EyemBinBlob>();
std::vector<EyemBinBlob> *tpResult = reinterpret_cast<std::vector<EyemBinBlob>*>(hObject); for (int i = 1; i < nccomps; i++) {
if (colors[i]) {
/*cv::rectangle(showMat, 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]), cv::Scalar(0, 0, 255));*/
cv::drawMarker(showMat, cv::Point((int)centroids.ptr<double>(i)[0], (int)centroids.ptr<double>(i)[1]), cv::Scalar(255, 0, 0), cv::MARKER_CROSS, 6);
std::vector<EyemBinBlob>::iterator it = tpResult->begin(); double x1, y1, x2, y2;
double lengthLine = MAX(stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]) / 2.;
while (it != tpResult->end()) x1 = centroids.ptr<double>(i)[0] - lengthLine*cos(mOrientation.ptr<float>(i)[0]);
{ y1 = centroids.ptr<double>(i)[1] - lengthLine*sin(mOrientation.ptr<float>(i)[0]);
if ((*it).iLabel != iLabel) x2 = centroids.ptr<double>(i)[0] + lengthLine*cos(mOrientation.ptr<float>(i)[0]);
{ y2 = centroids.ptr<double>(i)[1] + lengthLine*sin(mOrientation.ptr<float>(i)[0]);
it = tpResult->erase(it); cv::line(showMat, cv::Point(int(x1), int(y1)), cv::Point(int(x2), int(y2)), cv::Scalar(0, 255, 0));
blob.iXs = stats.ptr<int>(i)[cv::CC_STAT_LEFT];
blob.iYs = stats.ptr<int>(i)[cv::CC_STAT_TOP];
blob.iXe = blob.iYs + stats.ptr<int>(i)[cv::CC_STAT_WIDTH];
blob.iYe = blob.iYs + stats.ptr<int>(i)[cv::CC_STAT_HEIGHT];
blob.iWidth = stats.ptr<int>(i)[cv::CC_STAT_WIDTH];
blob.iHeight = stats.ptr<int>(i)[cv::CC_STAT_HEIGHT];
blob.dCenterX = centroids.ptr<double>(i)[0];
blob.dCenterY = centroids.ptr<double>(i)[1];
blob.iArea = stats.ptr<int>(i)[cv::CC_STAT_AREA];
blob.dTheta = mOrientation.ptr<float>(i)[0];
tpResults->push_back(blob);
} }
else
++it;
} }
//<输出结果图像
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);
//输出结果
*ipNum = static_cast<int>(tpResults->size());
*hObject = reinterpret_cast<IntPtr>(tpResults);
*tpResult = tpResults->data();
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -8,96 +8,8 @@ ...@@ -8,96 +8,8 @@
#include "eyemLib.h" #include "eyemLib.h"
// Chain code:
// 7 0 1
// 6 2
// 5 4 3
#define CV_CHAINCODE_UP 0 ///< Up.
#define CV_CHAINCODE_UP_RIGHT 1 ///< Up and right.
#define CV_CHAINCODE_RIGHT 2 ///< Right.
#define CV_CHAINCODE_DOWN_RIGHT 3 ///< Down and right.
#define CV_CHAINCODE_DOWN 4 ///< Down.
#define CV_CHAINCODE_DOWN_LEFT 5 ///< Down and left.
#define CV_CHAINCODE_LEFT 6 ///< Left.
#define CV_CHAINCODE_UP_LEFT 7 ///< Up and left.
const char movesE[4][3][4] = { { { -1, -1, 3, CV_CHAINCODE_UP_LEFT },{ 0, -1, 0, CV_CHAINCODE_UP },{ 1, -1, 0, CV_CHAINCODE_UP_RIGHT } },
{ { 1, -1, 0, CV_CHAINCODE_UP_RIGHT },{ 1, 0, 1, CV_CHAINCODE_RIGHT },{ 1, 1, 1, CV_CHAINCODE_DOWN_RIGHT } },
{ { 1, 1, 1, CV_CHAINCODE_DOWN_RIGHT },{ 0, 1, 2, CV_CHAINCODE_DOWN },{ -1, 1, 2, CV_CHAINCODE_DOWN_LEFT } },
{ { -1, 1, 2, CV_CHAINCODE_DOWN_LEFT },{ -1, 0, 3, CV_CHAINCODE_LEFT },{ -1, -1, 3, CV_CHAINCODE_UP_LEFT } }
};
const char movesI[4][3][4] = { { { 1, -1, 3, CV_CHAINCODE_UP_RIGHT },{ 0, -1, 0, CV_CHAINCODE_UP },{ -1, -1, 0, CV_CHAINCODE_UP_LEFT } },
{ { -1, -1, 0, CV_CHAINCODE_UP_LEFT },{ -1, 0, 1, CV_CHAINCODE_LEFT },{ -1, 1, 1, CV_CHAINCODE_DOWN_LEFT } },
{ { -1, 1, 1, CV_CHAINCODE_DOWN_LEFT },{ 0, 1, 2, CV_CHAINCODE_DOWN },{ 1, 1, 2, CV_CHAINCODE_DOWN_RIGHT } },
{ { 1, 1, 2, CV_CHAINCODE_DOWN_RIGHT },{ 1, 0, 3, CV_CHAINCODE_RIGHT },{ 1, -1, 3, CV_CHAINCODE_UP_RIGHT } }
};
typedef unsigned int CvLabel; typedef unsigned int CvLabel;
const char cvChainCodeMoves[8][2] = {
{ 0, -1 },
{ 1, -1 },
{ 1, 0 },
{ 1, 1 },
{ 0, 1 },
{ -1, 1 },
{ -1, 0 },
{ -1, -1 }
};
typedef unsigned char CvChainCode;
typedef std::list<CvChainCode> CvChainCodes;
typedef struct {
cv::Point startingPoint;
CvChainCodes chainCode;
} CvContourChainCode;
typedef std::list<CvContourChainCode *> CvContoursChainCode;
typedef struct {
CvLabel label; //ǩ
union
{
unsigned int area; //(moment 00)
unsigned int m00; //Moment 00
};
unsigned int minx; // X min.
unsigned int maxx; // X max.
unsigned int miny; // Y min.
unsigned int maxy; // Y max.
cv::Point2d centroid; //
double m10; ///< Moment 10.
double m01; ///< Moment 01.
double m11; ///< Moment 11.
double m20; ///< Moment 20.
double m02; ///< Moment 02.
double u11; ///< Central moment 11.
double u20; ///< Central moment 20.
double u02; ///< Central moment 02.
double n11; ///< Normalized central moment 11.
double n20; ///< Normalized central moment 20.
double n02; ///< Normalized central moment 02.
double p1; ///< Hu moment 1.
double p2; ///< Hu moment 2.
CvContourChainCode contour; ///< Contour.
CvContoursChainCode internalContours; ///< Internal contours.
} CvBlob;
typedef std::map<CvLabel, CvBlob *> CvBlobs;
typedef std::pair<CvLabel, CvBlob *> CvLabelBlob;
typedef std::map<CvLabel, cv::Scalar> Palete; typedef std::map<CvLabel, cv::Scalar> Palete;
/// \def _HSV2RGB_(H, S, V, R, G, B) /// \def _HSV2RGB_(H, S, V, R, G, B)
...@@ -136,25 +48,4 @@ typedef std::map<CvLabel, cv::Scalar> Palete; ...@@ -136,25 +48,4 @@ typedef std::map<CvLabel, cv::Scalar> Palete;
} \ } \
} }
inline void cvReleaseBlobs(CvBlobs &blobs)
{
for (CvBlobs::iterator it = blobs.begin(); it != blobs.end(); ++it)
{
CvBlob *blob = (*it).second;
if (blob)
{
for (CvContoursChainCode::iterator jt = blob->internalContours.begin(); jt != blob->internalContours.end(); ++jt)
{
CvContourChainCode *contour = *jt;
if (contour)
delete contour;
}
blob->internalContours.clear();
delete blob;
}
}
blobs.clear();
}
#endif/* __EYEM_BIN_H */ #endif/* __EYEM_BIN_H */
\ No newline at end of file \ No newline at end of file
...@@ -79,6 +79,9 @@ int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, Eyem ...@@ -79,6 +79,9 @@ int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, Eyem
int eyemClp2dIntersectionLineSegment(EyemOcsDABC tpLine, EyemOcsDXY tpPtSt, EyemOcsDXY tpPtEd, int *ipStatus, EyemOcsDXY &tpPoint) int eyemClp2dIntersectionLineSegment(EyemOcsDABC tpLine, EyemOcsDXY tpPtSt, EyemOcsDXY tpPtEd, int *ipStatus, EyemOcsDXY &tpPoint)
{ {
if ((tpPtSt.dX - tpPtEd.dX) + (tpPtSt.dY - tpPtEd.dY) < EPS) {
return FUNC_CANNOT_CALC;
}
double d1, d2; double d1, d2;
d1 = abs(tpLine.dA*tpPtSt.dX + tpLine.dB*tpPtSt.dY + tpLine.dC) / sqrt(tpLine.dA*tpLine.dA + tpLine.dB*tpLine.dB); d1 = abs(tpLine.dA*tpPtSt.dX + tpLine.dB*tpPtSt.dY + tpLine.dC) / sqrt(tpLine.dA*tpLine.dA + tpLine.dB*tpLine.dB);
if (abs(tpLine.dB) < FLT_EPSILON) { if (abs(tpLine.dB) < FLT_EPSILON) {
......
...@@ -27,17 +27,17 @@ static cv::Mat projectMap(const cv::Mat map, int threshold) ...@@ -27,17 +27,17 @@ static cv::Mat projectMap(const cv::Mat map, int threshold)
{ {
double height = .0, width = map.cols; double height = .0, width = map.cols;
cv::Mat temp; cv::Mat nmMap;
cv::normalize(map, temp, 0, 255, cv::NORM_MINMAX); cv::normalize(map, nmMap, 0, 255, cv::NORM_MINMAX);
cv::minMaxLoc(temp, NULL, &height, NULL, NULL); cv::minMaxLoc(nmMap, NULL, &height, NULL, NULL);
cv::Mat image = cv::Mat::zeros((int)height, (int)width, CV_8UC3); cv::Mat image = cv::Mat::zeros((int)height, (int)width, CV_8UC3);
image.setTo(cv::Scalar(100, 0, 0)); image.setTo(cv::Scalar(100, 0, 0));
std::vector<cv::Point> rejectPoint; std::vector<cv::Point> rejectPoint;
for (int i = 0; i < temp.cols; i++) for (int i = 0; i < nmMap.cols; i++)
{ {
rejectPoint.push_back(cv::Point(i, (int)(height - temp.at<float>(cv::Point(i, 0))))); rejectPoint.push_back(cv::Point(i, (int)(height - nmMap.at<float>(cv::Point(i, 0)))));
} }
cv::polylines(image, rejectPoint, false, cv::Scalar(0, 255, 0), 1, 8, 0); cv::polylines(image, rejectPoint, false, cv::Scalar(0, 255, 0), 1, 8, 0);
...@@ -389,6 +389,14 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -389,6 +389,14 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
if (image.empty()) { if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
//灰度图
int incn = image.channels();
if (incn > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2GRAY);
}
else if (incn == 3) {
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
}
const int X = image.cols, Y = image.rows; const int X = image.cols, Y = image.rows;
//显示用 //显示用
cv::Mat cc; cv::Mat cc;
...@@ -400,12 +408,16 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -400,12 +408,16 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
//主轴倾角 //主轴倾角
double t; double t;
t = atan2(tpLineEd.dY - tpLineSt.dY, tpLineEd.dX - tpLineSt.dX); t = atan2(tpLineEd.dY - tpLineSt.dY, tpLineEd.dX - tpLineSt.dX);
//参数限制
iCapWidth = iCapWidth <= 0 ? iCapWidth = 0 : iCapWidth - 1;
iCapLength = iCapLength <= 0 ? 8 : iCapLength;
nCalipers = nCalipers <= 0 ? 5 : nCalipers;
//直线上的坐标 //直线上的坐标
float L = (float)cv::norm(cv::Point2d(tpLineSt.dX, tpLineSt.dY) - cv::Point2d(tpLineEd.dX, tpLineEd.dY)); float L = (float)cv::norm(cv::Point2d(tpLineSt.dX, tpLineSt.dY) - cv::Point2d(tpLineEd.dX, tpLineEd.dY));
//步长 //步长
float plusStep = (L - (float)nCalipers*(float)iCapWidth) / ((float)nCalipers + 1.0f); float plusStep = (L - (float)nCalipers*(float)iCapWidth) / ((float)nCalipers + 1.0f);
//绘制profileLine //绘制profileLine
//drawArrowedLine("", tpLineSt, tpLineEd, cv::Scalar(255, 153, 0), 2); cv::arrowedLine(cc, cv::Point(cvRound(tpLineSt.dX), cvRound(tpLineSt.dY)), cv::Point(cvRound(tpLineEd.dX), cvRound(tpLineEd.dY)), cv::Scalar(255, 153, 0), 1);
//判断极性 //判断极性
bool anyPolarity = strcmp("all", ccTransition) == 0; bool anyPolarity = strcmp("all", ccTransition) == 0;
//默认过滤一半像素 //默认过滤一半像素
...@@ -419,7 +431,7 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -419,7 +431,7 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
//线采样,采用双三次插值 //线采样,采用双三次插值
cv::Size szMap(2 * iCapLength + 1, iCapWidth + 1); cv::Size szMap(2 * iCapLength + 1, iCapWidth + 1);
//结果 //结果
std::vector<EyemOcsDXY> edgePoint; std::vector<EyemOcsDXY> *tpResults = new std::vector<EyemOcsDXY>();
for (int n = 1; n <= nCalipers; n++) for (int n = 1; n <= nCalipers; n++)
{ {
float *pMag = new float[szMap.width*szMap.height * sizeof(float_t)]; float *pMag = new float[szMap.width*szMap.height * sizeof(float_t)];
...@@ -430,7 +442,6 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -430,7 +442,6 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
plusY = ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + m) * (float)sin(t); plusY = ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + m) * (float)sin(t);
//中轴线路径上的点 //中轴线路径上的点
cv::Point2f pLine((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY); cv::Point2f pLine((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY);
//drawPoint("", pLine, cv::Scalar(0, 0, 255), 4);
for (int iR = -iCapLength; iR <= iCapLength; iR++) { for (int iR = -iCapLength; iR <= iCapLength; iR++) {
//待插值坐标 //待插值坐标
float _plusX, _plusY; float _plusX, _plusY;
...@@ -441,11 +452,11 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -441,11 +452,11 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
pMag[(iCapLength + iR) + m*szMap.width] = -1; pMag[(iCapLength + iR) + m*szMap.width] = -1;
continue; continue;
} }
#ifdef _DEBUG
//drawPoint("", cv::Point2f(_plusX, _plusY), cv::Scalar(36, 127, 255), 1); //drawPoint("", cv::Point2f(_plusX, _plusY), cv::Scalar(36, 127, 255), 1);
//画像素 //画像素
float bb = (float)cos(t)*0.5f; float bb = (float)cos(t)*0.5f;
float aa = (float)sin(t)*0.5f; float aa = (float)sin(t)*0.5f;
cv::Point2f pt(_plusX, _plusY); cv::Point2f pt(_plusX, _plusY);
cv::Point2f pts[4]; cv::Point2f pts[4];
pts[0].x = (float)(pt.x - aa - bb); pts[0].x = (float)(pt.x - aa - bb);
...@@ -456,10 +467,11 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -456,10 +467,11 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
pts[2].y = (float)(2 * pt.y - pts[0].y); pts[2].y = (float)(2 * pt.y - pts[0].y);
pts[3].x = (float)(2 * pt.x - pts[1].x); pts[3].x = (float)(2 * pt.x - pts[1].x);
pts[3].y = (float)(2 * pt.y - pts[1].y); pts[3].y = (float)(2 * pt.y - pts[1].y);
//for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
//{ {
// drawLine("", pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0)); //drawLine("", pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0));
//} }
#endif
//整数部分 //整数部分
int x = cvRound(_plusX), y = cvRound(_plusY); int x = cvRound(_plusX), y = cvRound(_plusY);
//小数部分 //小数部分
...@@ -497,14 +509,13 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -497,14 +509,13 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
//判断灰度值过滤类型 //判断灰度值过滤类型
if (anyPolarity) { if (anyPolarity) {
//不分极性 //不分极性
float maxDist = 0; int maxPos = 0; float maxDist = 0; int maxPos = 0; found = true;
for (auto&peek : peeks) { for (auto&peek : peeks) {
if (abs(pFilteredMap[peek]) > maxDist) { if (abs(pFilteredMap[peek]) > maxDist) {
maxDist = abs(pFilteredMap[peek]); maxDist = abs(pFilteredMap[peek]);
maxPos = peek; maxPos = peek;
} }
} }
found = true;
dist = (float)maxPos; dist = (float)maxPos;
} }
else if (strcmp("positive", ccTransition) == 0) { else if (strcmp("positive", ccTransition) == 0) {
...@@ -539,19 +550,16 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -539,19 +550,16 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
a = pFilteredMap[l]; b = pFilteredMap[m]; a = pFilteredMap[l]; b = pFilteredMap[m];
c = pFilteredMap[r]; c = pFilteredMap[r];
u = 0.5f*(a - c) / (a - b - b + c); u = 0.5f*(a - c) / (a - b - b + c);
//定位结果 //定位结果
float dstX, dstY; float dstX, dstY;
dstX = midLineStart.x + (dist + u)*(float)cos(t + iSearchDirec* CV_PI / 2.0); dstX = midLineStart.x + (dist + u)*(float)cos(t + iSearchDirec* CV_PI / 2.0);
dstY = midLineStart.y + (dist + u)*(float)sin(t + iSearchDirec* CV_PI / 2.0); dstY = midLineStart.y + (dist + u)*(float)sin(t + iSearchDirec* CV_PI / 2.0);
//drawPoint("", cv::Point2f(dstX, dstY), cv::Scalar(0, 0, 255), 2); EyemOcsDXY tpResult;
//edgePoint.push_back(EdgePoint(0, dstX, dstY, 0, 0, true)); tpResult.dX = dstX; tpResult.dY = dstY;
tpResults->push_back(tpResult);
} }
} }
//作图显示用 #ifdef _DEBUG
cv::Mat cc;
cv::cvtColor(image, cc, cv::COLOR_GRAY2BGR);
//drawArrowedLine("", midLineStart, midLineEnd, cv::Scalar(0, 255, 0), 2);
cv::arrowedLine(cc, midLineStart, midLineEnd, cv::Scalar(0, 255, 0), 1); cv::arrowedLine(cc, midLineStart, midLineEnd, cv::Scalar(0, 255, 0), 1);
//画卡尺 //画卡尺
float bb = (float)cos(t)*0.5f; float bb = (float)cos(t)*0.5f;
...@@ -566,47 +574,220 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -566,47 +574,220 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
pts[2].y = (float)(2 * pt.y - pts[0].y); pts[2].y = (float)(2 * pt.y - pts[0].y);
pts[3].x = (float)(2 * pt.x - pts[1].x); pts[3].x = (float)(2 * pt.x - pts[1].x);
pts[3].y = (float)(2 * pt.y - pts[1].y); pts[3].y = (float)(2 * pt.y - pts[1].y);
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
{ {
//drawLine("", pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0), 2); //drawLine("", pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0), 2);
cv::line(cc, pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0));
} }
#endif
//释放资源 //释放资源
delete[] pMag; delete[] pMag;
pMag = NULL; pMag = NULL;
} }
if (!edgePoint.empty()) { #ifdef _DEBUG
if (!tpResults->empty()) {
//拟合直线 //拟合直线
//double k, b, rms; EyemOcsDABC tpLine;
//findLine(edgePoint, 1, k, b, rms); eyemFitLine((int)tpResults->size(), tpResults->data(), 3, tpLine);
////计算交点
//cv::Point2f it;
//eyemClp2dIntersectionLineSegment(k, -1, b, 43, 25, 231, 25, it);
//画直线y=kx+b--->kx-y+b=0 //画直线y=kx+b--->kx-y+b=0
//(0,P1)、(X,P2)、(P3,0)、(P4,Y) //(0,P1)、(X,P2)、(P3,0)、(P4,Y)
cv::Point2f p1, p2; cv::Mat dst;
//eyemClp2dIntersectionOfLineRectangle(k, -1, b, 0, 0, X, 0, X, Y, p1, p2); getSuperResolution(image, dst, 10);
cv::cvtColor(dst, dst, cv::COLOR_GRAY2BGR);
//drawLine("", p1, p2, cv::Scalar(0, 255, 0), 1); for (int i = 0; i < tpResults->size(); i++)
{
cv::circle(dst, cv::Point(int(round(tpResults->at(i).dX * 10)), int(round(tpResults->at(i).dY * 10))), 1, cv::Scalar(0, 255, 0), -1);
}
} }
//cv::Mat dst; #endif
//getSuperResolution(image, dst, 10); //释放资源(Tips:当存在越界时候在用free释放时会报错)
//cv::cvtColor(dst, dst, cv::COLOR_GRAY2BGR);
//for (int i = 0; i < dstPts.size(); i++)
//{
// cv::circle(dst, cv::Point(int(round(dstPts[i].x * 10)), int(round(dstPts[i].y * 10))), 1, cv::Scalar(0, 255, 0), -1);
//}
////释放内存(Tips:当存在越界时候在用free释放时会报错)
//free((void *)pMap);
//释放资源
delete[] filterK; delete[] filterK;
filterK = NULL; filterK = NULL;
//输出结果
*hObject = reinterpret_cast<IntPtr>(tpResults);
return FUNC_OK; return FUNC_OK;
} }
int eyemEdge1dFitCircle(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDXYR *tpCircle) int eyemEdge1dFindCircle(EyemImage tpImage, EyemOcsDXY tpPoint, int iRadius, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject)
{ {
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
//灰度图
int incn = image.channels();
if (incn > 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2GRAY);
}
else if (incn == 3) {
cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
}
const int X = image.cols, Y = image.rows;
//判断越界
if (tpPoint.dX < 0 || tpPoint.dY < 0 || tpPoint.dX>X || tpPoint.dY>Y) {
return 0;
}
cv::Mat cc;
cv::cvtColor(image, cc, cv::COLOR_GRAY2BGR);
//步长
float plusStep = float(TWO_PI / (float)nCalipers);
//绘制profileLine
cv::circle(cc, cv::Point(cvRound(tpPoint.dX), cvRound(tpPoint.dY)), iRadius, cv::Scalar(), 1);
//判断极性
bool anyPolarity = strcmp("all", ccTransition) == 0;
//默认过滤一半像素
float *filterK = new float[2 * nFilterSize + 1]();
//定义滤波核
for (int n = 0; n < nFilterSize; n++) {
filterK[n] = 1;
filterK[2 * nFilterSize - n] = -1;
}
cv::Mat whalf(cv::Size(2 * nFilterSize + 1, 1), CV_32FC1, filterK);
//参数限制
iCapWidth = iCapWidth <= 0 ? 0 : iCapWidth - 1;
iCapLength = iCapLength <= 0 ? 12 : iCapLength;
nCalipers = nCalipers <= 0 ? 10 : nCalipers;
//线采样
cv::Size szMap(2 * iCapLength + 1, iCapWidth + 1);
//结果
std::vector<EyemOcsDXY> *tpResults = new std::vector<EyemOcsDXY>();
for (float t = -(float)PI; t < PI; t += plusStep)
{
int m = 0;
//路径上的点
float x = float(tpPoint.dX + (float)iRadius*cos(t));
float y = float(tpPoint.dY + (float)iRadius*sin(t));
//采样图像
float *pMag = new float[szMap.width*szMap.height * sizeof(float_t)];
for (float n = -(float)iCapWidth / 2.0f; n <= (float)iCapWidth / 2.0f; n += 1.0f, m++)
{
for (int iR = -iCapLength; iR <= iCapLength; iR++) {
//待插值坐标
float _plusX, _plusY;
_plusX = (float)iR*iSearchDirec*(float)cos(t) + x + n*(float)cos(t + CV_PI / 2);
_plusY = (float)iR*iSearchDirec*(float)sin(t) + y + n*(float)sin(t + CV_PI / 2);
//防止越界
if (_plusX < 1 || _plusX >= X - 2 || _plusY < 1 || _plusY >= Y - 2) {
continue;
}
//drawPoint("", cv::Point2f(_plusX, _plusY), cv::Scalar(36, 127, 255), 1);
//整数部分
int x = cvRound(_plusX), y = cvRound(_plusY);
//小数部分
float u = abs(_plusX - ((float)x + 0.5f));
float v = abs(_plusY - ((float)y - 1.0f + 0.5f));
//插值计算灰度值
float gv = (1.0f - v)*(image.ptr<uint8_t>(y - 1)[x] * (1.0f - u) + image.ptr<uint8_t>(y - 1)[x - 1] * u)
+ v*(image.ptr<uint8_t>(y)[x] * (1.0f - u) + image.ptr<uint8_t>(y)[x - 1] * u);
//填入灰度值
pMag[(iCapLength + iR) + m*szMap.width] = gv;
}
}
//采样位置中线
cv::Point2f midLineStart, midLineEnd;
midLineStart = cv::Point2f(-iCapLength*iSearchDirec*(float)cos(t) + x, -iCapLength*iSearchDirec*(float)sin(t) + y);
midLineEnd = cv::Point2f(iCapLength*iSearchDirec*(float)cos(t) + x, iCapLength*iSearchDirec*(float)sin(t) + y);
cv::arrowedLine(cc, cv::Point(), cv::Point(), cv::Scalar(0, 255, 0), 1);
//采样图像
cv::Mat interMap(szMap, CV_32FC1, pMag);
//计算投影
cv::Mat projectedMap;
cv::reduce(interMap, projectedMap, 0, cv::REDUCE_AVG, CV_32F);
//差分过滤(TODO:加高斯滤波)
float *pFilteredMap = new float[szMap.width * sizeof(float_t)];
cv::Mat filteredMap(cv::Size(szMap.width, 1), CV_32FC1, pFilteredMap);
cv::sepFilter2D(projectedMap, filteredMap, CV_32F, whalf, cv::Mat::ones(1, 1, CV_32F));
//投影峰值查找
std::vector<int> peeks;
findPeak(szMap.width, pFilteredMap, (float)dAmpThreshold, peeks);
//存在满足幅度值的边缘
if (!peeks.empty()) {
float dist = 0; bool found = false;
//判断灰度值过滤类型
if (anyPolarity) {
//不分极性
float maxDist = 0; int maxPos = 0;
for (auto&peek : peeks) {
if (abs(pFilteredMap[peek]) > maxDist) {
maxDist = abs(pFilteredMap[peek]);
maxPos = peek;
}
}
found = true;
dist = (float)maxPos;
}
else if (strcmp("positive", ccTransition) == 0) {
int maxPos = 0;
for (auto&peek : peeks) {
if (pFilteredMap[peek] > 0) {
maxPos = peek;
found = true;
break;
}
}
dist = (float)maxPos;
}
else if (strcmp("negative", ccTransition) == 0) {
int maxPos = 0;
for (auto&peek : peeks) {
if (pFilteredMap[peek] < 0) {
maxPos = peek;
found = true;
break;
}
}
dist = (float)maxPos;
}
//阈值限制,计算亚像素坐标
if (found) {
int l, m, r; float a, b, c, u;
m = (int)dist;
l = m - 1 < 0 ? m : m - 1;
r = m + 1 >= szMap.width ? m : m + 1;
a = pFilteredMap[l]; b = pFilteredMap[m];
c = pFilteredMap[r];
u = 0.5f*(a - c) / (a - b - b + c);
//定位结果
float dstX, dstY;
dstX = midLineStart.x + iSearchDirec*(dist + u)*(float)cos(t);
dstY = midLineStart.y + iSearchDirec*(dist + u)*(float)sin(t);
EyemOcsDXY tpResult;
tpResult.dX = dstX; tpResult.dY = dstY;
tpResults->push_back(tpResult);
}
}
#ifdef _DEBUG
//画卡尺
float bb = (float)cos(t + CV_PI / 2)*0.5f;
float aa = (float)sin(t + CV_PI / 2)*0.5f;
cv::Point2f pt(x, y);
cv::Point2f pts[4];
pts[0].x = (float)(pt.x - aa * szMap.width - bb * szMap.height);
pts[0].y = (float)(pt.y + bb * szMap.width - aa * szMap.height);
pts[1].x = (float)(pt.x + aa * szMap.width - bb * szMap.height);
pts[1].y = (float)(pt.y - bb * szMap.width - aa * szMap.height);
pts[2].x = (float)(2 * pt.x - pts[0].x);
pts[2].y = (float)(2 * pt.y - pts[0].y);
pts[3].x = (float)(2 * pt.x - pts[1].x);
pts[3].y = (float)(2 * pt.y - pts[1].y);
for (int j = 0; j < 4; j++)
{
cv::line(cc, pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0));
}
#endif
//释放资源
delete[] pMag;
pMag = NULL;
}
//释放资源
delete[] filterK;
filterK = NULL;
//输出结果
*hObject = reinterpret_cast<IntPtr>(tpResults);
return FUNC_OK; return FUNC_OK;
} }
...@@ -622,6 +803,4 @@ bool eyemEdge1dGenMeasureFree(IntPtr hObject) ...@@ -622,6 +803,4 @@ bool eyemEdge1dGenMeasureFree(IntPtr hObject)
delete tpEdges; delete tpEdges;
tpEdges = NULL; tpEdges = NULL;
return true; return true;
} }
\ No newline at end of file \ No newline at end of file
...@@ -391,8 +391,10 @@ extern "C" { ...@@ -391,8 +391,10 @@ extern "C" {
EXPORTS int eyemMatAdd(EyemImage vpA, EyemImage vpB, EyemImage &vpC); EXPORTS int eyemMatAdd(EyemImage vpA, EyemImage vpB, EyemImage &vpC);
EXPORTS int eyemMatSub(EyemImage tpImageMinuend, EyemImage tpImageSubtrahend, EyemImage &tpDstImg); EXPORTS int eyemMatSub(EyemImage tpImageMinuend, EyemImage tpImageSubtrahend, EyemImage &tpDstImg);
EXPORTS int eyemMatAbs(EyemImage &tpImage); EXPORTS int eyemMatAbs(EyemImage &tpImage);
EXPORTS int eyemCvtType(EyemImage tpImage, const char *ccSubType, double alpha, double beta, EyemImage &tpDstImg); EXPORTS int eyemNormalize(EyemImage &tpImage);
EXPORTS int eyemCvtColor(EyemImage tpImage, int iCCodes, EyemImage &tpDstImg); EXPORTS int eyemDecompose(EyemImage tpImage, EyemImage *tpDstImgR, EyemImage *tpDstImgG, EyemImage *tpDstImgB);
EXPORTS int eyemCvtImageType(EyemImage tpImage, const char *ccSubType, double alpha, double beta, EyemImage &tpDstImg);
EXPORTS int eyemCvtImageColor(EyemImage tpImage, int iCCodes, EyemImage &tpDstImg);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -479,36 +481,6 @@ extern "C" { ...@@ -479,36 +481,6 @@ extern "C" {
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// 3D 几何计算(3D 卡尺)(eyemClp3d.cpp)
//
#ifdef __cplusplus
extern "C" {
#endif
// 函数接口
void eyemClp3dDistanceTwoPoints(EyemOcsDXYZ *, EyemOcsDXYZ *, double *);
void eyemClp3dCenterTwoPoints(EyemOcsDXYZ *, EyemOcsDXYZ *, EyemOcsDXYZ *);
int eyemClp3dLineTwoPoints(EyemOcsDXYZ *, EyemOcsDXYZ *, EyemOcsDPV *);
int eyemClp3dFootOfPerpendicularToLine(EyemOcsDXYZ *, EyemOcsDPV *, EyemOcsDXYZ *);
int eyemClp3dVerticalLinePointAndLine(EyemOcsDXYZ *, EyemOcsDPV *, EyemOcsDPV *);
int eyemClp3dDistancePointToLine(EyemOcsDXYZ *, EyemOcsDPV *, double *);
int eyemClp3dDistanceTwoLines(EyemOcsDPV *, EyemOcsDPV *, double *);
int eyemClp3dPlaneThreePoints(EyemOcsDXYZ *, EyemOcsDXYZ *, EyemOcsDXYZ *, EyemOcsDABCD *);
int eyemClp3dVerticalPlanePointAndVector(EyemOcsDXYZ *, EyemOcsDXYZ *, EyemOcsDABCD *);
int eyemClp3dVerticalLinePointAndPlane(EyemOcsDXYZ *, EyemOcsDABCD *, EyemOcsDPV *);
int eyemClp3dDistancePointToPlane(EyemOcsDXYZ *, EyemOcsDABCD *, double *);
int eyemClp3dIntersectionLineAndPlane(EyemOcsDPV *, EyemOcsDABCD *, EyemOcsDXYZ *);
int eyemClp3dAngleLineAndPlane(EyemOcsDPV *, EyemOcsDABCD *, double *);
int eyemClp3dFootOfPerpendicularToPlane(EyemOcsDXYZ *, EyemOcsDABCD *, EyemOcsDXYZ *);
int eyemClp3dIntersectionTwoPlanes(EyemOcsDABCD *, EyemOcsDABCD *, EyemOcsDPV *);
int eyemClp3dAngleTwoPlanes(EyemOcsDABCD *, EyemOcsDABCD *, double *);
#ifdef __cplusplus
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
// 计算几何(eyemCg.cpp) // 计算几何(eyemCg.cpp)
// //
...@@ -619,6 +591,7 @@ extern "C" { ...@@ -619,6 +591,7 @@ extern "C" {
// 函数接口 // 函数接口
EXPORTS int eyemBinThreshold(EyemImage tpSrcImg, int iLightDark, double dThresh, double dMaxVal, EyemImage *tpDstImg); EXPORTS int eyemBinThreshold(EyemImage tpSrcImg, int iLightDark, double dThresh, double dMaxVal, EyemImage *tpDstImg);
EXPORTS int eyemBinThresholdC(EyemImage tpImage, int ipRangeL[3], int ipRangeU[3], EyemImage *tpDstImg);
EXPORTS int eyemBinAutoThreshold(EyemImage tpSrcImg, double dSigma, int iLightDark, int binMethod, EyemImage *tpDstImg); EXPORTS int eyemBinAutoThreshold(EyemImage tpSrcImg, double dSigma, int iLightDark, int binMethod, EyemImage *tpDstImg);
EXPORTS int eyemBinNiBlack(EyemImage tpSrcImg, int iType, int iWinSize, double dK, int binarizationMethod, double dR, EyemImage *tpDstImg); EXPORTS int eyemBinNiBlack(EyemImage tpSrcImg, int iType, int iWinSize, double dK, int binarizationMethod, double dR, EyemImage *tpDstImg);
EXPORTS int eyemBinDynThreshold(EyemImage tpSrcImg, EyemImage tpPreImg, double dOffset, int iType, EyemImage *tpDstImg); EXPORTS int eyemBinDynThreshold(EyemImage tpSrcImg, EyemImage tpPreImg, double dOffset, int iType, EyemImage *tpDstImg);
...@@ -627,9 +600,6 @@ extern "C" { ...@@ -627,9 +600,6 @@ extern "C" {
EXPORTS int eyemBinOpening(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg); EXPORTS int eyemBinOpening(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg);
EXPORTS int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg); EXPORTS int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg);
EXPORTS int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg); EXPORTS int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg);
EXPORTS int eyemBinBlobFilterByArea(IntPtr hObject, int iMinArea, int iMaxArea);
EXPORTS int eyemBinBlobFilterByLabel(IntPtr hObject, int iLabel);
EXPORTS int eyemBinBlobRender(EyemImage tpImage, IntPtr hObject, EyemImage *tpDstImg);
EXPORTS bool eyemBinFree(IntPtr hObject); EXPORTS bool eyemBinFree(IntPtr hObject);
#ifdef __cplusplus #ifdef __cplusplus
...@@ -649,8 +619,7 @@ extern "C" { ...@@ -649,8 +619,7 @@ extern "C" {
// 函数接口 // 函数接口
EXPORTS int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, const char *ccSubType, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject); EXPORTS int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, const char *ccSubType, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject);
EXPORTS int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject); EXPORTS int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject);
EXPORTS int eyemEdge1dFitLine(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDABC *tpLine); EXPORTS int eyemEdge1dFindCircle(EyemImage tpImage, EyemOcsDXY tpPoint, int iRadius, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject);
EXPORTS int eyemEdge1dFitCircle(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDXYR *tpCircle);
EXPORTS int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iCapLength, int iCapWidth, int nCalipers, int iFilterSize, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject); EXPORTS int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iCapLength, int iCapWidth, int nCalipers, int iFilterSize, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject);
EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject); EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject);
...@@ -853,6 +822,7 @@ extern "C" { ...@@ -853,6 +822,7 @@ extern "C" {
EXPORTS int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, int *ipReelNum, EyemImage *tpDstImg); EXPORTS int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, int *ipReelNum, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char * ccSubType, int *ipReelNum, EyemImage *tpDstImg); EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char * ccSubType, int *ipReelNum, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char *ccTplName, IntPtr hModelID, int *ipReelNum, EyemImage *tpDstImg); EXPORTS int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, const char *ccTplName, IntPtr hModelID, int *ipReelNum, EyemImage *tpDstImg);
EXPORTS int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, 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, IntPtr hModelID, char **lpszTplName); EXPORTS int eyemMatchTemplateModel(EyemImage tpImage, IntPtr hModelID, char **lpszTplName);
......
此文件类型无法预览
...@@ -74,8 +74,8 @@ ...@@ -74,8 +74,8 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\tbb2017_20170604oss\include;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;$(IncludePath)</IncludePath> <IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\tbb2017_20170604oss\include;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;D:\feature_extract\include;D:\feature_extract\include\ncnn;$(IncludePath)</IncludePath>
<LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\tbb2017_20170604oss\lib\intel64\vc14;D:\zxing-cpp-master\build\Debug;$(LibraryPath)</LibraryPath> <LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\tbb2017_20170604oss\lib\intel64\vc14;D:\zxing-cpp-master\build\Debug;D:\feature_extract\lib;$(LibraryPath)</LibraryPath>
<TargetExt>.dll</TargetExt> <TargetExt>.dll</TargetExt>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
...@@ -83,8 +83,8 @@ ...@@ -83,8 +83,8 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\tbb2017_20170604oss\include;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;$(IncludePath)</IncludePath> <IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\tbb2017_20170604oss\include;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;D:\feature_extract\include;D:\feature_extract\include\ncnn;$(IncludePath)</IncludePath>
<LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\tbb2017_20170604oss\lib\intel64\vc14;D:\zxing-cpp-master\build\Release;$(LibraryPath)</LibraryPath> <LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\tbb2017_20170604oss\lib\intel64\vc14;D:\zxing-cpp-master\build\Release;D:\feature_extract\lib;$(LibraryPath)</LibraryPath>
<TargetExt>.dll</TargetExt> <TargetExt>.dll</TargetExt>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libdmtx.lib;libzxing-debug.lib;libdecoded.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libdmtx.lib;libzxing-debug.lib;libdecoded.lib;libresnet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
...@@ -161,7 +161,7 @@ ...@@ -161,7 +161,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libdmtx.lib;libzxing.lib;libdecode.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libdmtx.lib;libzxing.lib;libdecode.lib;libresnet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
......
...@@ -407,7 +407,7 @@ int eyemMatAbs(EyemImage &tpImage) ...@@ -407,7 +407,7 @@ int eyemMatAbs(EyemImage &tpImage)
return FUNC_OK; return FUNC_OK;
} }
int eyemCvtType(EyemImage tpImage, const char *ccSubType, double alpha, double beta, EyemImage &tpDstImg) int eyemCvtImageType(EyemImage tpImage, const char *ccSubType, double alpha, double beta, EyemImage &tpDstImg)
{ {
CV_Assert(NULL != tpImage.vpImage); CV_Assert(NULL != tpImage.vpImage);
...@@ -492,7 +492,7 @@ int eyemCvtType(EyemImage tpImage, const char *ccSubType, double alpha, double b ...@@ -492,7 +492,7 @@ int eyemCvtType(EyemImage tpImage, const char *ccSubType, double alpha, double b
return FUNC_OK; return FUNC_OK;
} }
int eyemCvtColor(EyemImage tpImage, int iCCodes, EyemImage &tpDstImg) int eyemCvtImageColor(EyemImage tpImage, int iCCodes, EyemImage &tpDstImg)
{ {
CV_Assert(NULL != tpImage.vpImage); CV_Assert(NULL != tpImage.vpImage);
...@@ -571,4 +571,91 @@ int eyemCvtColor(EyemImage tpImage, int iCCodes, EyemImage &tpDstImg) ...@@ -571,4 +571,91 @@ int eyemCvtColor(EyemImage tpImage, int iCCodes, EyemImage &tpDstImg)
//拷贝数据 //拷贝数据
memcpy(tpDstImg.vpImage, _dst.data, _Size); memcpy(tpDstImg.vpImage, _dst.data, _Size);
return FUNC_OK; return FUNC_OK;
}
int eyemDecompose(EyemImage tpImage, EyemImage *tpDstImgR, EyemImage *tpDstImgG, EyemImage *tpDstImgB)
{
CV_Assert(NULL != tpImage.vpImage);
if (tpImage.iChannels != 3) {
return FUNC_CANNOT_USE;
}
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
//分三通道
std::vector<cv::Mat> mv;
cv::split(image, mv);
//输出结果
tpDstImgR->iWidth = tpDstImgG->iWidth = tpDstImgB->iWidth = tpImage.iWidth;
tpDstImgR->iHeight = tpDstImgG->iHeight = tpDstImgB->iHeight = tpImage.iHeight;
tpDstImgR->iDepth = tpDstImgG->iDepth = tpDstImgB->iDepth = tpImage.iDepth;
tpDstImgR->iChannels = tpDstImgG->iChannels = tpDstImgB->iChannels = 1;
//内存尺寸
int _Size = tpDstImgR->iWidth*tpDstImgR->iHeight*tpDstImgR->iChannels * sizeof(uint8_t);
//分配初始化内存
tpDstImgR->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImgR->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImgR->vpImage, 0, _Size);
//拷贝数据
memcpy(tpDstImgR->vpImage, mv[2].data, _Size);
tpDstImgG->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImgG->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImgG->vpImage, 0, _Size);
//拷贝数据
memcpy(tpDstImgG->vpImage, mv[1].data, _Size);
tpDstImgB->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImgB->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImgB->vpImage, 0, _Size);
//拷贝数据
memcpy(tpDstImgB->vpImage, mv[0].data, _Size);
return FUNC_OK;
}
int eyemNormalize(EyemImage &tpImage)
{
CV_Assert(NULL != tpImage.vpImage);
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
_free(tpImage);
if (image.channels() != 3) {
cv::cvtColor(image, image, cv::COLOR_BGRA2BGR);
}
const int X = image.cols; const int Y = image.rows;
//归一化
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++) {
uint8_t b, g, r;
float bgr = (float)(image.ptr<cv::Vec3b>(y)[x][0] + image.ptr<cv::Vec3b>(y)[x][1] + image.ptr<cv::Vec3b>(y)[x][2]);
bgr = bgr == 0 ? 1 : 1.0f / bgr;
b = cvRound(255.0f*(float)image.ptr<cv::Vec3b>(y)[x][0] * bgr);
g = cvRound(255.0f*(float)image.ptr<cv::Vec3b>(y)[x][1] * bgr);
r = cvRound(255.0f*(float)image.ptr<cv::Vec3b>(y)[x][2] * bgr);
image.ptr<cv::Vec3b>(y)[x] = cv::Vec3b(b, g, r);
}
}
});
//输出
tpImage.iWidth = image.cols; tpImage.iHeight = image.rows; tpImage.iDepth = image.depth(); tpImage.iChannels = image.channels();
int _Size = image.cols *image.rows *image.channels() * sizeof(uint8_t);
tpImage.vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpImage.vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage.vpImage, 0, _Size);
//拷贝数据
memcpy(tpImage.vpImage, image.data, _Size);
return FUNC_OK;
} }
\ No newline at end of file \ No newline at end of file
...@@ -4352,13 +4352,10 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4352,13 +4352,10 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
logger.t("eyemCountObjectIrregularPartsE 初始阶段被跳过执行..."); logger.t("eyemCountObjectIrregularPartsE 初始阶段被跳过执行...");
return FUNC_CANNOT_CALC; return FUNC_CANNOT_CALC;
} }
//图像裁剪 //图像裁剪
src = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone(); src = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
//image size //image size
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
//去除局部量斑影响(默认亮斑尺寸不会大于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)));
...@@ -4470,7 +4467,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4470,7 +4467,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
for (int i = 0; i < trays.size(); i++) for (int i = 0; i < trays.size(); i++)
{ {
//左上角 //左上角
if (trays[i].Center.x < reelCenter.x&&trays[i].Center.y < reelCenter.y) if ((int)trays[i].Center.x <= reelCenter.x && (int)trays[i].Center.y <= reelCenter.y)
{ {
if (trays[i].bSorted == false) if (trays[i].bSorted == false)
{ {
...@@ -4483,7 +4480,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4483,7 +4480,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
for (int i = 0; i < trays.size(); i++) for (int i = 0; i < trays.size(); i++)
{ {
//左下角 //左下角
if (trays[i].Center.x < reelCenter.x&&trays[i].Center.y > reelCenter.y) if ((int)trays[i].Center.x <= reelCenter.x && (int)trays[i].Center.y >= reelCenter.y)
{ {
if (trays[i].bSorted == false) if (trays[i].bSorted == false)
{ {
...@@ -4496,7 +4493,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4496,7 +4493,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
for (int i = 0; i < trays.size(); i++) for (int i = 0; i < trays.size(); i++)
{ {
//右下角 //右下角
if (trays[i].Center.x > reelCenter.x&&trays[i].Center.y > reelCenter.y) if ((int)trays[i].Center.x >= reelCenter.x && (int)trays[i].Center.y >= reelCenter.y)
{ {
if (trays[i].bSorted == false) if (trays[i].bSorted == false)
{ {
...@@ -4509,7 +4506,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in ...@@ -4509,7 +4506,7 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
for (int i = 0; i < trays.size(); i++) for (int i = 0; i < trays.size(); i++)
{ {
//右上角 //右上角
if (trays[i].Center.x > reelCenter.x&&trays[i].Center.y < reelCenter.y) if ((int)trays[i].Center.x >= reelCenter.x && (int)trays[i].Center.y <= reelCenter.y)
{ {
if (trays[i].bSorted == false) if (trays[i].bSorted == false)
{ {
...@@ -6671,6 +6668,150 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char ...@@ -6671,6 +6668,150 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char
return FUNC_OK; return FUNC_OK;
} }
int eyemAchvMatchMat(EyemImage tpImage, EyemRect tpRoi, EyemImage *tpDstImg)
{
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
//转单通道
if (src.channels() != 1)
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
//跳过执行
if (killProcessID == 0) {
logger.t("eyemCountObjectIrregularPartsE 初始阶段被跳过执行...");
return FUNC_CANNOT_CALC;
}
//图像裁剪
src = src(cv::Rect(tpRoi.iXs, tpRoi.iYs, tpRoi.iWidth, tpRoi.iHeight)).clone();
//image size
int X = src.cols, Y = src.rows;
//去除局部量斑影响(默认亮斑尺寸不会大于15个像素)
cv::Mat srcTmp;
cv::morphologyEx(src, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
//去除黑斑影响
int m = cvRound(cv::mean(src)[0]);
srcTmp.forEach<uint16_t>([&](uint16_t& pixel, const int *pos)->void {
pixel = pixel == 0 ? m : pixel;
});
//图像增强
double min, max;
cv::Point maxId;
cv::minMaxLoc(srcTmp, &min, &max, NULL, &maxId);
src.convertTo(src, CV_64FC1);
src -= min;
src /= (max - min);
src *= 65535;
src.convertTo(src, CV_16UC1);
cv::Mat src8U;
src.convertTo(src8U, CV_8UC1, 1 / 255.);
//显示结果图像
cv::Mat cc;
cv::cvtColor(src8U, cc, cv::COLOR_GRAY2BGRA);
//设置bins
const int histSize = 17;
//range of values
float range[] = { 0,255 };
const float* histRange = { range };
//计算直方图
cv::Mat hist;
cv::calcHist(&src8U, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);
//计算背景
int maxIdx[2] = { 255,255 };
cv::minMaxIdx(hist, NULL, NULL, NULL, maxIdx);
//背景阈值
int backThresh = 15 * cvRound(((double)maxIdx[0] - 2));//正常-2
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void {
for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < X; x++) {
if (src8U.ptr<uint8_t>(y)[x] >= backThresh) {
src8U.ptr<uint8_t>(y)[x] = backThresh;
}
}
}
});
//方便显示
cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh));
//inv
cv::bitwise_not(src8U, src8U);
cv::Mat binary;
cv::threshold(src8U, binary, (255 - backThresh), 255, cv::THRESH_BINARY);
//连接在一起
cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(45, 45)));
//find the pallet
std::vector<std::vector<cv::Point>> contoursFilter;
cv::findContours(binary, contoursFilter, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
//填充内部确定料盘
cv::Mat image = cv::Mat::zeros(src8U.size(), CV_8UC1);
for (int i = 0; i < contoursFilter.size(); i++)
{
if (cv::contourArea(contoursFilter[i]) > 100000)
{
cv::drawContours(image, contoursFilter, i, cv::Scalar(255), -1);
}
}
cv::bitwise_not(src8U, src8U);
//剩下即料盘区域(面积大于100000均认为是料盘)
cv::findContours(image, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
//区分多个料盘
struct TrayPos
{
int iDir = -1;//0左上1左下2右下3右上
double dBackThresh;
bool bSorted;
cv::Point2f Center;
cv::Mat Tray;
TrayPos() {};
TrayPos(cv::Point2f center, cv::Mat tray, bool bSorted, double dBackThresh) :Center(center), Tray(tray), bSorted(bSorted), dBackThresh(dBackThresh) {}
};
std::vector <TrayPos> trays; std::vector<cv::Mat> matchMats;
for (int i = 0; i < contoursFilter.size(); i++)
{
//定位中心
cv::Moments mu = cv::moments(contoursFilter[i]);
cv::Point reelCenter(cvRound(mu.m10 / mu.m00), cvRound(mu.m01 / mu.m00));
//掩膜
cv::Mat trayMask = cv::Mat::zeros(Y, X, CV_8UC1);
cv::drawContours(trayMask, contoursFilter, i, cv::Scalar(255), -1);
//
cv::Mat tray = cv::Mat(Y, X, CV_8UC1, backThresh);
src8U.copyTo(tray, trayMask);
trays.push_back(TrayPos(reelCenter, tray, false, backThresh));
//获取局部图像
cv::Rect bbox = cv::boundingRect(contoursFilter[i]);
cv::Point pt(bbox.tl().x + bbox.width / 2, bbox.tl().y);
cv::Rect limit(cv::Point2i(pt.x - 112, pt.y), cv::Point2i(pt.x + 112, pt.y + 224));
matchMats.push_back(cc(limit).clone());
}
if (matchMats.empty()) {
return FUNC_CANNOT_CALC;
}
cv::Mat matchMat;
cv::cvtColor(matchMats[0], matchMat, cv::COLOR_BGRA2BGR);
//<输出结果图像
tpDstImg->iWidth = matchMat.cols; tpDstImg->iHeight = matchMat.rows; tpDstImg->iDepth = matchMat.depth(); tpDstImg->iChannels = matchMat.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, matchMat.data, _Size);
return FUNC_OK;
}
int eyemAchvTemplateImage(EyemImage tpImage, EyemRect tpRoi, 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).clone(); cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
...@@ -7282,49 +7423,93 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7282,49 +7423,93 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
cv::cvtColor(image, image, cv::COLOR_GRAY2BGR); cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
} }
//画图 //滤波
cv::blur(image, image, cv::Size(5, 5));
//用于显示
cv::Mat cc = image.clone(); cv::Mat cc = image.clone();
//转hsv空间
cv::Mat imgGray; cv::Mat imgGray;
cv::cvtColor(image, imgGray, cv::COLOR_BGR2HSV); cv::cvtColor(image, imgGray, cv::COLOR_BGR2HSV);
//红色比较特殊,分两个区间
cv::Mat mask1, mask2; cv::Mat mask1, mask2;
cv::inRange(imgGray, cv::Scalar(0, 50, 20), cv::Scalar(5, 255, 255), mask1); cv::inRange(imgGray, cv::Scalar(0, 43, 46), cv::Scalar(10, 255, 255), mask1);
cv::inRange(imgGray, cv::Scalar(175, 50, 20), cv::Scalar(180, 255, 255), mask2); cv::inRange(imgGray, cv::Scalar(156, 43, 46), cv::Scalar(180, 255, 255), mask2);
cv::Mat maskj, imageR; cv::Mat maskj, imageR;
cv::bitwise_or(mask1, mask2, maskj); cv::bitwise_or(mask1, mask2, maskj);
//膨胀部分区域 //去掉干扰
cv::bitwise_and(image, image, imageR, maskj); cv::morphologyEx(maskj, maskj, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
image = imageR;
//归一化 //测试用,局部用RBG分割
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void { cv::Mat labels, stats, centroids;
for (int y = range.start; y < range.end; y++) { int nccomps = cv::connectedComponentsWithStats(maskj, labels, stats, centroids);
for (int x = 0; x < X; x++) { //过滤连通域面积及长/宽比例不符合的,允许50%误差
uint8_t b, g, r; std::vector<uchar> colors(nccomps + 1, 0);
float bgr = (float)(image.ptr<cv::Vec3b>(y)[x][0] + image.ptr<cv::Vec3b>(y)[x][1] + image.ptr<cv::Vec3b>(y)[x][2]); for (int i = 1; i < nccomps; i++) {
bgr = bgr == 0 ? 1 : 1.0f / bgr; colors[i] = 255;
b = cvRound(255.0f*(float)image.ptr<cv::Vec3b>(y)[x][0] * bgr); double minSize = cv::min(stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]); double dRate = (double)stats.ptr<int>(i)[cv::CC_STAT_WIDTH] / (double)stats.ptr<int>(i)[cv::CC_STAT_HEIGHT];
g = cvRound(255.0f*(float)image.ptr<cv::Vec3b>(y)[x][1] * bgr); if (minSize < 20 || !(dRate > 0.75&&dRate < 1.25))
r = cvRound(255.0f*(float)image.ptr<cv::Vec3b>(y)[x][2] * bgr); {
image.ptr<cv::Vec3b>(y)[x] = cv::Vec3b(b, g, r); colors[i] = 0;
}
}
//过滤
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range& range)->void {
for (int y = range.start; y < range.end; y++)
{
uint8_t *ptrRow = maskj.ptr<uint8_t>(y);
for (int x = 0; x < X; x++)
{
int label = labels.ptr<int>(y)[x];
CV_Assert(0 <= label && label <= nccomps);
ptrRow[x] = colors[label];
} }
} }
}); });
//针对区域再进行过滤
std::vector<std::vector<cv::Point>> contours, contourFilter;
cv::findContours(maskj, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
for (auto&contour : contours) {
cv::Rect bbox = cv::boundingRect(contour);
int minSize = cv::min(bbox.height, bbox.width);
cv::Rect limRec = cv::Rect(cv::Point2i(bbox.tl().x - minSize, bbox.tl().y - minSize),
cv::Point2i(bbox.br().x + minSize, bbox.br().y + minSize))&cv::Rect(0, 0, X, Y);
//通道分离 cv::Mat limit = image(limRec).clone();
cv::Mat mask;
std::vector<cv::Mat> mv;
cv::split(image, mv);
cv::threshold(mv[2], mask, dThreshold, 255, cv::THRESH_BINARY);
//去掉干扰 //转hsv空间
cv::morphologyEx(mask, mask, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3))); //cv::cvtColor(limit, limit, cv::COLOR_BGR2HSV);
/*cv::Mat mask1, mask2;
cv::inRange(limit, cv::Scalar(0, 43, 46), cv::Scalar(10, 255, 255), mask1);
cv::inRange(limit, cv::Scalar(156, 43, 46), cv::Scalar(180, 255, 255), mask2);
cv::Mat maskj, imageR;
cv::bitwise_or(mask1, mask2, maskj);
std::vector<std::vector<cv::Point>> _contours;
cv::findContours(maskj, _contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, limRec.tl());*/
std::vector<std::vector<cv::Point>> contours, contourfilter; //过滤
cv::findContours(mask, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); std::vector<cv::Point> approx;
float arcL = (float)cv::arcLength(cv::Mat(contour), true);
cv::approxPolyDP(cv::Mat(contour), approx, arcL*0.01, true);
if (approx.size() > 5) {
cv::Rect bbox = cv::boundingRect(contour);
if (MIN(bbox.width, bbox.height) > 18 && ((float)bbox.width / (float)bbox.height) > 0.75 && \
((float)bbox.width / (float)bbox.height) < 1.25) {
//圆度
double afa = 4.0f*CV_PI*cv::contourArea(contour, false) / std::pow(arcL, 2);
if (afa > 0.45) {
contourFilter.push_back(contour);
}
}
}
}
struct AFA { struct AFA {
double dMatchDeg; double dMatchDeg;
...@@ -7343,28 +7528,15 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7343,28 +7528,15 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
} }
}; };
if (contourFilter.empty()) {
return FUNC_FAILED_DETECT;
}
bool typeCircle = true; bool typeCircle = true;
if (typeCircle) { if (typeCircle) {
//过滤 std::vector<AFA> AFAs;
std::vector<cv::Point> approx;
for (auto&contour : contours) {
float arcL = (float)cv::arcLength(cv::Mat(contour), true);
cv::approxPolyDP(cv::Mat(contour), approx, arcL*0.01, true);
if (approx.size() > 10) {
cv::Rect bbox = cv::boundingRect(contour);
if (MIN(bbox.width, bbox.height) > 20 && ((float)bbox.width / (float)bbox.height) > 0.75 && \
((float)bbox.width / (float)bbox.height) < 1.25) {
//圆度
double afa = 4.0f*CV_PI*cv::contourArea(contour, false) / std::pow(arcL, 2);
if (afa > 0.45) {
contourfilter.push_back(contour);
}
}
}
}
std::vector<AFA> afas;
//画图 //画图
for (auto&contour : contourfilter) { for (auto&contour : contourFilter) {
std::vector<EyemOcsDXY> taPoints; std::vector<EyemOcsDXY> taPoints;
for (int n = 0; n < contour.size(); n++) { for (int n = 0; n < contour.size(); n++) {
EyemOcsDXY taPoint; EyemOcsDXY taPoint;
...@@ -7375,18 +7547,41 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7375,18 +7547,41 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
double min_err; double min_err;
EyemOcsDXYR _tpCircle; EyemOcsDXYR _tpCircle;
eyemFitCircle((int)taPoints.size(), &taPoints[0], 10, min_err, _tpCircle); eyemFitCircle((int)taPoints.size(), &taPoints[0], 10, min_err, _tpCircle);
afas.push_back(AFA(min_err, _tpCircle)); AFAs.push_back(AFA(min_err, _tpCircle));
} }
if (AFAs.empty()) {
if (afas.empty()) {
return FUNC_FAILED_DETECT; return FUNC_FAILED_DETECT;
} }
//排序 //排序
std::sort(afas.begin(), afas.end(), std::less<AFA>()); std::sort(AFAs.begin(), AFAs.end(), std::less<AFA>());
//输出 //高精度定位
tpCircle->fX = (float)afas[0].tpCircle.dX; if (bHighAccuracy) {
tpCircle->fY = (float)afas[0].tpCircle.dY; EyemOcsDXY tpPoint; IntPtr hObject;
tpCircle->fR = (float)afas[0].tpCircle.dR; tpPoint.dX = AFAs[0].tpCircle.dX; tpPoint.dY = AFAs[0].tpCircle.dY;
//提取图像
std::vector<cv::Mat> mvx;
cv::split(cc, mvx);
EyemImage imageRed; imageRed.iWidth = cc.cols; imageRed.iHeight = cc.rows; imageRed.iDepth = cc.depth(); imageRed.iChannels = 1; imageRed.vpImage = mvx[2].data;
eyemEdge1dFindCircle(imageRed, tpPoint, 13, 4, 2, 19, 2, 1, 35, "positive", &hObject);
//拟合
std::vector<EyemOcsDXY> *tpResults = reinterpret_cast<std::vector<EyemOcsDXY>*>(hObject);
double rms; EyemOcsDXYR _tpCircle;
eyemFitCircle((int)tpResults->size(), tpResults->data(), 5, rms, _tpCircle);
//输出
tpCircle->fX = (float)_tpCircle.dX;
tpCircle->fY = (float)_tpCircle.dY;
tpCircle->fR = (float)_tpCircle.dR;
//释放
eyemEdge1dGenMeasureFree(hObject);
}
else {
//输出
tpCircle->fX = (float)AFAs[0].tpCircle.dX;
tpCircle->fY = (float)AFAs[0].tpCircle.dY;
tpCircle->fR = (float)AFAs[0].tpCircle.dR;
}
//画图 //画图
cv::rectangle(cc, cv::Rect(cv::Point2f(tpCircle->fX - 2.0f*tpCircle->fR, tpCircle->fY - 2.0f*tpCircle->fR), cv::rectangle(cc, cv::Rect(cv::Point2f(tpCircle->fX - 2.0f*tpCircle->fR, tpCircle->fY - 2.0f*tpCircle->fR),
cv::Point2f(tpCircle->fX + 2.0f*tpCircle->fR, tpCircle->fY + 2.0f*tpCircle->fR)), cv::Scalar(0, 255, 255), 4); cv::Point2f(tpCircle->fX + 2.0f*tpCircle->fR, tpCircle->fY + 2.0f*tpCircle->fR)), cv::Scalar(0, 255, 255), 4);
...@@ -7424,19 +7619,15 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7424,19 +7619,15 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
} }
//<输出结果图像 //<输出结果图像
tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels(); tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
//内存尺寸 //内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t); int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
//分配初始化内存 //分配初始化内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size); tpDstImg->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImg->vpImage) if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM; return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size); memset(tpDstImg->vpImage, 0, _Size);
//拷贝数据 //拷贝数据
memcpy(tpDstImg->vpImage, cc.data, _Size); memcpy(tpDstImg->vpImage, cc.data, _Size);
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "eyemLib.h" #include "eyemLib.h"
#include <tbb\tbb.h> #include <tbb\tbb.h>
constexpr double c = PI / 180.; constexpr double c = PI / 180.;
extern Logger logger; extern Logger logger;
......
此文件类型无法预览
#pragma once
#ifndef __RESNET_LIB_H
#define __RESNET_LIB_H
#ifdef __DLLEXPORT
#define __DLL_EXP _declspec(dllexport) // 导出函数 - 生成dll文件时使用
#else
#define __DLL_EXP _declspec(dllimport) // 导入函数 -使用dll时使用
#endif // __DLLEXPORT
#include "ncnn/net.h"
#include "opencv2/opencv.hpp"
#include <vector>
#include <iostream>
#include<fstream>
#include <sstream>
#include <string>
#include <windows.h>
//typedef struct {
// void* vpImage; // 地址
// int iWidth; // 图像内存 x 方向大小
// int iHeight; // 图像内存 y 方向大小
// int iDepth; // 图像位深度(参见说明)
// int iChannels; // 图像通道数
//} EyemImage;
#ifndef MAKETYPE
#define MAKETYPE CV_MAKETYPE
#endif
//// 一般定义
//#define FUNC_OK 0 // 正常
//#define FUNC_NOT_ENOUGH_MEM -1 // 工作内存不足
//#define FUNC_ILLEGAL_ARGUMENT -2 // 参数不合适
//#define FUNC_IMAGE_NOT_EXIST -3 // 图像不存在
//#define FUNC_CANNOT_CALC -100 // 不可计算
//#define FUNC_CANNOT_USE -999 // 不可用
#ifdef __cplusplus
extern "C" {
#endif
__DLL_EXP void match_feature(const char* input_path, EyemImage image, char* part_number);
__DLL_EXP void enroll_feature(const char* input_path, const char* output_path);
#ifdef __cplusplus
}
#endif
#endif
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!