Commit 1181d725 张士柳

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