Commit e9d5142d 张士柳

1 个父辈 29630f64
......@@ -10,9 +10,358 @@ using System.IO;
namespace eyemLib_Sharp
{
public unsafe class EyemLib
#region 结构体
// 图像信息
[StructLayout(LayoutKind.Sequential)]
public struct EyemImage
{
public IntPtr vpImage; // 地址
public int iWidth; // 图像内存 x 方向大小
public int iHeight; // 图像内存 y 方向大小
public int iDepth; // 图像位深度(详见说明)
public int iChannels; // 图像通道数
public static implicit operator EyemImage(UnmanagedBitmap v)
{
return v.Image;
}
}
// 矩形定义
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iWidth; // x 方向大小(宽度)
public int iHeight; // y 方向大小(高度)
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect2
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iXe; // 端点(右下) x 坐标
public int iYe; // 端点(右下) y 坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect3
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iWidth; // x 方向大小(宽度)
public int iHeight; // y 方向大小(高度)
public double dVar; // 某种可能会使用的值
}
[StructLayout(LayoutKind.Sequential)]
public struct BboxContainer
{
//最多支持100个目标
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public EyemRect[] bboxes;
}
///////////////////////////////////////////////////////////////////////////////
// Orthogonal Coordinate System
/////////////////////
// int type
//
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXY
{
public int iX; // X坐标
public int iY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYZ
{
public int iX; // X坐标
public int iY; // Y坐标
public int iZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYQ
{
public int iX; // X坐标
public int iY; // Y坐标
public int iQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYR // 用于表示圆
{
public int iX; // X坐标
public int iY; // Y坐标
public int iR; // 半径
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIABC // 用于表示直线(一般形式)
{
public int iA; // a
public int iB; // b
public int iC; // c
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIRQ // 用于表示直线(黑森标准形式)或矢量
{
public int iR; // ρ
public int iQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYQS
{
public int iX; // X坐标(单位:像素)
public int iY; // Y坐标(单位:像素)
public int iQ; // 斜率(単位:rad)
public int iS; // 刻度
}
/////////////////////
// float type
//
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXY
{
public float fX; // X坐标
public float fY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYZ
{
public float fX; // X坐标
public float fY; // Y坐标
public float fZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYQ
{
public float fX; // X坐标
public float fY; // Y坐标
public float fQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYR // 用于表示圆
{
public float fX; // X坐标
public float fY; // Y坐标
public float fR; // 半径
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFABC // 用于表示直线(一般形式)
{
public float fA; // a
public float fB; // b
public float fC; // c
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFRQ // 用于表示直线(黑森标准形式)或矢量
{
public float fR; // ρ
public float fQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYQS
{
public float fX; // X坐标(単位:像素)
public float fY; // Y坐标(単位:像素)
public float fQ; // 斜率(単位:rad)
public float fS; // 刻度
}
/////////////////////
// double type
//
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXY
{
public double dX; // X坐标
public double dY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYZ
{
public double dX; // X坐标
public double dY; // Y坐标
public double dZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYQ
{
public double dX; // X坐标
public double dY; // Y坐标
public double dQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYR // 用于表示圆
{
public double dX; // 中心的X坐标
public double dY; // 中心的Y坐标
public double dR; // 半径
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDABC // 直线(一般形)的表现形式
{
public double dA; // a
public double dB; // b
public double dC; // c
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDRQ // 用于表示直线(黑森标准形状)和矢量
{
public double dR; // ρ
public double dQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYQS
{
public double dX; // X坐标
public double dY; // Y坐标
public double dQ; // 旋转角度(単位:rad)
public double dS; // 规模
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDABCD // 用于表示平面(一般形式)
{
public double dA; // a
public double dB; // b
public double dC; // c
public double dD; // d
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYLSQ // 用于表示椭圆
{
public double dXo; // 中心X坐标
public double dYo; // 中心Y坐标
public double dL; // 长轴半径
public double dS; // 短轴半径
public double dQ; // 长轴倾斜角(単位:rad)
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDPV // 用于表示三维空间中的直线
{
public EyemOcsDXYZ tP; // 直线上一点的坐标
public EyemOcsDXYZ tV; // 直线方向矢量
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDCRUVW // 用于表示椭圆体
{
public EyemOcsDXYZ tC; // 椭圆体中心
public EyemOcsDXYZ tR; // 轴半径(dX:长轴、dY:中轴、dZ:短轴)
public double dU; // 长轴投影到 XY 平面与 X 轴的角(单位:rad)
public double dV; // 长轴与XY平面之角(单位:rad)
public double dW; // 绕长轴旋转角度(单位:rad)
}
// Blob 分析结果
[StructLayout(LayoutKind.Sequential)]
public struct EyemBinBlob
{
public int iLabel; // 标签
public int iArea; // 面积
public double dCenterX; // 重心x坐标
public double dCenterY; // 重心y坐标
public int iXs, iYs, iXe, iYe; // 外接矩形(始点,终点)
public int iWidth, iHeight; // 外接矩形(x 方向大小(宽度),y 方向大小(高度))
public double dTheta; // 主轴倾斜角(rad)
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemChainCode
{
public int iLabel; // 标签
public double dX; // x坐标
public double dY; // y坐标
public double dVx, dVy; // 向量
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemBlobParams
{
public bool filterByArea; //斑点大小限制
public int minArea, maxArea; //最小面积/最大面积
public bool filterByCircularity; //斑点圆度限制
public float minCircularity, maxCircularity; //圆度最小/大限制
public bool filterByInertia; //斑点的惯性率限制
public float minInertiaRatio, maxInertiaRatio; //惯性率最小/大限制
public bool filterByConvexity; //斑点凸度限制
public float minConvexity, maxConvexity; //凸度最小/大限制
}
// 条码 解码结果
[StructLayout(LayoutKind.Sequential)]
public struct EyemBarCode
{
public double dAngle; // 角度
public int iCenterX; // x坐标
public int iCenterY; // y坐标
public IntPtr hType; // 码类型
public IntPtr hText; // 码内容
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemModelID
{
public IntPtr vpImage; // 地址
public int iXs; // 图像X坐标
public int iYs; // 图像Y坐标
public int iWidth; // 图像内存X方向大小
public int iHeight; // 图像内存Y方向大小
public double dMatchDeg; // 匹配度
public IntPtr lpszName; // 名称
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemRigidMatrix
{
public double a00; // a00
public double a01; // a01
public double b00; // b00
public double a10; // a10
public double a11; // a11
public double b10; // b10
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemHSVModel
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] dpRangeL, dpRangeU; // 提取下限,提取上限[H S V]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] dpRangeLExt, dpRangeUExt; // 额外提取下限,额外提取上限(针对处于跨模型颜色,比如红色)[H S V]
}// 用于HSV颜色模型分割(H(0-180)、S(0-255)、V(0-255))
#endregion
public unsafe class EyemLib
{
#region 枚举
//稳健估计方法
......@@ -95,339 +444,6 @@ namespace eyemLib_Sharp
#endregion
#region 结构体
// 图像信息
[StructLayout(LayoutKind.Sequential)]
public struct EyemImage
{
public IntPtr vpImage; // 地址
public int iWidth; // 图像内存 x 方向大小
public int iHeight; // 图像内存 y 方向大小
public int iDepth; // 图像位深度(详见说明)
public int iChannels; // 图像通道数
}
// 矩形定义
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iWidth; // x 方向大小(宽度)
public int iHeight; // y 方向大小(高度)
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect2
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iXe; // 端点(右下) x 坐标
public int iYe; // 端点(右下) y 坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemRect3
{
public int iXs; // 起始点(左上角) x 坐标
public int iYs; // 起始点(左上角) y 坐标
public int iWidth; // x 方向大小(宽度)
public int iHeight; // y 方向大小(高度)
public double dVar; // 某种可能会使用的值
}
[StructLayout(LayoutKind.Sequential)]
public struct BboxContainer
{
//最多支持100个目标
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public EyemRect[] bboxes;
}
///////////////////////////////////////////////////////////////////////////////
// Orthogonal Coordinate System
/////////////////////
// int type
//
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXY
{
public int iX; // X坐标
public int iY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYZ
{
public int iX; // X坐标
public int iY; // Y坐标
public int iZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYQ
{
public int iX; // X坐标
public int iY; // Y坐标
public int iQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYR // 用于表示圆
{
public int iX; // X坐标
public int iY; // Y坐标
public int iR; // 半径
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIABC // 用于表示直线(一般形式)
{
public int iA; // a
public int iB; // b
public int iC; // c
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIRQ // 用于表示直线(黑森标准形式)或矢量
{
public int iR; // ρ
public int iQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYQS
{
public int iX; // X坐标(单位:像素)
public int iY; // Y坐标(单位:像素)
public int iQ; // 斜率(単位:rad)
public int iS; // 刻度
}
/////////////////////
// float type
//
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXY
{
public float fX; // X坐标
public float fY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYZ
{
public float fX; // X坐标
public float fY; // Y坐标
public float fZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYQ
{
public float fX; // X坐标
public float fY; // Y坐标
public float fQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYR // 用于表示圆
{
public float fX; // X坐标
public float fY; // Y坐标
public float fR; // 半径
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFABC // 用于表示直线(一般形式)
{
public float fA; // a
public float fB; // b
public float fC; // c
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFRQ // 用于表示直线(黑森标准形式)或矢量
{
public float fR; // ρ
public float fQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYQS
{
public float fX; // X坐标(単位:像素)
public float fY; // Y坐标(単位:像素)
public float fQ; // 斜率(単位:rad)
public float fS; // 刻度
}
/////////////////////
// double type
//
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXY
{
public double dX; // X坐标
public double dY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYZ
{
public double dX; // X坐标
public double dY; // Y坐标
public double dZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYQ
{
public double dX; // X坐标
public double dY; // Y坐标
public double dQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYR // 用于表示圆
{
public double dX; // 中心的X坐标
public double dY; // 中心的Y坐标
public double dR; // 半径
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDABC // 直线(一般形)的表现形式
{
public double dA; // a
public double dB; // b
public double dC; // c
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDRQ // 用于表示直线(黑森标准形状)和矢量
{
public double dR; // ρ
public double dQ; // θ
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYQS
{
public double dX; // X坐标
public double dY; // Y坐标
public double dQ; // 旋转角度(単位:rad)
public double dS; // 规模
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDABCD // 用于表示平面(一般形式)
{
public double dA; // a
public double dB; // b
public double dC; // c
public double dD; // d
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYLSQ // 用于表示椭圆
{
public double dXo; // 中心X坐标
public double dYo; // 中心Y坐标
public double dL; // 长轴半径
public double dS; // 短轴半径
public double dQ; // 长轴倾斜角(単位:rad)
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDPV // 用于表示三维空间中的直线
{
public EyemOcsDXYZ tP; // 直线上一点的坐标
public EyemOcsDXYZ tV; // 直线方向矢量
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDCRUVW // 用于表示椭圆体
{
public EyemOcsDXYZ tC; // 椭圆体中心
public EyemOcsDXYZ tR; // 轴半径(dX:长轴、dY:中轴、dZ:短轴)
public double dU; // 长轴投影到 XY 平面与 X 轴的角(单位:rad)
public double dV; // 长轴与XY平面之角(单位:rad)
public double dW; // 绕长轴旋转角度(单位:rad)
}
// Blob 分析结果
[StructLayout(LayoutKind.Sequential)]
public struct EyemBinBlob
{
public int iLabel; // 标签
public int iArea; // 面积
public double dCenterX; // 重心x坐标
public double dCenterY; // 重心y坐标
public int iXs, iYs, iXe, iYe; // 外接矩形(始点,终点)
public int iWidth, iHeight; // 外接矩形(x 方向大小(宽度),y 方向大小(高度))
public double dTheta; // 主轴倾斜角(rad)
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemChainCode
{
public int iLabel; // 标签
public double dX; // x坐标
public double dY; // y坐标
public double dVx, dVy; // 向量
}
// 条码 解码结果
[StructLayout(LayoutKind.Sequential)]
public struct EyemBarCode
{
public double dAngle; // 角度
public int iCenterX; // x坐标
public int iCenterY; // y坐标
public IntPtr hType; // 码类型
public IntPtr hText; // 码内容
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemModelID
{
public IntPtr vpImage; // 地址
public int iXs; // 图像X坐标
public int iYs; // 图像Y坐标
public int iWidth; // 图像内存X方向大小
public int iHeight; // 图像内存Y方向大小
public double dMatchDeg; // 匹配度
public IntPtr lpszName; // 名称
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemRigidMatrix
{
public double a00; // a00
public double a01; // a01
public double b00; // b00
public double a10; // a10
public double a11; // a11
public double b10; // b10
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemHSVModel
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] dpRangeL, dpRangeU; // 提取下限,提取上限[H S V]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public double[] dpRangeLExt, dpRangeUExt; // 额外提取下限,额外提取上限(针对处于跨模型颜色,比如红色)[H S V]
}// 用于HSV颜色模型分割(H(0-180)、S(0-255)、V(0-255))
#endregion
#region 通用
/// <summary>
......@@ -593,7 +609,7 @@ namespace eyemLib_Sharp
/// <param name="tpDstImage">结果图像</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemBinBlob(EyemImage tpImage, out BlobHandle hObject, int iAreaThrs, out EyemBinBlob* tpResult, out int ipNum, out EyemImage tpDstImage);
private static extern int eyemBinBlob(EyemImage tpImage, out BlobHandle hObject, EyemBlobParams tpParams, out EyemBinBlob* tpResult, out int ipNum, out EyemImage tpDstImage);
/// <summary>
/// 释放Blob资源
/// </summary>
......@@ -1065,7 +1081,7 @@ namespace eyemLib_Sharp
#region 测试专用接口
//测试接口
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemLibImpl(EyemImage tpImage, EyemHSVModel tpHSVModel, out EyemImage tpDstImg);
private static extern int eyemLibImpl(EyemImage tpImage, out EyemImage tpDstImg);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemEdge1dRidgeDetection(EyemImage tpImage);
......@@ -1132,6 +1148,9 @@ namespace eyemLib_Sharp
sw.Restart();
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//UnmanagedBitmap umBitmap = new UnmanagedBitmap("D:\\算法测试图像\\circle_plate_04.png");
//return;
//flag = eyemInitNNDataCodeModel(".\\darknet\\detect-tiny.cfg", ".\\darknet\\detect-tiny.weights", "", "") & eyemInitNNDetector(".\\darknet\\detect-tiny-label.cfg", ".\\darknet\\detect-tiny-label.weights");
////红色分割
......@@ -1149,36 +1168,36 @@ namespace eyemLib_Sharp
//tpHsvModel.dpRangeL = new double[] { 100, 43, 46 }; tpHsvModel.dpRangeU = new double[] { 124, 255, 255 };
//tpHsvModel.dpRangeLExt = new double[] { 0, 0, 0 }; tpHsvModel.dpRangeUExt = new double[] { 0, 0, 0 };
//flag = eyemLibImpl(image, tpHsvModel, out tpDstImg);
//flag = eyemLibImpl(image, out tpDstImg);
EyemImage templ, search;
flag = eyemImageRead("D://批量测试图像//template.png", -1, out templ);
if (flag != 0)
{
Console.WriteLine("读图失败!");
return;
}
//EyemImage templ, search;
//flag = eyemImageRead("D://批量测试图像//template.png", -1, out templ);
//if (flag != 0)
//{
// Console.WriteLine("读图失败!");
// return;
//}
flag = eyemImageRead("D://批量测试图像//search1.png", -1, out search);
if (flag != 0)
{
Console.WriteLine("读图失败!");
return;
}
//flag = eyemImageRead("D://批量测试图像//search1.png", -1, out search);
//if (flag != 0)
//{
// Console.WriteLine("读图失败!");
// return;
//}
flag = eyemMakeShapeModel(templ, 100, 10);
//flag = eyemMakeShapeModel(templ, 100, 10);
flag = eyemFindShapeModel(search, 10, 0, 90, 1, 10, 100, 0.9, 0.9);
//flag = eyemFindShapeModel(search, 10, 0, 90, 1, 10, 100, 0.9, 0.9);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
sw.Stop();
Console.WriteLine("时间花费" + sw.ElapsedMilliseconds.ToString());
eyemImageFree(ref templ);
eyemImageFree(ref search);
return;
//sw.Stop();
//Console.WriteLine("时间花费" + sw.ElapsedMilliseconds.ToString());
//eyemImageFree(ref templ);
//eyemImageFree(ref search);
//return;
//flag = eyemNormalize(ref image);
......@@ -1190,13 +1209,10 @@ namespace eyemLib_Sharp
//EyemOcsFXYR tpCircle = new EyemOcsFXYR();
//flag = eyemMarkerTracing(image, tpHsvModel, ref tpCircle, out tpDstImg, false);
//eyemImageFree(ref tpDstImg);
//sw.Stop();
//Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString());
//flag = eyemEdge1dRidgeDetection(image);
//flag = eyemShockFilter(image, 9, 1.5, 0.5, 10, out tpDstImg);
//flag = eyemNonLocalMeansFilter(image, 7, 21, 3.0, -1);
......@@ -1209,26 +1225,31 @@ namespace eyemLib_Sharp
//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);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//hObject.Dispose();
//eyemImageFree(ref tpDstImg);
//eyemImageFree(ref image);
//Console.WriteLine("时间-:" + sw.ElapsedMilliseconds.ToString());
//return;
sw.Restart();
EyemBlobParams tpParams = new EyemBlobParams();
tpParams.filterByArea = true; tpParams.minArea = 25; tpParams.maxArea = int.MaxValue;
tpParams.filterByCircularity = false; tpParams.minCircularity = 0.8F; tpParams.maxCircularity = float.MaxValue;
tpParams.filterByConvexity = false; tpParams.minConvexity = 0.95F; tpParams.maxConvexity = float.MaxValue;
tpParams.filterByInertia = false; tpParams.minInertiaRatio = 0.8F; tpParams.maxInertiaRatio = float.MaxValue;
int ipNum;
BlobHandle hObject;
EyemBinBlob* tpResults;
eyemBinBlob(image, out hObject, tpParams, out tpResults, out ipNum, out tpDstImg);
sw.Stop();
for (int i = 0; i < ipNum; i++)
{
Console.WriteLine(tpResults[i].iArea);
}
Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null)
{
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
}
hObject.Dispose();
eyemImageFree(ref tpDstImg);
eyemImageFree(ref image);
Console.WriteLine("时间-:" + sw.ElapsedMilliseconds.ToString());
return;
#endregion
#region Test 1DEdge
......@@ -1428,7 +1449,6 @@ namespace eyemLib_Sharp
//tpModeImg.iWidth = tpModelID.iWidth; tpModeImg.iHeight = tpModelID.iHeight; tpModeImg.vpImage = tpModelID.vpImage;
//Bitmap bitmap = eyemCvtToBitmap(tpModeImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
......@@ -1439,7 +1459,7 @@ namespace eyemLib_Sharp
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_LOWCONTRAST_PARTS",IP_SQUARE_PARTS
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_SMALL_PARTS", ipReelNum, out tpDstImg);
eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_LARGE_PARTS", ipReelNum, out tpDstImg);
//eyemCountObjectE(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + "20210825095751-1.tpl", hModelID, ipReelNum, out tpDstImg);
......@@ -1449,7 +1469,6 @@ namespace eyemLib_Sharp
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// //bitmap.Save("D:\\ResOut\\" + file);
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
......@@ -1473,7 +1492,6 @@ namespace eyemLib_Sharp
}
sw.Stop();
Console.WriteLine(file + "--->" + "耗时:" + sw.ElapsedMilliseconds.ToString() + "ms" + ",结果:" + strReelNum);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
......
......@@ -21,7 +21,6 @@ namespace eyemLib_Sharp
foreach (var item in fileNames)
{
EyemLib.eyemReadImageTool(item);
break;
}
EyemLib.Free();
Console.Write("请按任意键继续。。。");
......
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace eyemLib_Sharp
{
public unsafe class UnmanagedBitmap : IDisposable
{
#region 接口
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage tpImage);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern void eyemImageFree(ref EyemImage tpImage);
#endregion
private EyemImage image;
public EyemImage Image
{
get { return image; }
}
public UnmanagedBitmap()
{
image = new EyemImage();
}
public UnmanagedBitmap(string fileName)
{
eyemImageRead(fileName, -1, out image);
}
public UnmanagedBitmap(Bitmap bitmap)
{
mustbeDispose = true;
image = eyemCvtToEyemImage(bitmap);
}
private bool mustbeDispose = false;
~UnmanagedBitmap()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// dispose managed resources
}
if (mustbeDispose)
{
image.iChannels = image.iDepth = image.iHeight = image.iWidth = 0;
Marshal.FreeHGlobal(image.vpImage);
image.vpImage = IntPtr.Zero;
}
else
{
eyemImageFree(ref image);
}
}
#region EyemImageBitmap相互转换
public static Bitmap eyemCvtToBitmap(EyemImage tpImage)
{
if (tpImage.vpImage == IntPtr.Zero || tpImage.iDepth != 0)
return null;
PixelFormat format;
switch (tpImage.iChannels)
{
case 1:
format = PixelFormat.Format8bppIndexed;
break;
case 3:
format = PixelFormat.Format24bppRgb;
break;
case 4:
format = PixelFormat.Format32bppArgb;
break;
default:
return null;
}
Bitmap bitmap = new Bitmap(tpImage.iWidth, tpImage.iHeight, format);
//对于输出灰度图像
if (format == PixelFormat.Format8bppIndexed)
{
ColorPalette palette = bitmap.Palette;
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
bitmap.Palette = palette;
}
//锁定数据区
BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, tpImage.iWidth, tpImage.iHeight),
ImageLockMode.WriteOnly, format);
try
{
int pd = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4;
long bytesToCopy = tpImage.iWidth * tpImage.iChannels;
for (int y = 0; y < tpImage.iHeight; y++)
{
long offsetSrc = (y * tpImage.iWidth * tpImage.iChannels);
long offsetDst = (y * pd);
Buffer.MemoryCopy((byte*)(tpImage.vpImage.ToPointer()) + offsetSrc, (byte*)(bd.Scan0.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy);
}
}
finally
{
bitmap.UnlockBits(bd);
}
return bitmap;
}
public static EyemImage eyemCvtToEyemImage(Bitmap bitmap)
{
EyemImage tpImage = new EyemImage();
//锁定数据区
BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, bitmap.PixelFormat);
switch (bitmap.PixelFormat)
{
case PixelFormat.Format8bppIndexed:
tpImage.iChannels = 1;
break;
case PixelFormat.Format24bppRgb:
tpImage.iChannels = 3;
break;
case PixelFormat.Format32bppArgb:
tpImage.iChannels = 4;
break;
default:
throw new Exception("Image formats are not supported");
}
//仅支持8位
tpImage.iDepth = 0;
//图像尺寸
tpImage.iWidth = bitmap.Width; tpImage.iHeight = bitmap.Height;
//分配内存(释放不是用eyemImageFree,用Marshal.FreeHGlobal(tpImage.vpImage))
tpImage.vpImage = Marshal.AllocHGlobal(bd.Stride * bd.Height);
try
{
int pd = ((tpImage.iWidth * tpImage.iChannels) + 3) / 4 * 4;
long bytesToCopy = tpImage.iWidth * tpImage.iChannels;
for (int y = 0; y < tpImage.iHeight; y++)
{
long offsetSrc = y * pd;
long offsetDst = y * tpImage.iWidth * tpImage.iChannels;
Buffer.MemoryCopy((byte*)(bd.Scan0.ToPointer()) + offsetSrc, (byte*)(tpImage.vpImage.ToPointer()) + offsetDst, bytesToCopy, bytesToCopy);
}
}
finally
{
bitmap.UnlockBits(bd);
}
return tpImage;
}
#endregion
}
}
......@@ -55,6 +55,7 @@
<Compile Include="log4cpp\LogManager.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UnmanagedBitmap.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
......
......@@ -1276,7 +1276,6 @@ int eyemBinThresholdC(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpD
//合并
cv::Mat maskj;
cv::bitwise_or(mask1, mask2, maskj);
//输出结果图像
if (NULL != tpDstImg->vpImage) {
tpDstImg->iWidth = tpDstImg->iHeight = tpDstImg->iDepth = tpDstImg->iChannels = 0;
......@@ -1284,21 +1283,16 @@ int eyemBinThresholdC(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpD
free(tpDstImg->vpImage);
tpDstImg->vpImage = NULL;
}
tpDstImg->iWidth = maskj.cols; tpDstImg->iHeight = maskj.rows; tpDstImg->iDepth = maskj.depth(); tpDstImg->iChannels = maskj.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, maskj.data, _Size);
return FUNC_OK;
}
......@@ -1323,7 +1317,7 @@ int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDst
return FUNC_OK;
}
int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg)
int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, EyemBlobParams tpParams, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg)
{
CV_Assert(tpImage.vpImage != NULL);
......@@ -1336,7 +1330,6 @@ int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob *
if (image.type() != CV_8UC1 || image.channels() != 1) {
return FUNC_CANNOT_CALC;
}
cv::threshold(image, image, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);
//显示图像
......@@ -1344,35 +1337,18 @@ int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob *
cv::cvtColor(image, showMat, cv::COLOR_GRAY2RGB);
//图像尺寸
const int X = image.cols, Y = image.rows;
//斑点大小限制
bool filterByArea = true;
int minArea = 25, maxArea = 25000;
//斑点圆度限制
bool filterByCircularity = false;
float minCircularity = 0.8f, maxCircularity = std::numeric_limits<float>::max();
//斑点的惯性率限制
bool filterByInertia = false;
float minInertiaRatio = 0.1f, maxInertiaRatio = std::numeric_limits<float>::max();
//斑点凸度限制
bool filterByConvexity = false;
float minConvexity = 0.8f, maxConvexity = std::numeric_limits<float>::max();
//斑点检测
cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(image, labels, stats, centroids);
std::vector<uchar> colors(nccomps + 1, 0);
//按面积过滤
if (filterByArea) {
if (tpParams.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)) {
if (!(dArea >= tpParams.minArea&&dArea <= tpParams.maxArea)) {
colors[i] = 0;
}
}
......@@ -1414,14 +1390,14 @@ int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob *
}
//按圆度过滤
if (filterByCircularity) {
if (tpParams.filterByCircularity) {
double perimeter = cv::arcLength(contour, true);
double ratio = 4 * CV_PI * moms.m00 / (perimeter * perimeter);
if (ratio < minCircularity || ratio >= maxCircularity)
if (ratio < tpParams.minCircularity || ratio >= tpParams.maxCircularity)
colors[label] = 0;
}
//按惯性率过滤
if (filterByInertia) {
if (tpParams.filterByInertia) {
double denominator = std::sqrt(std::pow(2 * moms.mu11, 2) + std::pow(moms.mu20 - moms.mu02, 2));
const double eps = 1e-2;
double ratio;
......@@ -1438,11 +1414,11 @@ int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob *
else {
ratio = 1;
}
if (ratio < minInertiaRatio || ratio >= maxInertiaRatio)
if (ratio < tpParams.minInertiaRatio || ratio >= tpParams.maxInertiaRatio)
colors[label] = 0;
}
//按凸度过滤
if (filterByConvexity) {
if (tpParams.filterByConvexity) {
std::vector <cv::Point> hull;
cv::convexHull(contour, hull);
double area = cv::contourArea(contour);
......@@ -1450,7 +1426,7 @@ int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob *
if (fabs(hullArea) < DBL_EPSILON)
colors[label] = 0;
double ratio = area / hullArea;
if (ratio < minConvexity || ratio >= maxConvexity)
if (ratio < tpParams.minConvexity || ratio >= tpParams.maxConvexity)
colors[label] = 0;
}
}
......@@ -1485,8 +1461,8 @@ int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob *
std::vector<EyemBinBlob> * tpResults = new std::vector<EyemBinBlob>();
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::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);
double x1, y1, x2, y2;
......
......@@ -26,147 +26,18 @@ void setSkipProcessID(int pid)
killProcessID = pid;
}
//void strip_args(char *s)
//{
// size_t i;
// size_t len = strlen(s);
// size_t offset = 0;
// for (i = 0; i < len; ++i) {
// char c = s[i];
// if (c == '\t' || c == '\n' || c == '\r' || c == 0x0d || c == 0x0a) ++offset;
// else s[i - offset] = c;
// }
// s[len - offset] = '\0';
//}
//extern void run_tester(int argc, char **argv);
//extern void run_count_object(int argc, char **argv);
//extern void run_count_object_irregular(int argc, char **argv);
//extern void run_count_object_(int argc, char **argv);
//extern void run_count_object_irregular_(int argc, char **argv);
//extern void run_detect_decode(int argc, char **argv);
//extern void run_detect_decode_usenn(int argc, char **argv);
Logger logger;
int main(int argc, char **argv)
{
//cv::ocl::Context ctx = cv::ocl::Context::getDefault();
//if (!ctx.ptr())
//{
// std::cout << "OpenCL is not available" << std::endl;
//}
//else {
// std::cout << "OpenCL is available" << std::endl;
//}
//std::cerr << " OpenCV version: " << CV_VERSION_MAJOR << "." << CV_VERSION_MINOR << "." << CVAUX_STR(CV_VERSION_REVISION)
// << std::endl;
//std::cerr << " EyemLib version: " << "4." << FILE_VER_GET_PREFETCHED << "." << FILE_VER_GET_NEUTRAL << "." << FILE_VER_GET_LOCALISED
// << std::endl;
//if (argc < 2) {
// fprintf(stderr, "usage: %s <function>\n", argv[0]);
// return 0;
//}
//int i;
//for (i = 0; i < argc; ++i) {
// if (!argv[i]) continue;
// strip_args(argv[i]);
//}
//if (0 == strcmp(argv[1], "func")) {
// run_tester(argc, argv);
//}
//else if (0 == strcmp(argv[1], "method")) {
//}
cv::ocl::Context ctx = cv::ocl::Context::getDefault();
if (!ctx.ptr())
{
std::cout << "OpenCL is not available" << std::endl;
}
else {
std::cout << "OpenCL is available" << std::endl;
}
std::cerr << " OpenCV version: " << CV_VERSION_MAJOR << "." << CV_VERSION_MINOR << "." << CVAUX_STR(CV_VERSION_REVISION)
<< std::endl;
return 0;
}
//void del_arg(int argc, char **argv, int index)
//{
// int i;
// for (i = index; i < argc - 1; ++i) argv[i] = argv[i + 1];
// argv[i] = 0;
//}
//
//int find_arg(int argc, char* argv[], char *arg)
//{
// int i;
// for (i = 0; i < argc; ++i) {
// if (!argv[i]) continue;
// if (0 == strcmp(argv[i], arg)) {
// del_arg(argc, argv, i);
// return 1;
// }
// }
// return 0;
//}
//void run_tester(int argc, char **argv)
//{
// char *func_name = argv[2];
// if (0 == strcmp(func_name, "count_object")) run_count_object(argc, argv);
// else if (0 == strcmp(func_name, "count_object_irregular")) run_count_object_irregular(argc, argv);
// else if (0 == strcmp(func_name, "count_object_")) run_count_object_(argc, argv);
// else if (0 == strcmp(func_name, "count_object_irregular_")) run_count_object_irregular_(argc, argv);
// else if (0 == strcmp(func_name, "detect_decode")) run_detect_decode(argc, argv);
// else if (0 == strcmp(func_name, "detect_decode_usenn")) run_detect_decode_usenn(argc, argv);
// else printf(" There isn't such command: %s", argv[2]);
//}
//
//void run_count_object(int argc, char **argv) {
// std::string filename(argv[2]);
// cv::Mat src = cv::imread(filename, -1);
// if (src.empty()) {
// printf("file does not exist");
// return;
// }
//}
//
//void run_count_object_irregular(int argc, char **argv) {
// std::string filename(argv[2]);
// cv::Mat src = cv::imread(filename, -1);
// if (src.empty()) {
// printf("file does not exist");
// return;
// }
//}
//
//void run_count_object_(int argc, char **argv) {
// std::string filename(argv[2]);
// cv::Mat src = cv::imread(filename, -1);
// if (src.empty()) {
// printf("file does not exist");
// return;
// }
//}
//
//void run_count_object_irregular_(int argc, char **argv) {
// std::string filename(argv[2]);
// cv::Mat src = cv::imread(filename, -1);
// if (src.empty()) {
// printf("file does not exist");
// return;
// }
//}
//
//void run_detect_decode(int argc, char **argv) {
// std::string filename(argv[2]);
// cv::Mat src = cv::imread(filename, -1);
// if (src.empty()) {
// printf("file does not exist");
// return;
// }
//}
//
//void run_detect_decode_usenn(int argc, char **argv) {
// std::string filename(argv[2]);
// cv::Mat src = cv::imread(filename, -1);
// if (src.empty()) {
// printf("file does not exist");
// return;
// }
//}
\ No newline at end of file
......@@ -638,6 +638,17 @@ typedef struct {
double dVx, dVy; // 向量
} EyemChainCode;
typedef struct {
bool filterByArea = true; //斑点大小限制
int minArea = 25, maxArea = std::numeric_limits<int>::max();//最小面积/最大面积
bool filterByCircularity = false; //斑点圆度限制
float minCircularity = 0.8f, maxCircularity = std::numeric_limits<float>::max();//圆度最小/大限制
bool filterByInertia = false; //斑点的惯性率限制
float minInertiaRatio = 0.1f, maxInertiaRatio = std::numeric_limits<float>::max();//惯性率最小/大限制
bool filterByConvexity = false; //斑点凸度限制
float minConvexity = 0.95f, maxConvexity = std::numeric_limits<float>::max();//凸度最小/大限制
} EyemBlobParams;
#ifdef __cplusplus
extern "C" {
......@@ -653,7 +664,7 @@ extern "C" {
EXPORTS int eyemBinErosion(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 eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg);
EXPORTS int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, EyemBlobParams tpParams, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg);
EXPORTS bool eyemBinFree(IntPtr hObject);
#ifdef __cplusplus
......@@ -911,7 +922,7 @@ extern "C" {
EXPORTS int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum);
EXPORTS int eyemMarkerTracing(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg, bool bHighAccuracy = false);
EXPORTS int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg);
EXPORTS int eyemLibImpl(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpDstImg);
EXPORTS int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg);
EXPORTS int eyemDrawLine(EyemImage tpImage, EyemOcsDABC tpLine);
EXPORTS int eyemDrawCircle(EyemImage tpImage, EyemOcsDXYR tpCircle);
EXPORTS int eyemDrawRectangle(EyemImage tpImag, EyemRect tpRect);
......
此文件类型无法预览
......@@ -182,6 +182,7 @@
<ClInclude Include="eyemNNDetector.h" />
<ClInclude Include="eyemSmooth.h" />
<ClInclude Include="eyemCodeDetector.h" />
<ClInclude Include="eyemStopwatch.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="yoloWrapper.h" />
</ItemGroup>
......@@ -206,6 +207,7 @@
<ClCompile Include="eyemNNDetector.cpp" />
<ClCompile Include="eyemSmooth.cpp" />
<ClCompile Include="eyemCodeDetector.cpp" />
<ClCompile Include="eyemStopwatch.cpp" />
<ClCompile Include="libopencv.cpp" />
<ClCompile Include="yoloWrapper.cpp" />
</ItemGroup>
......
......@@ -72,6 +72,9 @@
<ClInclude Include="eyemMatchShapes.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemStopwatch.h">
<Filter>源文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="eyemLib.cpp">
......@@ -140,6 +143,9 @@
<ClCompile Include="eyemMatchShapes.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemStopwatch.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="eyemLib.rc">
......
......@@ -2000,7 +2000,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
cv::Rect rec = cv::Rect(forfilter[i].x - 25, forfilter[i].y - 25, 50, 50)&cv::Rect(0, 0, X, Y);
cv::Mat filter = testmat(rec);
cv::Mat mask = binary(rec);
if (!(testmat.ptr<uint8_t>(forfilter[i].y)[forfilter[i].x] > cv::mean(filter, mask)[0] + 45)) {
if (!(testmat.ptr<uint8_t>(forfilter[i].y)[forfilter[i].x] > cv::mean(filter, mask)[0] + 16)) {
filtermap.at<uchar>(forfilter[i]) = 255;
cv::circle(cc, forfilter[i], 1, cv::Scalar(0, 255, 0, 255), 1);
}
......@@ -4477,6 +4477,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
{
//面积过滤
if (stats.ptr<int>(j)[cv::CC_STAT_AREA] > 2) {
cv::circle(cc, cv::Point(cvRound((float)dpCent[(0) + (j)* 2]), cvRound((float)dpCent[(1) + (j)* 2])), 1, cv::Scalar(0, 255, 0));
binary.at<uchar>(cv::Point(cvRound((float)dpCent[(0) + (j)* 2]), cvRound((float)dpCent[(1) + (j)* 2]))) = 255;
}
}
......@@ -4741,9 +4742,9 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
image -= srcPrevEx;
//获取最大轮廓
cv::findContours(image, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
if (contoursFilter.size() <= 0)
{
continue;
if (contoursFilter.size() <= 0) {
//极有可能是不满足一圈的料//2021/09/26修改
cv::findContours(srcPrevEx, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
}
std::vector<cv::Point> contourMax = contoursFilter[0];
for (int i = 1; i < contoursFilter.size(); i++)
......@@ -4755,7 +4756,6 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
}
cv::Moments mu = cv::moments(contourMax);
cv::Point2f reelCenter(float(mu.m10 / mu.m00), float(mu.m01 / mu.m00));
//画中心
//计算最大外接圆半径
float tFRadius = 0;
cv::minEnclosingCircle(contourMax, cv::Point2f(), tFRadius);
......@@ -4764,6 +4764,23 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
cv::drawMarker(cc, reelCenter, cv::Scalar(0, 0, 238, 255), 1, 35, 2);
//去掉中心1/3区域
cv::circle(sinPartMask, reelCenter, cvRound(tFRadius / 2), cv::Scalar(0), -1);
//20210926新增测试用
cv::Mat llbabels;
int totalSize = cv::connectedComponents(sinPartMask, llbabels);
//判断为仅剩几圈的料
if (totalSize < 265) {
cv::Mat srcPrevEEx;
cv::morphologyEx(srcPrev, srcPrevEEx, cv::MORPH_TOPHAT, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
//非极大值抑制
cv::Mat mask;
cv::threshold(srcPrevEEx, mask, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
//去掉分数过低的
double mmval = cv::mean(srcPrevEEx, mask)[0];
mask &= cv::Mat(srcPrevEEx >mmval*0.75);
//
sinPartSize = 10;
sinPartMask = mask.clone();
}
//掩膜区域,用于区分处理区域
uchar *upMask = sinPartMask.data;
//最小料不进行粘连判断
......@@ -4927,6 +4944,19 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
contourMax = contoursFilter[i];
}
}
//20210927测试用
//如果最大轮廓面积小于100000判断中间料盘影响到了定位
if (cv::contourArea(contourMax) < 85000) {
cv::findContours(srcPrevEx0, contoursFilter, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
contourMax = contoursFilter[0];
for (int i = 1; i < contoursFilter.size(); i++)
{
if (cv::contourArea(contoursFilter[i]) > cv::contourArea(contourMax))
{
contourMax = contoursFilter[i];
}
}
}
//计算最大外接圆半径
float tFRadius = 0;
cv::minEnclosingCircle(contourMax, cv::Point2f(), tFRadius);
......@@ -5901,25 +5931,22 @@ int eyemCountObjectE(EyemImage tpImage, EyemRect tpRoi, const char *fileName, in
//输出结果
const int SizeConst = 4;
//<输出计数结果标记图像
{
for (int i = 0; i < SizeConst; i++) {
ipReelNum[i] = trayNum[i];
}
tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
for (int i = 0; i < SizeConst; i++) {
ipReelNum[i] = trayNum[i];
}
//内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
//分配内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size);
//内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
//拷贝数据
memcpy(tpDstImg->vpImage, cc.data, _Size);
}
//分配内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size);
//拷贝数据
memcpy(tpDstImg->vpImage, cc.data, _Size);
return FUNC_OK;
}
......@@ -5931,15 +5958,12 @@ int eyemCountObjectIrregularPartsE(EyemImage tpImage, EyemRect tpRoi, const char
if (src.empty() || NULL == hModelID) {
return FUNC_IMAGE_NOT_EXIST;
}
//跳过执行
if (killProcessID == 0) {
logger.t("eyemCountObjectIrregularPartsE 初始阶段被跳过执行...");
return FUNC_CANNOT_CALC;
}
double begin0 = (double)cv::getTickCount();
//转单通道图像
if (src.channels() != 1)
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
......@@ -7941,7 +7965,8 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
return FUNC_OK;
}
int eyemLibImpl(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpDstImg)
#include "eyemStopwatch.h"
int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg)
{
CV_Assert(NULL != tpImage.vpImage);
......@@ -7950,11 +7975,14 @@ int eyemLibImpl(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpDstImg)
if (image.empty())
return FUNC_IMAGE_NOT_EXIST;
//多个分割阈值
if ((tpHSVModel.dpRangeLExt[0] + tpHSVModel.dpRangeLExt[1] + tpHSVModel.dpRangeLExt[2]) != 0 ||
(tpHSVModel.dpRangeUExt[0] + tpHSVModel.dpRangeUExt[1] + tpHSVModel.dpRangeUExt[2]) != 0) {
std::cout << "红色" << std::endl;
}
#pragma region clock test
//Stopwatch sw;
//sw.Start();
//cv::bitwise_not(image, image);
//sw.Stop();
//std::cout << "时间花费:" << sw.ElapsedMilliseconds() << std::endl;
#pragma endregion
#pragma region resize img
//const int minInputSize = 832;
......
#include "eyemStopwatch.h"
Stopwatch::Stopwatch() {};
Stopwatch:: ~Stopwatch() {};
void Stopwatch::Start()
{
begin0 = static_cast<double>(cv::getTickCount());
}
void Stopwatch::Stop()
{
end1 = static_cast<double>(cv::getTickCount());
}
void Stopwatch::Reset()
{
begin0 = end1 = 0.0;
}
void Stopwatch::Restart()
{
begin0 = static_cast<double>(cv::getTickCount());
}
\ No newline at end of file
#pragma once
//
// eyemStopwatchͷ
//
#ifndef __EYEMSTOPWATCH_H
#define __EYEMSTOPWATCH_H
#include "eyemLib.h"
class Stopwatch
{
public:
Stopwatch();
~Stopwatch();
void Start();
void Stop();
void Reset();
void Restart();
double ElapsedMilliseconds() { return 1000.0 * (end1 - begin0) / cv::getTickFrequency(); }
private:
double begin0 = 0.0, end1 = 0.0;
};
#endif/* __EYEMSTOPWATCH_H */
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!