Commit 1181d725 张士柳

1 个父辈 deb5735c
...@@ -5,309 +5,323 @@ using System.Diagnostics; ...@@ -5,309 +5,323 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
namespace eyemLib_Sharp namespace eyemLib_Sharp
{ {
#region 枚举 public unsafe class EyemLib
//稳健估计方法
public enum ROBUST_METHOD
{ {
EYEM_DIST_USER = -1, #region 图像常量
EYEM_DIST_L1 = 1,
EYEM_DIST_L12 = 2,
EYEM_DIST_FAIR = 3,
EYEM_DIST_WELSCH = 4,
EYEM_DIST_HUBER = 5,
EYEM_DIST_BISQUARE = 6,
EYEM_DIST_CAUCHY = 7,
EYEM_DIST_LOGISTIC = 8,
EYEM_DIST_ANDREWS = 9,
EYEM_DIST_ATLWORTH = 10
}
#endregion public static readonly int CV_8U = 0;
public static readonly int CV_8S = 1;
public static readonly int CV_16U = 2;
public static readonly int CV_16S = 3;
public static readonly int CV_32S = 4;
public static readonly int CV_32F = 5;
public static readonly int CV_64F = 6;
#region 结构体 #endregion
// 图像信息
[StructLayout(LayoutKind.Sequential)]
public struct EyemImage
{
public IntPtr ucpImage; // 地址
public int iWidth; // 图像内存 x 方向大小
public int iHeight; // 图像内存 y 方向大小
public int iDepth; // 图像通道数
}
// 矩形定义 #region 枚举
[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 enum ROBUST_METHOD
{ {
int iXs; // 起始点(左上角) x 坐标 EYEM_DIST_USER = -1,
int iYs; // 起始点(左上角) y 坐标 EYEM_DIST_L1 = 1,
int iXe; // 端点(右下) x 坐标 EYEM_DIST_L12 = 2,
int iYe; // 端点(右下) y 坐标 EYEM_DIST_FAIR = 3,
} EYEM_DIST_WELSCH = 4,
EYEM_DIST_HUBER = 5,
EYEM_DIST_BISQUARE = 6,
EYEM_DIST_CAUCHY = 7,
EYEM_DIST_LOGISTIC = 8,
EYEM_DIST_ANDREWS = 9,
EYEM_DIST_ATLWORTH = 10
}
/////////////////////////////////////////////////////////////////////////////// #endregion
// Orthogonal Coordinate System
///////////////////// #region 结构体
// int type // 图像信息
// [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] public struct EyemImage
public struct EyemOcsIXY {
{ public IntPtr ucpImage; // 地址
int iX; // X坐标 public int iWidth; // 图像内存 x 方向大小
int iY; // Y坐标 public int iHeight; // 图像内存 y 方向大小
} public int iDepth; // 图像位深度(详见说明)
public int iChannels; // 图像通道数
}
[StructLayout(LayoutKind.Sequential)] // 矩形定义
public struct EyemOcsIXYZ [StructLayout(LayoutKind.Sequential)]
{ public struct EyemRect
int iX; // X坐标 {
int iY; // Y坐标 public int iXs; // 起始点(左上角) x 坐标
int iZ; // Z坐标 public int iYs; // 起始点(左上角) y 坐标
} public int iWidth; // x 方向大小(宽度)
public int iHeight; // y 方向大小(高度)
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYQ public struct EyemRect2
{ {
int iX; // X坐标 int iXs; // 起始点(左上角) x 坐标
int iY; // Y坐标 int iYs; // 起始点(左上角) y 坐标
int iQ; // θ int iXe; // 端点(右下) x 坐标
} int iYe; // 端点(右下) y 坐标
}
[StructLayout(LayoutKind.Sequential)] ///////////////////////////////////////////////////////////////////////////////
public struct EyemOcsIXYR // 用于表示圆 // Orthogonal Coordinate System
{
int iX; // X坐标
int iY; // Y坐标
int iR; // 半径
}
[StructLayout(LayoutKind.Sequential)] /////////////////////
public struct EyemOcsIABC // 用于表示直线(一般形式) // int type
{ //
int iA; // a [StructLayout(LayoutKind.Sequential)]
int iB; // b public struct EyemOcsIXY
int iC; // c {
} int iX; // X坐标
int iY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIRQ // 用于表示直线(黑森标准形式)或矢量 public struct EyemOcsIXYZ
{ {
int iR; // ρ int iX; // X坐标
int iQ; // θ int iY; // Y坐标
} int iZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYQS public struct EyemOcsIXYQ
{ {
int iX; // X坐标(单位:像素) int iX; // X坐标
int iY; // Y坐标(单位:像素) int iY; // Y坐标
int iQ; // 斜率(単位:rad) int iQ; // θ
int iS; // 刻度 }
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsIXYR // 用于表示圆
{
int iX; // X坐标
int iY; // Y坐标
int iR; // 半径
}
///////////////////// [StructLayout(LayoutKind.Sequential)]
// float type public struct EyemOcsIABC // 用于表示直线(一般形式)
// {
[StructLayout(LayoutKind.Sequential)] int iA; // a
public struct EyemOcsFXY int iB; // b
{ int iC; // c
float fX; // X坐标 }
float fY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYZ public struct EyemOcsIRQ // 用于表示直线(黑森标准形式)或矢量
{ {
float fX; // X坐标 int iR; // ρ
float fY; // Y坐标 int iQ; // θ
float fZ; // Z坐标 }
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYQ public struct EyemOcsIXYQS
{ {
float fX; // X坐标 int iX; // X坐标(单位:像素)
float fY; // Y坐标 int iY; // Y坐标(单位:像素)
float fQ; // θ int iQ; // 斜率(単位:rad)
} int iS; // 刻度
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYR // 用于表示圆
{
float fX; // X坐标
float fY; // Y坐标
float fR; // 半径
}
[StructLayout(LayoutKind.Sequential)] /////////////////////
public struct EyemOcsFABC // 用于表示直线(一般形式) // float type
{ //
float fA; // a [StructLayout(LayoutKind.Sequential)]
float fB; // b public struct EyemOcsFXY
float fC; // c {
} float fX; // X坐标
float fY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFRQ // 用于表示直线(黑森标准形式)或矢量 public struct EyemOcsFXYZ
{ {
float fR; // ρ float fX; // X坐标
float fQ; // θ float fY; // Y坐标
} float fZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYQS public struct EyemOcsFXYQ
{ {
float fX; // X坐标(単位:像素) float fX; // X坐标
float fY; // Y坐标(単位:像素) float fY; // Y坐标
float fQ; // 斜率(単位:rad) float fQ; // θ
float fS; // 刻度 }
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsFXYR // 用于表示圆
{
float fX; // X坐标
float fY; // Y坐标
float fR; // 半径
}
///////////////////// [StructLayout(LayoutKind.Sequential)]
// double type public struct EyemOcsFABC // 用于表示直线(一般形式)
// {
[StructLayout(LayoutKind.Sequential)] float fA; // a
public struct EyemOcsDXY float fB; // b
{ float fC; // c
public double dX; // X坐标 }
public double dY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYZ public struct EyemOcsFRQ // 用于表示直线(黑森标准形式)或矢量
{ {
double dX; // X坐标 float fR; // ρ
double dY; // Y坐标 float fQ; // θ
double dZ; // Z坐标 }
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYQ public struct EyemOcsFXYQS
{ {
double dX; // X坐标 float fX; // X坐标(単位:像素)
double dY; // Y坐标 float fY; // Y坐标(単位:像素)
double dQ; // θ float fQ; // 斜率(単位:rad)
} float fS; // 刻度
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYR // 用于表示圆
{
double dX; // 中心的X坐标
double dY; // 中心的Y坐标
double dR; // 半径
}
[StructLayout(LayoutKind.Sequential)] /////////////////////
public struct EyemOcsDABC // 直线(一般形)的表现形式 // double type
{ //
double dA; // a [StructLayout(LayoutKind.Sequential)]
double dB; // b public struct EyemOcsDXY
double dC; // c {
} public double dX; // X坐标
public double dY; // Y坐标
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYZ
{
double dX; // X坐标
double dY; // Y坐标
double dZ; // Z坐标
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDRQ // 直線(ヘッセの標準形)やベクトルの表現に使用 public struct EyemOcsDXYQ
{ {
double dR; // ρ double dX; // X坐标
double dQ; // θ double dY; // Y坐标
} double dQ; // θ
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYQS public struct EyemOcsDXYR // 用于表示圆
{ {
double dX; // X座標 double dX; // 中心的X坐标
double dY; // Y座標 double dY; // 中心的Y坐标
double dQ; // 回転角(単位:rad) double dR; // 半径
double dS; // スケール }
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDABCD // 平面(一般形)の表現に使用 public struct EyemOcsDABC // 直线(一般形)的表现形式
{ {
double dA; // a double dA; // a
double dB; // b double dB; // b
double dC; // c double dC; // c
double dD; // d }
}
[StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDXYLSQ // 楕円の表現に使用
{
double dXo; // 中心のX座標
double dYo; // 中心のY座標
double dL; // 長軸半径
double dS; // 短軸半径
double dQ; // 長軸の傾き(単位:rad)
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDPV // 3次元空間内の直線の表現に使用 public struct EyemOcsDRQ // 直線(ヘッセの標準形)やベクトルの表現に使用
{ {
EyemOcsDXYZ tP; // 直線上の1点の座標 double dR; // ρ
EyemOcsDXYZ tV; // 直線の方向ベクトル double dQ; // θ
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemOcsDCRUVW // 楕円体の表現に使用 public struct EyemOcsDXYQS
{ {
EyemOcsDXYZ tC; // 楕円体の中心 double dX; // X座標
EyemOcsDXYZ tR; // 軸の半径(dX:長軸, dY:中軸, dZ:短軸) double dY; // Y座標
double dU; // 長軸のXY平面への射影がX軸となす角(単位:rad) double dQ; // 回転角(単位:rad)
double dV; // 長軸のXY平面とのなす角(単位:rad) double dS; // スケール
double dW; // 長軸まわりの回転角(単位:rad) }
}
// Blob 分析结果 [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] public struct EyemOcsDABCD // 平面(一般形)の表現に使用
public struct EyemBinBlob {
{ double dA; // a
public int iArea; // 面积 double dB; // b
public double dCenterX; // 重心x坐标 double dC; // c
public double dCenterY; // 重心y坐标 double dD; // d
public int iXs, iYs, iXe, iYe; // 外接矩形(始点,终点) }
public int iWidth, iHeight; // 外接矩形(x 方向大小(宽度),y 方向大小(高度))
public double dTheta; // 主轴倾斜角(rad)
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct EyemChainCode public struct EyemOcsDXYLSQ // 楕円の表現に使用
{ {
int iLabel; // 标签 double dXo; // 中心のX座標
double dX; // x坐标 double dYo; // 中心のY座標
double dY; // y坐标 double dL; // 長軸半径
double dVx, dVy; // 向量 double dS; // 短軸半径
} double dQ; // 長軸の傾き(単位:rad)
}
// 条码 解码结果 [StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Sequential)] public struct EyemOcsDPV // 3次元空間内の直線の表現に使用
public struct EyemBarCode {
{ EyemOcsDXYZ tP; // 直線上の1点の座標
public double dAngle; // 角度 EyemOcsDXYZ tV; // 直線の方向ベクトル
public int iCenterX; // x坐标 }
public int iCenterY; // y坐标
public IntPtr hType; // 码类型 [StructLayout(LayoutKind.Sequential)]
public IntPtr hText; // 码内容 public struct EyemOcsDCRUVW // 楕円体の表現に使用
} {
#endregion EyemOcsDXYZ tC; // 楕円体の中心
EyemOcsDXYZ tR; // 軸の半径(dX:長軸, dY:中軸, dZ:短軸)
double dU; // 長軸のXY平面への射影がX軸となす角(単位:rad)
double dV; // 長軸のXY平面とのなす角(単位:rad)
double dW; // 長軸まわりの回転角(単位:rad)
}
// Blob 分析结果
[StructLayout(LayoutKind.Sequential)]
public struct EyemBinBlob
{
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
{
int iLabel; // 标签
double dX; // x坐标
double dY; // y坐标
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; // 码内容
}
#endregion
public unsafe class EyemLib
{
#region 通用 #region 通用
// Win32 memory copy function // Win32 memory copy function
...@@ -315,13 +329,13 @@ namespace eyemLib_Sharp ...@@ -315,13 +329,13 @@ namespace eyemLib_Sharp
private static extern byte* memcpy(byte* dst, byte* src, int count); private static extern byte* memcpy(byte* dst, byte* src, int count);
//读取图像 //读取图像
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage ucpImage); private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage tpImage);
//读取Raw格式图像,仅支持8/16位 //读取Raw格式图像,仅支持8/16位
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageReadRaw(string filename, int iWidth, int iHeight, int iDepth, out EyemImage ucpImage); private static extern int eyemImageReadRaw(string filename, int iWidth, int iHeight, int iDepth, out EyemImage tpImage);
//保存图像 //创建图像
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageWrite(string filename, EyemImage ipImage); private static extern int eyemImageMalloc(int iWidth, int iHeight, int iChannels, int iType, out EyemImage tpImage);
//释放图像资源 //释放图像资源
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern void eyemImageFree(IntPtr ipImage); private static extern void eyemImageFree(IntPtr ipImage);
...@@ -426,6 +440,7 @@ namespace eyemLib_Sharp ...@@ -426,6 +440,7 @@ namespace eyemLib_Sharp
Console.WriteLine("读图失败!"); Console.WriteLine("读图失败!");
return; return;
} }
int flags = eyemImageMalloc(ucpImage.iWidth, ucpImage.iHeight, 3, CV_16U, out tpDstImg);
//ucpImage.iWidth = 3072; ucpImage.iHeight = 3072; ucpImage.iDepth = 2; //ucpImage.iWidth = 3072; ucpImage.iHeight = 3072; ucpImage.iDepth = 2;
//Bitmap bmp = new Bitmap(ucpImage.iWidth, ucpImage.iHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); //Bitmap bmp = new Bitmap(ucpImage.iWidth, ucpImage.iHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
...@@ -594,17 +609,17 @@ namespace eyemLib_Sharp ...@@ -594,17 +609,17 @@ namespace eyemLib_Sharp
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","" //"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",""
//eyemCountObject(ucpImage, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg); //eyemCountObject(ucpImage, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularParts(ucpImage, file.Replace(".png", ""), 0d, "IP_LONG_PARTS", 100, 5, ref pNumObj, out tpDstImg); //eyemCountObjectIrregularParts(ucpImage, file.Replace(".png", ""), 0d, "IP_LONG_PARTS", 100, 5, ref pNumObj, out tpDstImg);
int ipNum; EyemBarCode* tpResults; //int ipNum; EyemBarCode* tpResults;
DataCodeHandle hObject; //DataCodeHandle hObject;
int iRes = eyemDetectAndDecode(ucpImage, tpRoi, file.Replace(".png", ""), "QR_CODE|DATA_MATRIX", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 215, 1d); //int iRes = eyemDetectAndDecode(ucpImage, tpRoi, file.Replace(".png", ""), "QR_CODE|DATA_MATRIX|CODE_39|CODE_128", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 256, 1d);
for (int i = 0; i < ipNum; i++) //for (int i = 0; i < ipNum; i++)
{ //{
Console.WriteLine("类型:" + Marshal.PtrToStringAnsi(tpResults[i].hType) + ";坐标" + "[" + tpResults[i].iCenterX.ToString() + "," + tpResults[i].iCenterY.ToString() + "]" + ";角度:" + tpResults[i].dAngle.ToString("F4") + "," + ";内容:" + Marshal.PtrToStringAnsi(tpResults[i].hText) + ""); // Console.WriteLine("类型:" + Marshal.PtrToStringAnsi(tpResults[i].hType) + ";坐标" + "[" + tpResults[i].iCenterX.ToString() + "," + tpResults[i].iCenterY.ToString() + "]" + ";角度:" + tpResults[i].dAngle.ToString("F4") + "," + ";内容:" + Marshal.PtrToStringAnsi(tpResults[i].hText) + "");
Marshal.FreeCoTaskMem(tpResults[i].hText); Marshal.FreeCoTaskMem(tpResults[i].hType); // Marshal.FreeCoTaskMem(tpResults[i].hText); Marshal.FreeCoTaskMem(tpResults[i].hType);
} //}
hObject.Dispose(); //hObject.Dispose();
sw.Stop(); //sw.Stop();
Console.WriteLine("耗时:" + sw.ElapsedMilliseconds.ToString() + ",结果:" + pNumObj); //Console.WriteLine("耗时:" + sw.ElapsedMilliseconds.ToString() + ",结果:" + pNumObj);
//free image //free image
eyemImageFree(ucpImage.ucpImage); eyemImageFree(ucpImage.ucpImage);
} }
......
...@@ -4,68 +4,68 @@ using System.Runtime.InteropServices; ...@@ -4,68 +4,68 @@ using System.Runtime.InteropServices;
namespace eyemLib_Sharp namespace eyemLib_Sharp
{ {
public unsafe class EyemSamples //public unsafe class EyemSamples
{ //{
#region 通用 // #region 通用
// Win32 memory copy function // // Win32 memory copy function
[DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)] // [DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern byte* memcpy(byte* dst, byte* src, int count); // private static extern byte* memcpy(byte* dst, byte* src, int count);
//读取图像 // //读取图像
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] // [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage ucpImage); // private static extern int eyemImageRead(string filename, int iFalgs, out EyemImage ucpImage);
//保存图像 // //保存图像
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] // [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemImageWrite(string filename, EyemImage ipImage); // private static extern int eyemImageWrite(string filename, EyemImage ipImage);
//释放图像资源 // //释放图像资源
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] // [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern void eyemImageFree(IntPtr ipImage); // private static extern void eyemImageFree(IntPtr ipImage);
#endregion // #endregion
//读码程序 // //读码程序
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] // [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, string fileName, string strCodeType, out DataCodeHandle hObject, out EyemBarCode* tpResults, out int ipNum, bool bUseNiBlack, int iBlockSize, int iRangeC, int iSymbolMin, int iSymbolMax, double dToleErr = 0.5, double dMinorStep = 1.0); // private static extern int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, string fileName, string strCodeType, out DataCodeHandle hObject, out EyemBarCode* tpResults, out int ipNum, bool bUseNiBlack, int iBlockSize, int iRangeC, int iSymbolMin, int iSymbolMax, double dToleErr = 0.5, double dMinorStep = 1.0);
//释放工具 // //释放工具
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] // [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern bool eyemDetectAndDecodeFree(IntPtr hObject); // private static extern bool eyemDetectAndDecodeFree(IntPtr hObject);
public static void eyemReadImageTool(string fileName) // public static void eyemReadImageTool(string fileName)
{ // {
EyemImage ucpImage; // EyemImage ucpImage;
int flag = eyemImageRead(fileName, -1, out ucpImage); // int flag = eyemImageRead(fileName, -1, out ucpImage);
if (flag != 0) // if (flag != 0)
{ // {
Console.WriteLine("读图失败!"); // Console.WriteLine("读图失败!");
return; // return;
} // }
EyemRect tpRoi = new EyemRect(); // EyemRect tpRoi = new EyemRect();
tpRoi.iXs = tpRoi.iYs = 0; // tpRoi.iXs = tpRoi.iYs = 0;
tpRoi.iWidth = ucpImage.iWidth; // tpRoi.iWidth = ucpImage.iWidth;
tpRoi.iHeight = ucpImage.iHeight; // tpRoi.iHeight = ucpImage.iHeight;
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2]; // string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
int ipNum; EyemBarCode* tpResults; // int ipNum; EyemBarCode* tpResults;
DataCodeHandle hObject; // DataCodeHandle hObject;
eyemDetectAndDecode(ucpImage, tpRoi, file.Replace(".png", ""), "QRCode", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 215); // eyemDetectAndDecode(ucpImage, tpRoi, file.Replace(".png", ""), "QRCode", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 215);
for (int i = 0; i < ipNum; i++) // for (int i = 0; i < ipNum; i++)
{ // {
Console.WriteLine("类型:" + Marshal.PtrToStringAnsi(tpResults[i].hType) + ";坐标" + "[" + tpResults[i].iCenterX.ToString() + "," + tpResults[i].iCenterY.ToString() + "]" + ";内容:" + Marshal.PtrToStringAnsi(tpResults[i].hText) + ""); // Console.WriteLine("类型:" + Marshal.PtrToStringAnsi(tpResults[i].hType) + ";坐标" + "[" + tpResults[i].iCenterX.ToString() + "," + tpResults[i].iCenterY.ToString() + "]" + ";内容:" + Marshal.PtrToStringAnsi(tpResults[i].hText) + "");
} // }
//释放 // //释放
hObject.Dispose(); // hObject.Dispose();
//释放图像 // //释放图像
eyemImageFree(ucpImage.ucpImage); // eyemImageFree(ucpImage.ucpImage);
} // }
//释放解码句柄 // //释放解码句柄
public class DataCodeHandle : SafeHandleZeroOrMinusOneIsInvalid // public class DataCodeHandle : SafeHandleZeroOrMinusOneIsInvalid
{ // {
public DataCodeHandle() : base(true) { } // public DataCodeHandle() : base(true) { }
protected override bool ReleaseHandle() // protected override bool ReleaseHandle()
{ // {
return eyemDetectAndDecodeFree(handle); // return eyemDetectAndDecodeFree(handle);
} // }
} // }
} //}
} }
...@@ -17,12 +17,11 @@ namespace eyemLib_Sharp ...@@ -17,12 +17,11 @@ namespace eyemLib_Sharp
// { // {
// EyemLib.eyemReadImageTool(fn); // EyemLib.eyemReadImageTool(fn);
// }); // });
// Console.Clear(); // Console.Write("请按任意键继续。。。");
//} //}
foreach (var fileName in fileNames) foreach (var fileName in fileNames)
{ {
EyemLib.eyemReadImageTool(fileName); EyemLib.eyemReadImageTool(fileName);
//EyemLib.eyemReadImageToolTest(fileName);
} }
Console.Write("请按任意键继续。。。"); Console.Write("请按任意键继续。。。");
Console.ReadKey(); Console.ReadKey();
......
...@@ -257,6 +257,12 @@ static void filterByApriltag(cv::Mat &binary, cv::Mat &labels, std::vector<tMap> ...@@ -257,6 +257,12 @@ static void filterByApriltag(cv::Mat &binary, cv::Mat &labels, std::vector<tMap>
}); });
} }
static inline bool isContainsTwoDCode()
{
return false;
}
static double getThreshVal_Otsu_8u(const cv::Mat& _src) static double getThreshVal_Otsu_8u(const cv::Mat& _src)
{ {
cv::Size size = _src.size(); cv::Size size = _src.size();
...@@ -574,7 +580,7 @@ static int calcHist(cv::Mat src) ...@@ -574,7 +580,7 @@ static int calcHist(cv::Mat src)
int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileName, const char *ccCodeType, IntPtr *hObject, EyemBarCode **hResults, int *ipNum, bool bUseNiBlack, int iBlockSize, const int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown, double dToleErr, double dMinorStep) int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileName, const char *ccCodeType, IntPtr *hObject, EyemBarCode **hResults, int *ipNum, bool bUseNiBlack, int iBlockSize, const int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown, double dToleErr, double dMinorStep)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, tpImage.iDepth, tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
if (src.empty()) { if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
...@@ -601,7 +607,7 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -601,7 +607,7 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
} }
} }
//高斯滤波去噪 //高斯滤波去噪
cv::Mat srcPrev, binary, mask; cv::Mat srcPrev, binary;
//确定识别类型 //确定识别类型
std::vector<std::string> hints_; std::vector<std::string> hints_;
split(ccCodeType, "|", hints_); split(ccCodeType, "|", hints_);
...@@ -620,25 +626,31 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -620,25 +626,31 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//是否添加二维码检测 //是否添加二维码检测
bool addTwoDReader = std::find(hints_.begin(), hints_.end(), "QR_CODE") != hints_.end() || bool addTwoDReader = std::find(hints_.begin(), hints_.end(), "QR_CODE") != hints_.end() ||
std::find(hints_.begin(), hints_.end(), "DATA_MATRIX") != hints_.end() || std::find(hints_.begin(), hints_.end(), "DATA_MATRIX") != hints_.end() ||
std::find(hints_.begin(), hints_.end(), "AZTEC") != hints_.end(); std::find(hints_.begin(), hints_.end(), "AZTEC") != hints_.end() ||
std::find(hints_.begin(), hints_.end(), "PDF_417") != hints_.end();
//未设置识别类型 //未设置识别类型
if (!addOneDReader && !addTwoDReader) if (!addOneDReader && !addTwoDReader)
return FUNC_CANNOT_CALC; return FUNC_CANNOT_CALC;
//检测热点图,s1用来检测一维码;s2用来检测二维码(条码来说会比背景值小,二维码来说会比背景值大) //检测热点图,s1用来检测一维码;s2用来检测二维码(条码来说会比背景值小,二维码来说会比背景值大)
cv::Mat s1(iY, iX, CV_8UC1, cv::Scalar(0)), s2(iY, iX, CV_8UC1, cv::Scalar(0)); cv::Mat s1(iY, iX, CV_8UC1, cv::Scalar(0)), s2(iY, iX, CV_8UC1, cv::Scalar(0));
//<//////////////////////通用预处理方式//////////////////////>// //<//////////////////////通用预处理方式//////////////////////>//
cv::adaptiveThreshold(src, binary, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 83, 0); //高斯滤波去噪
cv::GaussianBlur(src, srcPrev, cv::Size(iBlockSize, iBlockSize), 0.85);
//
////突出条码部分 cv::adaptiveThreshold(srcPrev, binary, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, iBlockSize, 2);
//cv::morphologyEx(src, srcPrev, cv::MORPH_GRADIENT, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3))); ////分块处理
////二值化 //for (int blockY = 0; blockY < iY; blockY += iSymbolMax)
//cv::Mat srcPrevBin; //{
//cv::threshold(srcPrev, srcPrevBin, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); // for (int blockX = 0; blockX < iX; blockX += iSymbolMax)
////略微膨胀覆盖条码 // {
//cv::morphologyEx(srcPrevBin, srcPrevBin, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(iBlockSize, iBlockSize))); // //用原图来进行过滤最好
////尽量去掉无关区域 // cv::Mat blockSrc = srcPrev(cv::Range(blockY, cv::min(blockY + iSymbolMax, iY)), cv::Range(blockX, cv::min(blockX + iSymbolMax, iX)));
//cv::bitwise_and(srcPrevBin, binary, binary);
// cv::threshold(blockSrc, blockSrc, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);
// }
//}
//略微处理连接断裂二维码部分
//cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(cvRound((double)iBlockSize / 3.), cvRound((double)iBlockSize / 3.))));
//连通域分析 //连通域分析
cv::Mat labels, stats, centroids; cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(binary, labels, stats, centroids); int nccomps = cv::connectedComponentsWithStats(binary, labels, stats, centroids);
...@@ -646,8 +658,8 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -646,8 +658,8 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
std::vector<uchar> colors(nccomps + 1, 0); std::vector<uchar> colors(nccomps + 1, 0);
for (int i = 1; i < nccomps; i++) { for (int i = 1; i < nccomps; i++) {
colors[i] = 255; colors[i] = 255;
double maxSize = cv::max(stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]); double minSize = cv::min(stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]); double maxSize = cv::max(stats.ptr<int>(i)[cv::CC_STAT_WIDTH], stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]); 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]; double dRateA = (double)stats.ptr<int>(i)[cv::CC_STAT_AREA] / ((double)stats.ptr<int>(i)[cv::CC_STAT_WIDTH] * (double)stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]);
if ((stats.ptr<int>(i)[cv::CC_STAT_AREA] < cvRound(10.0*dScaleUpAndDown)) || (minSize < (cvRound((double)iBlockSize*dScaleUpAndDown / 3.))) || (maxSize > 35 * iBlockSize)) if ((stats.ptr<int>(i)[cv::CC_STAT_AREA] < cvRound(15.0*dScaleUpAndDown)) || (maxSize > 35 * iBlockSize) || (maxSize < (double)iBlockSize*(1. - dToleErr)))
{ {
colors[i] = 0; colors[i] = 0;
} }
...@@ -665,7 +677,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -665,7 +677,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
} }
} }
}); });
//格式化文件名 //格式化文件名
const int bufSize = 32; const int bufSize = 32;
char file[bufSize * 4] = { 0 }; char file[bufSize * 4] = { 0 };
...@@ -676,63 +687,54 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -676,63 +687,54 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//膨胀区域 //膨胀区域
cv::Mat binaryEx; cv::Mat binaryEx;
cv::morphologyEx(binary, binaryEx, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(iBlockSize * 2, iBlockSize * 2))); cv::morphologyEx(binary, binaryEx, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(iBlockSize * 2 + 1, iBlockSize * 2 + 1)));
//连通域分析 //连通域分析
nccomps = cv::connectedComponentsWithStats(binaryEx, labels, stats, centroids); nccomps = cv::connectedComponentsWithStats(binaryEx, labels, stats, centroids);
for (int i = 1; i < nccomps; i++) cv::parallel_for_(cv::Range(1, nccomps), [&](const cv::Range& rangeTop)->void {
{ for (int i = rangeTop.start; i < rangeTop.end; i++)
//角点响应图
cv::Mat harMap;
cv::Rect rec(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]);
if ((cv::max(rec.size().width, rec.size().height) > 5 * iBlockSize) && (rec.area() > 5 * std::pow(iBlockSize, 2)))
{ {
cv::cornerHarris(src(rec), harMap, iBlockSize, 3, 0.04); cv::Rect rec(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]);
// 归一化与转换 if ((cv::min(rec.size().width, rec.size().height) > 5 * iBlockSize) && (rec.area() > 5 * std::pow(iBlockSize, 2)))
cv::normalize(harMap, harMap, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat()); {
cv::convertScaleAbs(harMap, harMap); //角点响应图
// 尺寸 cv::Mat harMap;
cv::Size sz = rec.size(); cv::cornerHarris(src(rec), harMap, iBlockSize, 3, 0.04);
// 用于一维码检测 // 归一化与转换
cv::Mat m1 = harMap < calcHist(harMap); cv::normalize(harMap, harMap, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
cv::convertScaleAbs(harMap, harMap);
const uchar *s1ptr = m1.data; // 尺寸
uchar *d1ptr = s1.data; cv::Size sz = rec.size();
// 叠加图像 // 用于一维码检测
cv::parallel_for_(cv::Range(0, sz.height), [&](const cv::Range& range)->void { cv::Mat m1 = harMap < calcHist(harMap);
for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < sz.width; x++) { const uchar *s1ptr = m1.data;
d1ptr[(x + rec.x) + (y + rec.y)*iX] += s1ptr[(x)+(y)*sz.width]; uchar *d1ptr = s1.data;
// 叠加图像
cv::parallel_for_(cv::Range(0, sz.height), [&](const cv::Range& range)->void {
for (int y = range.start; y < range.end; y++) {
for (int x = 0; x < sz.width; x++) {
d1ptr[(x + rec.x) + (y + rec.y)*iX] += s1ptr[(x)+(y)*sz.width];
}
} }
} });
}); // 用于二维码检测,似乎用阈值法干扰比较少
// 用于二维码检测 cv::Mat m2 = harMap > calcHist(harMap);
cv::Mat m2 = harMap > calcHist(harMap);
const uchar *s2ptr = m2.data;
const uchar *s2ptr = m2.data; uchar *d2ptr = s2.data;
uchar *d2ptr = s2.data; // 叠加图像
// 叠加图像 cv::parallel_for_(cv::Range(0, sz.height), [&](const cv::Range& range)->void {
cv::parallel_for_(cv::Range(0, sz.height), [&](const cv::Range& range)->void { for (int y = range.start; y < range.end; y++) {
for (int y = range.start; y < range.end; y++) { for (int x = 0; x < sz.width; x++) {
for (int x = 0; x < sz.width; x++) { d2ptr[(x + rec.x) + (y + rec.y)*iX] += s2ptr[(x)+(y)*sz.width];
d2ptr[(x + rec.x) + (y + rec.y)*iX] += s2ptr[(x)+(y)*sz.width]; }
} }
} });
}); }
} }
} });
//输出解码结果 //输出解码结果
std::vector<EyemBarCode> *tpResults = new std::vector<EyemBarCode>(); std::vector<EyemBarCode> *tpResults = new std::vector<EyemBarCode>();
//解码内容 //解码内容
...@@ -742,10 +744,8 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -742,10 +744,8 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//判断要增加的识别,从这一步可以进行分开处理 //判断要增加的识别,从这一步可以进行分开处理
if (addOneDReader) if (addOneDReader)
{ {
//添加一维码识别
cv::morphologyEx(binary, mask, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iBlockSize + 1, 2 * iBlockSize + 1)));
//去掉干扰 //去掉干扰
cv::bitwise_and(s1, mask, s1); cv::bitwise_and(s1, binaryEx, s1);
//连通域分析 //连通域分析
nccomps = cv::connectedComponentsWithStats(s1, labels, stats, centroids); nccomps = cv::connectedComponentsWithStats(s1, labels, stats, centroids);
std::vector<uchar> colors2(nccomps + 1, 0); std::vector<uchar> colors2(nccomps + 1, 0);
...@@ -929,18 +929,10 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -929,18 +929,10 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//添加二维码识别 //添加二维码识别
if (addTwoDReader) if (addTwoDReader)
{ {
//突出条码部分
cv::morphologyEx(src, srcPrev, cv::MORPH_BLACKHAT, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(4 * iBlockSize, 4 * iBlockSize)));
//二值化,用于分割粘连
cv::Mat srcPrevBin;
cv::threshold(srcPrev, srcPrevBin, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
//
int ksize = cvRound(floor((double)iBlockSize / 3.)) > 3 ? cvRound(floor((double)iBlockSize / 3.)) : 3;
cv::morphologyEx(srcPrevBin, srcPrevBin, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(ksize, ksize)));
//断裂处连接在一起 //断裂处连接在一起
cv::morphologyEx(s2, s2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iBlockSize + 1, 2 * iBlockSize + 1))); cv::morphologyEx(s2, s2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iBlockSize + 1, 2 * iBlockSize + 1)));
//去除干扰 //去除干扰
cv::bitwise_and(srcPrevBin, s2, s2); cv::bitwise_and(binary, s2, s2);
//对图像过滤 //对图像过滤
cv::Mat labels, stats, centroids; cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(s2, labels, stats, centroids); int nccomps = cv::connectedComponentsWithStats(s2, labels, stats, centroids);
...@@ -968,104 +960,108 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -968,104 +960,108 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
} }
} }
}); });
//用于轮廓检测 //判断区域内是否包含二维码
std::vector<std::vector<cv::Point>> contourAll, contourFilter; std::vector<std::vector<cv::Point>> contourAll, contourFilter;
findContours(s2, contourAll, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); findContours(s2, contourAll, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
//for (int i = 0; i < static_cast<int>(contourAll.size()); i++) for (int i = 0; i < static_cast<int>(contourAll.size()); i++)
//{ {
// cv::RotatedRect rec = cv::minAreaRect(contourAll[i]); cv::RotatedRect rec = cv::minAreaRect(contourAll[i]);
// //偏移量 //满足矩形条件与面积条件
// cv::Point2f pts[4]; double dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width);
// rec.points(pts); if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20)
// //满足矩形条件与面积条件 {
// double dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width); //范围
// if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20) int dynSize = cvRound(cv::max((double)rec.boundingRect().size().height / dScaleUpAndDown, (double)rec.boundingRect().size().width / dScaleUpAndDown));
// { //用原图来进行过滤最好
// int dynSize = cvRound(cv::max((double)rec.boundingRect().size().height / dScaleUpAndDown, (double)rec.boundingRect().size().width / dScaleUpAndDown)); cv::Mat waitArea = realSrc(cv::Range(cv::max(0, cvRound(rec.center.y / dScaleUpAndDown) - (2 * iBlockSize + dynSize / 2)), cv::min(iRealY - 1, cvRound(rec.center.y / dScaleUpAndDown) + (2 * iBlockSize + dynSize / 2))), cv::Range(cv::max(0, cvRound(rec.center.x / dScaleUpAndDown) - (2 * iBlockSize + dynSize / 2)), cv::min(iRealX - 1, cvRound(rec.center.x / dScaleUpAndDown) + (2 * iBlockSize + dynSize / 2))));
// //用原图来进行过滤最好 //测试用
// cv::Mat waitArea = realSrc(cv::Range(cv::max(0, cvRound(rec.center.y / dScaleUpAndDown) - (2 * iBlockSize + dynSize / 2)), cv::min(iRealY - 1, cvRound(rec.center.y / dScaleUpAndDown) + (2 * iBlockSize + dynSize / 2))), cv::Range(cv::max(0, cvRound(rec.center.x / dScaleUpAndDown) - (2 * iBlockSize + dynSize / 2)), cv::min(iRealX - 1, cvRound(rec.center.x / dScaleUpAndDown) + (2 * iBlockSize + dynSize / 2)))); cv::Mat waitAreaEx;
// //计算响应图 cv::morphologyEx(waitArea, waitAreaEx, cv::MORPH_BLACKHAT, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iRealBlockSize + 1, 2 * iRealBlockSize + 1)));
// cv::Mat harMap; //用对比度阈值过滤
// cv::cornerHarris(waitArea, harMap, iRealBlockSize, 3, 0.04); double min, max;
// // 归一化与转换 cv::minMaxLoc(waitAreaEx, &min, &max);
// cv::normalize(harMap, harMap, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat()); if (max - min < 35) {
// cv::convertScaleAbs(harMap, harMap); continue;
// //进一步判断 }
// cv::Mat m2; //计算响应图
// cv::threshold(harMap, m2, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); cv::Mat harMap;
// ////测试用 cv::cornerHarris(waitArea, harMap, iRealBlockSize, 3, 0.04);
// //cv::Mat locBinary; // 归一化与转换
// //cv::threshold(waitArea, locBinary, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU); cv::normalize(harMap, harMap, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
// //连接断裂处 cv::convertScaleAbs(harMap, harMap);
// cv::morphologyEx(m2, m2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(cvRound((double)iRealBlockSize / 3.), cvRound((double)iRealBlockSize / 3.)))); //进一步判断
// //用于轮廓检测 cv::Mat m2;
// std::vector<std::vector<cv::Point>> contours; cv::threshold(harMap, m2, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
// findContours(m2, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); //连接断裂处
// //最大轮廓 cv::morphologyEx(m2, m2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(cvRound((double)iRealBlockSize / 3.), cvRound((double)iRealBlockSize / 3.))));
// std::vector<cv::Point> contourMax = contours[0]; //用于轮廓检测
// for (int cc = 0; cc < contours.size(); cc++) std::vector<std::vector<cv::Point>> contours;
// { findContours(m2, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
// if (cv::contourArea(contours[cc]) > cv::contourArea(contourMax)) //最大轮廓
// { std::vector<cv::Point> contourMax = contours[0];
// contourMax = contours[cc]; for (int cc = 0; cc < contours.size(); cc++)
// } {
// } if (cv::contourArea(contours[cc]) > cv::contourArea(contourMax))
// ////扫描线 {
// //cv::Point ptStart, ptEnd; contourMax = contours[cc];
// //ptStart = cv::Point(pts[0]); ptEnd = cv::Point(pts[2]); }
// rec = cv::minAreaRect(contourMax); }
// dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width); rec = cv::minAreaRect(contourMax);
// //判断比例 dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width);
// if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20) //判断比例
// { if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20)
// double dRateA = std::pow(cv::min(rec.size.height, rec.size.width), 2) / std::pow(dynSize, 2); {
// if (dRateA >= 0.5*(1. - dToleErr)) double dRateA = std::pow(cv::min(rec.size.height, rec.size.width), 2) / std::pow(dynSize, 2);
// { if (dRateA >= 0.5*(1. - dToleErr) && ((double)rec.size.width > double(8. * iBlockSize)) && ((double)rec.size.height > double(8. * iBlockSize)))
// ////按照比例过滤 {
// //int flags = 0; //cv::Point2f pts[4];
// //double test_line[2]{ 0 }; //rec.points(pts);
////
// //cv::LineIterator it(binary, ptStart, ptEnd, 4); //cv::Mat locBinary;
//cv::adaptiveThreshold(waitArea, locBinary, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, iRealBlockSize, 7);
// //uint8_t future_pixel = 0; ////扫描线
//cv::Point ptStart, ptEnd;
// //for (int n = 0; n < it.count; n++, ++it) //ptStart = cv::Point(pts[0]); ptEnd = cv::Point(pts[2]);
// //{ ////按照比例过滤
// // //统计均匀性 //int flags = 0;
// // uint8_t next_pixel = binary.ptr<uint8_t>(it.pos().y)[it.pos().x]; //double test_line[2]{ 0 };
// // test_line[next_pixel % 254]++;
// // if (next_pixel != future_pixel) //cv::LineIterator it(locBinary, ptStart, ptEnd, 4);
// // {
// // flags++; //uint8_t future_pixel = 0;
// // future_pixel = 255 - future_pixel;
// // } //for (int n = 0; n < it.count; n++, ++it)
// //} //{
// ////判断是否满足比例 // //统计均匀性
// //double dRate = cv::min(test_line[0], test_line[1]) / cv::max(test_line[0], test_line[1]); // uint8_t next_pixel = locBinary.ptr<uint8_t>(it.pos().y)[it.pos().x];
// //if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr)) // test_line[next_pixel % 254]++;
// //{ // if (next_pixel != future_pixel)
// //cv::rectangle(showMat, cv::minAreaRect(contourAll[i]).boundingRect(), cv::Scalar(0, 255, 0), 1); // {
// contourFilter.push_back(contourAll[i]); // flags++;
// //} // future_pixel = 255 - future_pixel;
// } // }
// } //}
// } ////判断是否满足比例
//} //double dRate = cv::min(test_line[0], test_line[1]) / cv::max(test_line[0], test_line[1]);
//for (int i = 0; i < contourFilter.size(); i++) //if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && flags > 8)
//{ //{
// cv::Rect rect = cv::minAreaRect(contourFilter[i]).boundingRect(); //contourFilter.push_back(contourAll[i]);
// cv::RotatedRect rRect = cv::minAreaRect(contourFilter[i]); //}
// //外包矩形
// int dynSize = cvRound(cv::max((double)rect.size().height / dScaleUpAndDown, (double)rect.size().width / dScaleUpAndDown)); //cv::Rect rect = cv::minAreaRect(contourFilter[i]).boundingRect();
// //疑似二维码区域 //cv::RotatedRect rRect = cv::minAreaRect(contourFilter[i]);
// cv::Mat waitArea = realSrc(cv::Range(cv::max(0, cvRound(rRect.center.y / dScaleUpAndDown) - cvRound(4.*(double)iBlockSize + dynSize / 2)), cv::min(realSrc.rows - 1, cvRound(rRect.center.y / dScaleUpAndDown) + cvRound(4.*(double)iBlockSize + dynSize / 2))), cv::Range(cv::max(0, cvRound(rRect.center.x / dScaleUpAndDown) - cvRound(4.*(double)iBlockSize + dynSize / 2)), cv::min(realSrc.cols - 1, cvRound(rRect.center.x / dScaleUpAndDown) + cvRound(4.*(double)iBlockSize + dynSize / 2)))); ////外包矩形
// //处理后再压入识别 //int dynSize = cvRound(cv::max((double)rect.size().height / dScaleUpAndDown, (double)rect.size().width / dScaleUpAndDown));
// waitAreas.push_back(WaitArea(waitArea, cv::Point(cvRound(rRect.center.x / dScaleUpAndDown), cvRound(rRect.center.y / dScaleUpAndDown)), 0, 0, false, std::vector<cv::Mat>())); ////疑似二维码区域
// //画图 //cv::Mat waitArea = realSrc(cv::Range(cv::max(0, cvRound(rRect.center.y / dScaleUpAndDown) - cvRound(4.*(double)iBlockSize + dynSize / 2)), cv::min(realSrc.rows - 1, cvRound(rRect.center.y / dScaleUpAndDown) + cvRound(4.*(double)iBlockSize + dynSize / 2))), cv::Range(cv::max(0, cvRound(rRect.center.x / dScaleUpAndDown) - cvRound(4.*(double)iBlockSize + dynSize / 2)), cv::min(realSrc.cols - 1, cvRound(rRect.center.x / dScaleUpAndDown) + cvRound(4.*(double)iBlockSize + dynSize / 2))));
// cv::rectangle(showMat, rect, cv::Scalar(0, 255, 0), 1); ////处理后再压入识别
//} waitAreas.push_back(WaitArea(waitArea, cv::Point(cvRound(rec.center.x / dScaleUpAndDown), cvRound(rec.center.y / dScaleUpAndDown)), 0, 0, false, std::vector<cv::Mat>()));
}
}
}
}
} }
////解码 //解码
//decodeMul(waitAreas, hints_, showMat, decodeResults, iBlockSize, iRangeC, dMinorStep); //decodeMul(waitAreas, hints_, showMat, decodeResults, iBlockSize, iRangeC, dMinorStep);
////输出结果 ////输出结果
//for (int i = 0; i < decodeResults.size(); i++) //for (int i = 0; i < decodeResults.size(); i++)
...@@ -1098,6 +1094,8 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -1098,6 +1094,8 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//*hResults = tpResults->data(); //*hResults = tpResults->data();
//*ipNum = static_cast<int>(tpResults->size()); //*ipNum = static_cast<int>(tpResults->size());
//*hObject = reinterpret_cast<IntPtr>(tpResults); //*hObject = reinterpret_cast<IntPtr>(tpResults);
////膨胀区域
//cv::morphologyEx(binary, binaryEx, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(iBlockSize, iBlockSize)));
return FUNC_OK; return FUNC_OK;
...@@ -1105,20 +1103,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -1105,20 +1103,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//计算导数 //计算导数
cv::Mat dx, dy, mag; cv::Mat dx, dy, mag;
cv::Sobel(srcPrev, dx, CV_32F, 1, 0); cv::Sobel(srcPrev, dx, CV_32F, 1, 0);
......
...@@ -5,19 +5,16 @@ ...@@ -5,19 +5,16 @@
#ifndef __EYEM_LIB_H #ifndef __EYEM_LIB_H
#define __EYEM_LIB_H #define __EYEM_LIB_H
//#include <map>
//#include <list>
//#include <vector>
//#include <limits>
//#include <float.h>
//#include <fstream>
#include <Windows.h> #include <Windows.h>
#include <opencv.hpp> #include <opencv.hpp>
#include <opencv2\core\simd_intrinsics.hpp>
#ifndef EYEM_EXPORTS #ifndef EXPORTS
#define EYEM_EXPORTS __declspec(dllexport) #define EXPORTS __declspec(dllexport)
#endif
#ifndef MAKETYPE
#define MAKETYPE CV_MAKETYPE
#endif #endif
/********************************************************************************************/ /********************************************************************************************/
...@@ -116,7 +113,8 @@ typedef struct { ...@@ -116,7 +113,8 @@ typedef struct {
void *vpImage; // 地址 void *vpImage; // 地址
int iWidth; // 图像内存 x 方向大小 int iWidth; // 图像内存 x 方向大小
int iHeight; // 图像内存 y 方向大小 int iHeight; // 图像内存 y 方向大小
int iDepth; // 图像位深度 int iDepth; // 图像位深度(参见说明)
int iChannels; // 图像通道数
} EyemImage; } EyemImage;
...@@ -372,26 +370,26 @@ extern "C" { ...@@ -372,26 +370,26 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
//EYEM_EXPORTS CvMat *eyemMatMallocMatrix(int iRows, int iCols, void *vpData); //EXPORTS CvMat *eyemMatMallocMatrix(int iRows, int iCols, void *vpData);
//EYEM_EXPORTS void eyemMatFreeMatrix(CvMat *dpMat); //EXPORTS void eyemMatFreeMatrix(CvMat *dpMat);
//EYEM_EXPORTS void eyemMatZero(CvMat *vpA); //EXPORTS void eyemMatZero(CvMat *vpA);
//EYEM_EXPORTS void eyemMatCopy(CvMat *vpDst, CvMat *vpSrc); //EXPORTS void eyemMatCopy(CvMat *vpDst, CvMat *vpSrc);
//EYEM_EXPORTS void eyemMatAdd(CvMat *vpA, CvMat *vpB, CvMat *vpC); //EXPORTS void eyemMatAdd(CvMat *vpA, CvMat *vpB, CvMat *vpC);
EYEM_EXPORTS void eyemMatSub(int, int, void *, void *, void *); EXPORTS void eyemMatSub(int, int, void *, void *, void *);
EYEM_EXPORTS void eyemMatMulScalar(double, int, int, void *, void *); EXPORTS void eyemMatMulScalar(double, int, int, void *, void *);
EYEM_EXPORTS int eyemMatMul(int, int, void *, int, int, void *, void *); EXPORTS int eyemMatMul(int, int, void *, int, int, void *, void *);
EYEM_EXPORTS int eyemMatGenMul(double, int, int, void *, int, int, void *, double, void *, void *); EXPORTS int eyemMatGenMul(double, int, int, void *, int, int, void *, double, void *, void *);
EYEM_EXPORTS void eyemMatMulTransposed(int, int, int, void *, void *); EXPORTS void eyemMatMulTransposed(int, int, int, void *, void *);
EYEM_EXPORTS int eyemMatMulTransposed2(int, int, int, void *, int, int, void *, void *); EXPORTS int eyemMatMulTransposed2(int, int, int, void *, int, int, void *, void *);
EYEM_EXPORTS void eyemMatTranspose(int, int, void *, void *); EXPORTS void eyemMatTranspose(int, int, void *, void *);
EYEM_EXPORTS double eyemMatTrace(int, void *); EXPORTS double eyemMatTrace(int, void *);
EYEM_EXPORTS int eyemMatInvert(int, void *, void *); EXPORTS int eyemMatInvert(int, void *, void *);
EYEM_EXPORTS int eyemMatSolveLU(int, void *, double[], double[]); EXPORTS int eyemMatSolveLU(int, void *, double[], double[]);
EYEM_EXPORTS int eyemMatSolveSVD(int, int, void *, double[], double[]); EXPORTS int eyemMatSolveSVD(int, int, void *, double[], double[]);
EYEM_EXPORTS int eyemMatJacobiEigen(int, void *, double[], void *); EXPORTS int eyemMatJacobiEigen(int, void *, double[], void *);
EYEM_EXPORTS int eyemMatQrEigen(int, void *, double[], void *); EXPORTS int eyemMatQrEigen(int, void *, double[], void *);
EYEM_EXPORTS int eyemMatSVD(int, int, void *, void *, double[], void *); EXPORTS int eyemMatSVD(int, int, void *, void *, double[], void *);
EYEM_EXPORTS int eyemMatCholeskyDecomp(int, void *, void *); EXPORTS int eyemMatCholeskyDecomp(int, void *, void *);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -423,16 +421,16 @@ extern "C" { ...@@ -423,16 +421,16 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_EXPORTS int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, int numToIgnore, EyemOcsDABC &tpLine); EXPORTS int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, int numToIgnore, EyemOcsDABC &tpLine);
EYEM_EXPORTS int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, double dRobustCoef, EyemOcsDABC &tpLine); EXPORTS int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, double dRobustCoef, EyemOcsDABC &tpLine);
EYEM_EXPORTS int eyemFitPlane(int, EyemOcsDXYZ[], int, double, EyemOcsDABCD *); EXPORTS int eyemFitPlane(int, EyemOcsDXYZ[], int, double, EyemOcsDABCD *);
EYEM_EXPORTS int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, int numToIgnore, EyemOcsDXYR &tpCircle); EXPORTS int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, int numToIgnore, EyemOcsDXYR &tpCircle);
EYEM_EXPORTS int eyemFitEllipse(int, EyemOcsDXY[], int, double, EyemOcsDXYLSQ *); EXPORTS int eyemFitEllipse(int, EyemOcsDXY[], int, double, EyemOcsDXYLSQ *);
EYEM_EXPORTS int eyemFitEllipseC(int, EyemOcsDXY[], int, double, double[]); EXPORTS int eyemFitEllipseC(int, EyemOcsDXY[], int, double, double[]);
EYEM_EXPORTS int eyemFitConics(int, EyemOcsDXY[], int, double, double[]); EXPORTS int eyemFitConics(int, EyemOcsDXY[], int, double, double[]);
EYEM_EXPORTS int eyemFitParabola(int, EyemOcsDXY[], int, double, EyemOcsDABC *); EXPORTS int eyemFitParabola(int, EyemOcsDXY[], int, double, EyemOcsDABC *);
EYEM_EXPORTS int eyemFitEllipsoid(int, EyemOcsDXYZ[], int, double, EyemOcsDCRUVW *); EXPORTS int eyemFitEllipsoid(int, EyemOcsDXYZ[], int, double, EyemOcsDCRUVW *);
EYEM_EXPORTS int eyemFitCone(int, EyemOcsDXYZ[], int, double, double[]); EXPORTS int eyemFitCone(int, EyemOcsDXYZ[], int, double, double[]);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -447,22 +445,22 @@ extern "C" { ...@@ -447,22 +445,22 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_EXPORTS void eyemClp2dDistanceTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, double &tpDist); EXPORTS void eyemClp2dDistanceTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, double &tpDist);
EYEM_EXPORTS void eyemClp2dCenterTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY &tpCenter); EXPORTS void eyemClp2dCenterTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY &tpCenter);
EYEM_EXPORTS int eyemClp2dLineTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDABC &tpLine); EXPORTS int eyemClp2dLineTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDABC &tpLine);
EYEM_EXPORTS int eyemClp2dMidperpendicularTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDABC &tpLine); EXPORTS int eyemClp2dMidperpendicularTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDABC &tpLine);
EYEM_EXPORTS int eyemClp2dVerticalLinePointAndLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, EyemOcsDABC &tpVertical); EXPORTS int eyemClp2dVerticalLinePointAndLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, EyemOcsDABC &tpVertical);
EYEM_EXPORTS void eyemClp2dLinePointAndSlope(EyemOcsDXY tpPoint, double dSlope, EyemOcsDABC &tpLine); EXPORTS void eyemClp2dLinePointAndSlope(EyemOcsDXY tpPoint, double dSlope, EyemOcsDABC &tpLine);
EYEM_EXPORTS int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDXY &tpPoint); EXPORTS int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDXY &tpPoint);
EYEM_EXPORTS int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle); EXPORTS int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle);
EYEM_EXPORTS int eyemClp2dCenterLineOfTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDABC &tpLineC); EXPORTS int eyemClp2dCenterLineOfTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDABC &tpLineC);
EYEM_EXPORTS int eyemClp2dDistancePointToLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, double &dpDist); EXPORTS int eyemClp2dDistancePointToLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, double &dpDist);
EYEM_EXPORTS int eyemClp2dTranslationOfLine(EyemOcsDABC tpSrcL, EyemOcsDXY tpTrans, EyemOcsDABC &tpDstL); EXPORTS int eyemClp2dTranslationOfLine(EyemOcsDABC tpSrcL, EyemOcsDXY tpTrans, EyemOcsDABC &tpDstL);
EYEM_EXPORTS void eyemClp2dAreaTriangle(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, double &dpArea); EXPORTS void eyemClp2dAreaTriangle(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, double &dpArea);
EYEM_EXPORTS int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, EyemOcsDXYR &tpCircle); EXPORTS int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, EyemOcsDXYR &tpCircle);
EYEM_EXPORTS int eyemClp2dIntersectionLineAndCircle(EyemOcsDABC tpLine, EyemOcsDXYR tpCircle, EyemOcsDXY &tpPoint1, EyemOcsDXY &tpPoint2); EXPORTS int eyemClp2dIntersectionLineAndCircle(EyemOcsDABC tpLine, EyemOcsDXYR tpCircle, EyemOcsDXY &tpPoint1, EyemOcsDXY &tpPoint2);
EYEM_EXPORTS int eyemClp2dTangentPointToCircle(EyemOcsDXY tpPoint, EyemOcsDXYR tpCircle, EyemOcsDABC &tpTangent1, EyemOcsDXY &tpContact1, EyemOcsDABC &tpTangent2, EyemOcsDXY &tpContact2); EXPORTS int eyemClp2dTangentPointToCircle(EyemOcsDXY tpPoint, EyemOcsDXYR tpCircle, EyemOcsDABC &tpTangent1, EyemOcsDXY &tpContact1, EyemOcsDABC &tpTangent2, EyemOcsDXY &tpContact2);
EYEM_EXPORTS int eyemClp2dClosestToCircle(EyemOcsDXY tpPoint, EyemOcsDXYR tpCircle, EyemOcsDXY &tpClosest, double &dpDist); EXPORTS int eyemClp2dClosestToCircle(EyemOcsDXY tpPoint, EyemOcsDXYR tpCircle, EyemOcsDXY &tpClosest, double &dpDist);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -628,15 +626,15 @@ extern "C" { ...@@ -628,15 +626,15 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_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);
EYEM_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);
EYEM_EXPORTS int eyemBinNiBlack(EyemImage tpSrcImg, EyemImage *tpDstImg, int iType, int iWinSize, double dK, int binarizationMethod, double dR); EXPORTS int eyemBinNiBlack(EyemImage tpSrcImg, EyemImage *tpDstImg, int iType, int iWinSize, double dK, int binarizationMethod, double dR);
EYEM_EXPORTS int eyemBinDynThreshold(EyemImage tpSrcImg, EyemImage tpThresholdImg, int iOffset, int iLightDark, EyemImage *tpDstImg); EXPORTS int eyemBinDynThreshold(EyemImage tpSrcImg, EyemImage tpThresholdImg, int iOffset, int iLightDark, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemBinDilation(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg); EXPORTS int eyemBinDilation(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemBinErosion(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg); EXPORTS int eyemBinErosion(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemBinOpening(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg); EXPORTS int eyemBinOpening(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg); EXPORTS int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDstImg);
EYEM_EXPORTS bool eyemBinFree(IntPtr hObject); EXPORTS bool eyemBinFree(IntPtr hObject);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -653,12 +651,12 @@ extern "C" { ...@@ -653,12 +651,12 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_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);
EYEM_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);
EYEM_EXPORTS int eyemEdge1dFitLine(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDABC *tpLine); EXPORTS int eyemEdge1dFitLine(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDABC *tpLine);
EYEM_EXPORTS int eyemEdge1dFitCircle(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDXYR *tpCircle); EXPORTS int eyemEdge1dFitCircle(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDXYR *tpCircle);
EYEM_EXPORTS int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, IntPtr *hObject); EXPORTS int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, IntPtr *hObject);
EYEM_EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject); EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -673,11 +671,11 @@ extern "C" { ...@@ -673,11 +671,11 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_EXPORTS int eyemEdgesPixel(EyemImage tpImage, double dThresh); EXPORTS int eyemEdgesPixel(EyemImage tpImage, double dThresh);
EYEM_EXPORTS int eyemEdgesSubpixel(EyemImage tpImage, IntPtr *hObject, EyemOcsDXY **tpEdges, int iFilter, int iLow, int iHigh); EXPORTS int eyemEdgesSubpixel(EyemImage tpImage, IntPtr *hObject, EyemOcsDXY **tpEdges, int iFilter, int iLow, int iHigh);
EYEM_EXPORTS int eyemSkeleton(EyemImage tpImage, cv::Mat &skeleton); EXPORTS int eyemSkeleton(EyemImage tpImage, cv::Mat &skeleton);
EYEM_EXPORTS int eyemSobelAmp(EyemImage tpImage, EyemImage &ImaAmp); EXPORTS int eyemSobelAmp(EyemImage tpImage, EyemImage &ImaAmp);
EYEM_EXPORTS int eyemAutoCanny(EyemImage tpImage, float dSigma = 0.33); EXPORTS int eyemAutoCanny(EyemImage tpImage, float dSigma = 0.33);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -774,9 +772,9 @@ extern "C" { ...@@ -774,9 +772,9 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_EXPORTS int eyemSmoothMean(EyemImage tpImage, int kSizew, int kSizeh, EyemImage *tpDstImg); EXPORTS int eyemSmoothMean(EyemImage tpImage, int kSizew, int kSizeh, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemSmoothGaussian(EyemImage tpImage, int kSizew, int kSizeh, double dSigmaX, double dSigmaY, EyemImage *tpDstImg); EXPORTS int eyemSmoothGaussian(EyemImage tpImage, int kSizew, int kSizeh, double dSigmaX, double dSigmaY, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemSmoothMedian(EyemImage tpImage, int kSize, EyemImage *tpDstImg); EXPORTS int eyemSmoothMedian(EyemImage tpImage, int kSize, EyemImage *tpDstImg);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -791,7 +789,7 @@ extern "C" { ...@@ -791,7 +789,7 @@ extern "C" {
#endif #endif
// 函数接口 // 函数接口
EYEM_EXPORTS int eyemEDLinesDetector(EyemImage tpImage, int _gradThresh, int _anchorThresh, int _scanInterval, int _minPathLen, double _sigma, bool _sumFlag, double _line_error, int _min_line_len, double _max_distance_between_two_lines, double _max_error, EyemImage *tpDstImg); EXPORTS int eyemEDLinesDetector(EyemImage tpImage, int _gradThresh, int _anchorThresh, int _scanInterval, int _minPathLen, double _sigma, bool _sumFlag, double _line_error, int _min_line_len, double _max_distance_between_two_lines, double _max_error, EyemImage *tpDstImg);
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -815,13 +813,14 @@ typedef struct { ...@@ -815,13 +813,14 @@ typedef struct {
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
EYEM_EXPORTS int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileName, const char *ccCodeType, IntPtr *hObject, EyemBarCode **tpResult, int *ipNum, bool bUseNiBlack, int iBlockSize, const int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0); EXPORTS int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileName, const char *ccCodeType, IntPtr *hObject, EyemBarCode **tpResult, int *ipNum, bool bUseNiBlack, int iBlockSize, const int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0);
EYEM_EXPORTS bool eyemDetectAndDecodeFree(IntPtr hObject); EXPORTS bool eyemDetectAndDecodeFree(IntPtr hObject);
EYEM_EXPORTS int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char * ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char * ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EYEM_EXPORTS int eyemImageRead(const char *filename, int iFalgs, EyemImage *ucpImage); EXPORTS int eyemImageRead(const char *filename, int iFalgs, EyemImage *ucpImage);
EYEM_EXPORTS int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, EyemImage *tpImage); EXPORTS int eyemImageMalloc(int iWidth, int iHeight, int iChannels, int ccType, EyemImage *tpImage);
EYEM_EXPORTS void eyemImageFree(void *ipImage); EXPORTS int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, EyemImage *tpImage);
EXPORTS void eyemImageFree(void *ipImage);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -5,37 +5,143 @@ int eyemImageRead(const char *filename, int iFlag, EyemImage *tpImage) ...@@ -5,37 +5,143 @@ int eyemImageRead(const char *filename, int iFlag, EyemImage *tpImage)
cv::Mat src = cv::imread(filename, iFlag); cv::Mat src = cv::imread(filename, iFlag);
if (src.empty()) if (src.empty())
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
//仅支持灰度图像 //图像信息
if (src.channels() != 1) int _X = src.cols, _Y = src.rows, _Depth = src.depth(), _Channels = src.channels();
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY); //内存尺寸
// int _Size = _X*_Y*_Channels;
tpImage->iWidth = src.cols;
tpImage->iHeight = src.rows;
tpImage->iDepth = src.depth();
//仅支持8位与16位图
switch (src.depth()) switch (src.depth())
{ {
case CV_8U: case CV_8U:
tpImage->vpImage = (unsigned char *)malloc(src.cols*src.rows * sizeof(unsigned char)); _Size *= sizeof(unsigned char);
tpImage->vpImage = (unsigned char *)malloc(_Size);
if (NULL == tpImage->vpImage) if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM; return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, src.cols*src.rows * sizeof(unsigned char)); memset(tpImage->vpImage, 0, _Size);
break;
case CV_8S:
_Size *= sizeof(signed char);
tpImage->vpImage = (signed char *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break; break;
case CV_16U: case CV_16U:
tpImage->vpImage = (unsigned short *)malloc(src.cols*src.rows * sizeof(unsigned short)); _Size *= sizeof(unsigned short);
tpImage->vpImage = (unsigned short *)malloc(_Size);
if (NULL == tpImage->vpImage) if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM; return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, src.cols*src.rows * sizeof(unsigned short)); memset(tpImage->vpImage, 0, _Size);
break; break;
default: case CV_16S:
_Size *= sizeof(signed short);
tpImage->vpImage = (signed short *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_32S:
_Size *= sizeof(signed int);
tpImage->vpImage = (signed int *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_32F:
_Size *= sizeof(float);
tpImage->vpImage = (float *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_64F:
_Size *= sizeof(double);
tpImage->vpImage = (double *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break; break;
default:
//no support format
return FUNC_CANNOT_USE;
} }
//图像信息
tpImage->iWidth = _X; tpImage->iHeight = _Y; tpImage->iDepth = _Depth; tpImage->iChannels = _Channels;
//拷贝数据 //拷贝数据
int _Size = src.cols*src.rows*((src.depth() >> 1) + 1);
memcpy(tpImage->vpImage, src.data, _Size); memcpy(tpImage->vpImage, src.data, _Size);
return FUNC_OK; return FUNC_OK;
} }
int eyemImageMalloc(int iWidth, int iHeight, int iChannels, int ccType, EyemImage *tpImage)
{
//内存尺寸
int _Size = iWidth*iHeight*iChannels;
switch (ccType)
{
case CV_8U:
tpImage->iDepth = 0;
_Size *= sizeof(unsigned char);
tpImage->vpImage = (unsigned char *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_8S:
tpImage->iDepth = 1;
_Size *= sizeof(signed char);
tpImage->vpImage = (signed char *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_16U:
tpImage->iDepth = 2;
_Size *= sizeof(unsigned short);
tpImage->vpImage = (unsigned short *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_16S:
tpImage->iDepth = 3;
_Size *= sizeof(signed short);
tpImage->vpImage = (signed short *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_32S:
tpImage->iDepth = 4;
_Size *= sizeof(signed int);
tpImage->vpImage = (signed int *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_32F:
tpImage->iDepth = 5;
_Size *= sizeof(float);
tpImage->vpImage = (float *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
case CV_64F:
tpImage->iDepth = 6;
_Size *= sizeof(double);
tpImage->vpImage = (double *)malloc(_Size);
if (NULL == tpImage->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpImage->vpImage, 0, _Size);
break;
default:
//no support format
return FUNC_CANNOT_USE;
}
//图像信息
tpImage->iWidth = iWidth; tpImage->iHeight = iHeight; tpImage->iChannels = iChannels;
return FUNC_OK;
}
int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, EyemImage *tpImage) int eyemImageReadRaw(const char *filename, int iWidth, int iHeight, int iDepth, EyemImage *tpImage)
{ {
if (std::strlen(filename) == 0) if (std::strlen(filename) == 0)
...@@ -282,10 +388,14 @@ static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize) ...@@ -282,10 +388,14 @@ static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize)
int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg) int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, tpImage.iDepth, tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
if (src.empty()) { if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
//转单通道
if (src.channels() != 1)
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
cv::Mat src8U; cv::Mat src8U;
//环鸿&佳世达 //环鸿&佳世达
src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone(); src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone();
...@@ -1259,10 +1369,14 @@ int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int ...@@ -1259,10 +1369,14 @@ int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int
int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char *ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg) int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char *ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, tpImage.iDepth, tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
if (src.empty()) { if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
//转单通道
if (src.channels() != 1)
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
cv::Mat src8U; cv::Mat src8U;
//环鸿&佳世达 //环鸿&佳世达
src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone(); src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone();
...@@ -2799,5 +2913,4 @@ void eyemImageFree(void *ucpImage) ...@@ -2799,5 +2913,4 @@ void eyemImageFree(void *ucpImage)
{ {
// must be free // must be free
free(ucpImage); free(ucpImage);
ucpImage = NULL;
} }
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!