Commit 81920d8b 张士柳

添加项目文件。

1 个父辈 d730cd33
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
namespace eyemLib_Sharp
{
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);
#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);
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);
}
//释放解码句柄
public class DataCodeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public DataCodeHandle() : base(true) { }
protected override bool ReleaseHandle()
{
return eyemDetectAndDecodeFree(handle);
}
}
}
}
using System;
using System.IO;
using System.Threading.Tasks;
namespace eyemLib_Sharp
{
class Program
{
static void Main(string[] args)
{
string[] fileNames = Directory.GetFiles(@"D:\批量测试图像\", "*.*", SearchOption.AllDirectories);
//for (int j = 0; j < 100; j++)
//{
// ParallelOptions po = new ParallelOptions();
// po.MaxDegreeOfParallelism = 6;
// Parallel.ForEach(fileNames, po, fn =>
// {
// EyemLib.eyemReadImageTool(fn);
// });
// Console.Clear();
//}
foreach (var fileName in fileNames)
{
EyemLib.eyemReadImageTool(fileName);
//EyemLib.eyemReadImageToolTest(fileName);
}
Console.Write("请按任意键继续。。。");
Console.ReadKey();
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("eyemLib-Sharp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("eyemLib-Sharp")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//将 ComVisible 设置为 false 将使此程序集中的类型
//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("c5284403-d4fd-4d83-bbae-7a4020f1c01f")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>eyemLib_Sharp</RootNamespace>
<AssemblyName>eyemLib-Sharp</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EyemSamples.cs" />
<Compile Include="EyemLib.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eyemLib", "eyemLib\eyemLib.vcxproj", "{33D5F550-C799-4B05-8E14-ACA390DF5442}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eyemLib-Sharp", "eyemLib-Sharp\eyemLib-Sharp.csproj", "{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}"
ProjectSection(ProjectDependencies) = postProject
{33D5F550-C799-4B05-8E14-ACA390DF5442} = {33D5F550-C799-4B05-8E14-ACA390DF5442}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Debug|Any CPU.ActiveCfg = Debug|Win32
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Debug|x64.ActiveCfg = Debug|x64
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Debug|x64.Build.0 = Debug|x64
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Debug|x86.ActiveCfg = Debug|Win32
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Debug|x86.Build.0 = Debug|Win32
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Release|Any CPU.ActiveCfg = Release|Win32
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Release|x64.ActiveCfg = Release|x64
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Release|x64.Build.0 = Release|x64
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Release|x86.ActiveCfg = Release|Win32
{33D5F550-C799-4B05-8E14-ACA390DF5442}.Release|x86.Build.0 = Release|Win32
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Debug|x64.ActiveCfg = Debug|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Debug|x64.Build.0 = Debug|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Debug|x86.ActiveCfg = Debug|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Debug|x86.Build.0 = Debug|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Release|Any CPU.Build.0 = Release|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Release|x64.ActiveCfg = Release|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Release|x64.Build.0 = Release|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Release|x86.ActiveCfg = Release|Any CPU
{C5284403-D4FD-4D83-BBAE-7A4020F1C01F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
此文件的差异被折叠, 点击展开。
此文件的差异被折叠, 点击展开。
#pragma once
//
// eyemBarCode·标头
//
#ifndef __EYEM_BARCODE_H
#define __EYEM_BARCODE_H
#include "eyemLib.h"
#include "dmtx.h"
#include <zxing/common/Counted.h>
#include <zxing/Binarizer.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/Result.h>
#include <zxing/ReaderException.h>
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/common/HybridBinarizer.h>
#include <zxing/Exception.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/DecodeHints.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/MatSource.h>
#include <zxing\oned\MultiFormatOneDReader.h>
#include <zxing\datamatrix\DataMatrixReader.h>
#include <zxing\aztec\AztecReader.h>
#include <mutex>
#include <numeric>
#include <omp.h>
using namespace zxing;
using namespace zxing::qrcode;
std::mutex mtx;
enum {
NONE,
AZTEC,
CODABAR,
CODE_39,
CODE_93,
CODE_128,
DATA_MATRIX,
EAN_8,
EAN_13,
ITF,
MAXICODE,
PDF_417,
QR_CODE,
RSS_14,
RSS_EXPANDED,
UPC_A,
UPC_E,
UPC_EAN_EXTENSION
};
#define enumtoCharArr(val) #val
//
struct tMap
{
int Label;
cv::Point Pt;
tMap(int Label, cv::Point Pt) :Label(Label), Pt(Pt) {}
};
//预处理区域
struct WaitArea
{
double C;
double angle;
bool oneD = false;
std::vector<cv::Mat> oneDMats;
cv::Mat waitArea;
cv::Point Pt;
WaitArea(cv::Mat waitArea, cv::Point Pt, double C, double angle, bool oneD, std::vector<cv::Mat> oneDMats) :waitArea(waitArea), Pt(Pt), C(C), angle(angle), oneD(oneD), oneDMats(oneDMats) {}
};
//解码结果
struct DecodeResult
{
double dAngle;
cv::Point ptResult;
std::string strResultText;
std::string strResultType;
//构造函数
DecodeResult() {};
DecodeResult(double dAngle, cv::Point ptResult, std::string strResultText, std::string strResultType) :dAngle(dAngle), ptResult(ptResult), strResultText(strResultText), strResultType(strResultType) {}
//重载>运算符
bool operator >(const DecodeResult &te)const
{
return (*this).strResultText > te.strResultText;
}
//重载==运算符
bool operator ==(const DecodeResult &te)const
{
return strcmp((*this).strResultText.c_str(), te.strResultText.c_str()) == 0;
}
};
#endif/* __EYEM_BARCODE_H */
\ No newline at end of file
此文件的差异被折叠, 点击展开。
#pragma once
//
// eyemBinͷ
//
#ifndef __EYEM_BIN_H
#define __EYEM_BIN_H
#include "eyemLib.h"
typedef unsigned int CvLabel;
const char cvChainCodeMoves[8][2] = {
{ 0, -1 },
{ 1, -1 },
{ 1, 0 },
{ 1, 1 },
{ 0, 1 },
{ -1, 1 },
{ -1, 0 },
{ -1, -1 }
};
typedef unsigned char CvChainCode;
typedef std::list<CvChainCode> CvChainCodes;
typedef struct {
cv::Point startingPoint;
CvChainCodes chainCode;
} CvContourChainCode;
typedef std::list<CvContourChainCode *> CvContoursChainCode;
typedef struct {
CvLabel label; //ǩ
union
{
unsigned int area; //(moment 00)
unsigned int m00; //Moment 00
};
unsigned int minx; // X min.
unsigned int maxx; // X max.
unsigned int miny; // Y min.
unsigned int maxy; // Y max.
cv::Point2d centroid; //
double m10; ///< Moment 10.
double m01; ///< Moment 01.
double m11; ///< Moment 11.
double m20; ///< Moment 20.
double m02; ///< Moment 02.
double u11; ///< Central moment 11.
double u20; ///< Central moment 20.
double u02; ///< Central moment 02.
double n11; ///< Normalized central moment 11.
double n20; ///< Normalized central moment 20.
double n02; ///< Normalized central moment 02.
double p1; ///< Hu moment 1.
double p2; ///< Hu moment 2.
CvContourChainCode contour; ///< Contour.
CvContoursChainCode internalContours; ///< Internal contours.
} CvBlob;
typedef std::map<CvLabel, CvBlob *> CvBlobs;
typedef std::pair<CvLabel, CvBlob *> CvLabelBlob;
typedef std::map<CvLabel, cv::Scalar> Palete;
/// \def _HSV2RGB_(H, S, V, R, G, B)
/// \brief Color translation between HSV and RGB.
#define _HSV2RGB_(H, S, V, R, G, B) \
{ \
double _h = H/60.; \
int _hf = (int)floor(_h); \
int _hi = ((int)_h)%6; \
double _f = _h - _hf; \
\
double _p = V * (1. - S); \
double _q = V * (1. - _f * S); \
double _t = V * (1. - (1. - _f) * S); \
\
switch (_hi) \
{ \
case 0: \
R = 255.*V; G = 255.*_t; B = 255.*_p; \
break; \
case 1: \
R = 255.*_q; G = 255.*V; B = 255.*_p; \
break; \
case 2: \
R = 255.*_p; G = 255.*V; B = 255.*_t; \
break; \
case 3: \
R = 255.*_p; G = 255.*_q; B = 255.*V; \
break; \
case 4: \
R = 255.*_t; G = 255.*_p; B = 255.*V; \
break; \
case 5: \
R = 255.*V; G = 255.*_p; B = 255.*_q; \
break; \
} \
}
inline void cvReleaseBlobs(CvBlobs &blobs)
{
for (CvBlobs::iterator it = blobs.begin(); it != blobs.end(); ++it)
{
CvBlob *blob = (*it).second;
if (blob)
{
for (CvContoursChainCode::iterator jt = blob->internalContours.begin(); jt != blob->internalContours.end(); ++jt)
{
CvContourChainCode *contour = *jt;
if (contour)
delete contour;
}
blob->internalContours.clear();
delete blob;
}
}
blobs.clear();
}
#endif/* __EYEM_BIN_H */
\ No newline at end of file
#include "eyemCalib.h"
#pragma once
//
// eyemCalibͷ
//
#ifndef __EYEM_CALIB_H
#define __EYEM_CALIB_H
#include "eyemLib.h"
#endif/* __EYEM_CALIB_H */
#include "eyemLib.h"
void eyemClp2dDistanceTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, double &tpDist)
{
tpDist = std::sqrt(std::pow(tpPoint2.dX - tpPoint1.dX, 2) + std::pow(tpPoint2.dY - tpPoint1.dY, 2));
}
void eyemClp2dCenterTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY &tpCenter)
{
tpCenter.dX = (tpPoint1.dX + tpPoint2.dX) / 2.0;
tpCenter.dY = (tpPoint1.dY + tpPoint2.dY) / 2.0;
}
int eyemClp2dLineTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDABC &tpLine)
{
if ((tpPoint1.dX - tpPoint2.dX) < DBL_EPS && (tpPoint1.dY - tpPoint2.dY) < DBL_EPS)
{
return FUNC_CANNOT_CALC;
}
tpLine.dA = -(tpPoint1.dY - tpPoint2.dY);
tpLine.dB = (tpPoint1.dX - tpPoint2.dX);
tpLine.dC = tpPoint2.dX*tpPoint1.dY - tpPoint1.dX*tpPoint2.dY;
return FUNC_OK;
}
int eyemClp2dMidperpendicularTwoPoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDABC &tpLine)
{
if ((tpPoint1.dX - tpPoint2.dX) < DBL_EPS && (tpPoint1.dY - tpPoint2.dY) < DBL_EPS)
{
return FUNC_CANNOT_CALC;
}
tpLine.dA = 2 * (tpPoint2.dX - tpPoint1.dX);
tpLine.dB = 2 * (tpPoint2.dY - tpPoint1.dY);
tpLine.dC = pow(tpPoint1.dX, 2) - pow(tpPoint2.dX, 2) + pow(tpPoint1.dY, 2) - pow(tpPoint2.dY, 2);
return FUNC_OK;
}
int eyemClp2dVerticalLinePointAndLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, EyemOcsDABC &tpVertical)
{
double v = std::sqrt(std::pow(tpLine.dB, 2) + std::pow(-tpLine.dA, 2));
if (v < DBL_EPS)
{
return FUNC_CANNOT_CALC;
}
tpVertical.dA = tpLine.dB / v;
tpVertical.dB = -tpLine.dA / v;
tpVertical.dC = -tpVertical.dA*tpPoint.dX - tpVertical.dB*tpPoint.dY;
return FUNC_OK;
}
void eyemClp2dLinePointAndSlope(EyemOcsDXY tpPoint, double dSlope, EyemOcsDABC &tpLine)
{
//単位:rad
tpLine.dA = -sin(dSlope);
tpLine.dB = cos(dSlope);
tpLine.dC = -tpLine.dA*tpPoint.dX - tpLine.dB*tpPoint.dY;
}
int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDXY &tpPoint)
{
if (abs(tpLine1.dA*tpLine2.dB - tpLine2.dA*tpLine1.dB) < DBL_EPS)
{
return FUNC_CANNOT_CALC;
}
//计算系数
double sa[4], sb[2], sx[2];
cv::Mat a = cv::Mat(2, 2, CV_64F, sa), b = cv::Mat(2, 1, CV_64F, sb);
//系数矩阵A*X=B;
cv::Mat x = cv::Mat(2, 1, CV_64F, sx);
std::memset(sa, 0, sizeof(sa));
std::memset(sb, 0, sizeof(sb));
std::memset(sx, 0, sizeof(sx));
sa[0] = tpLine1.dA, sa[1] = tpLine1.dB;
sa[2] = tpLine2.dA, sa[3] = tpLine2.dB;
sb[0] = -tpLine1.dC, sb[1] = -tpLine2.dC;
//solve
cv::solve(a, b, x, cv::DECOMP_SVD);
tpPoint.dX = sx[0];
tpPoint.dY = sx[1];
return FUNC_OK;
}
int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle)
{
double det = tpLine1.dA*tpLine2.dB - tpLine2.dA*tpLine1.dB;
if (abs(det) < DBL_EPS)
{
return FUNC_CANNOT_CALC;
}
double u, v, uv;
u = sqrt(pow(tpLine1.dA, 2) + pow(tpLine1.dB, 2));
v = sqrt(pow(tpLine2.dA, 2) + pow(tpLine2.dB, 2));
uv = sqrt(pow(tpLine1.dA*tpLine2.dB - tpLine2.dA*tpLine1.dB, 2));
dpAngle = asin(uv / u*v);
return FUNC_OK;
}
int eyemClp2dCenterLineOfTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDABC &tpLineC)
{
double la, lb, lc;
la = tpLine1.dA / (sqrt(pow(tpLine1.dA, 2) + pow(tpLine1.dB, 2))) + tpLine2.dA / (sqrt(pow(tpLine2.dA, 2) + pow(tpLine2.dB, 2)));
lb = tpLine1.dB / (sqrt(pow(tpLine1.dA, 2) + pow(tpLine1.dB, 2))) + tpLine2.dB / (sqrt(pow(tpLine2.dA, 2) + pow(tpLine2.dB, 2)));
lc = tpLine1.dC / (sqrt(pow(tpLine1.dA, 2) + pow(tpLine1.dB, 2))) + tpLine2.dC / (sqrt(pow(tpLine2.dA, 2) + pow(tpLine2.dB, 2)));
tpLineC.dA = la / (sqrt(pow(la, 2) + pow(lb, 2)));
tpLineC.dB = lb / (sqrt(pow(la, 2) + pow(lb, 2)));
tpLineC.dC = lc / (sqrt(pow(la, 2) + pow(lb, 2)));
return FUNC_OK;
}
int eyemClp2dDistancePointToLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, double &dpDist)
{
dpDist = abs(tpLine.dA*tpPoint.dX + tpLine.dB*tpPoint.dY + tpLine.dC) / sqrt(tpLine.dA*tpLine.dA + tpLine.dB*tpLine.dB);
return FUNC_OK;
}
int eyemClp2dTranslationOfLine(EyemOcsDABC tpSrcL, EyemOcsDXY tpTrans, EyemOcsDABC &tpDstL)
{
tpDstL.dA = tpSrcL.dA, tpDstL.dB = tpSrcL.dB;
tpDstL.dC = tpSrcL.dC - tpSrcL.dA*tpTrans.dX - tpSrcL.dB*tpTrans.dY;
return FUNC_OK;
}
void eyemClp2dAreaTriangle(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, double &dpArea)
{
dpArea = ((tpPoint2.dX - tpPoint1.dX)*(tpPoint3.dY - tpPoint1.dY) - ((tpPoint2.dY - tpPoint1.dY)*(tpPoint3.dX - tpPoint1.dX))) / 2.0;
}
int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, EyemOcsDXYR &tpCircle)
{
//计算系数
double sa[9], sb[3];
cv::Mat a = cv::Mat(3, 3, CV_64F, sa), b = cv::Mat(3, 1, CV_64F, sb);
//系数矩阵A*X=B;
cv::Mat x = cv::Mat(3, 1, CV_64F);
std::memset(sa, 0, sizeof(sa));
std::memset(sb, 0, sizeof(sb));
sa[0] = -2.0*tpPoint1.dX, sa[1] = -2.0*tpPoint1.dY, sa[2] = 1.;
sa[3] = -2.0*tpPoint2.dX, sa[4] = -2.0*tpPoint2.dY, sa[5] = 1.;
sa[6] = -2.0*tpPoint3.dX, sa[7] = -2.0*tpPoint3.dY, sa[8] = 1.;
sb[0] = -(pow(tpPoint1.dX, 2) + pow(tpPoint1.dY, 2)),
sb[1] = -(pow(tpPoint2.dX, 2) + pow(tpPoint2.dY, 2)),
sb[2] = -(pow(tpPoint3.dX, 2) + pow(tpPoint3.dY, 2));
//solve
cv::solve(a, b, x, cv::DECOMP_SVD);
tpCircle.dX = *x.ptr<double>(0);
tpCircle.dY = *x.ptr<double>(1);
tpCircle.dR = sqrt(pow(*x.ptr<double>(0), 2) + pow(*x.ptr<double>(1), 2) - (*x.ptr<double>(2)));
return FUNC_OK;
}
#pragma once
//
// eyemClp2dͷ
//
#ifndef __EYEM_CLP2D_H
#define __EYEM_CLP2D_H
#include "eyemLib.h"
#endif/* __EYEM_CLP2D_H */
文件属性发生变化
#pragma once
//
// eyemSmooth¡¤±êÍ·
//
#ifndef __EYEM_EDLINES_H
#define __EYEM_EDLINES_H
#include "eyemLib.h"
#include <algorithm>
#include <map>
using namespace cv;
struct SEGMENT
{
float x1, y1, x2, y2, angle;
};
/**
* Detect lines in the input image.
*
* @param _image A grayscale(CV_8UC1) input image.
* If only a roi needs to be selected, use
* lsd_ptr->detect(image(roi), ..., lines);
* lines += Scalar(roi.x, roi.y, roi.x, roi.y);
* @param _lines Return: A vector of Vec4f elements specifying the beginning and ending point of
* a line. Where Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 is the end.
* Returned lines are directed so that the brighter side is placed on left.
*/
void detectE(cv::InputArray _image, cv::OutputArray _lines);
/**
* Draw lines on the given canvas.
*
* @param image The image, where lines will be drawn
* Should have the size of the image, where the lines were found
* @param lines The lines that need to be drawn
* @param draw_arrow If true, arrow heads will be drawn
*/
void drawSegmentsE(cv::InputOutputArray _image, cv::InputArray lines, bool draw_arrow = false);
int imagewidth, imageheight, threshold_length;
float threshold_dist;
double canny_th1, canny_th2;
int canny_aperture_size;
bool do_merge;
//template<class T>
//void incidentPoint(const Mat& l, T& pt);
void mergeLinesE(const SEGMENT& seg1, const SEGMENT& seg2, SEGMENT& seg_merged);
bool mergeSegmentsE(const SEGMENT& seg1, const SEGMENT& seg2, SEGMENT& seg_merged);
bool getPointChainE(const cv::Mat& img, cv::Point pt, cv::Point& chained_pt, float& direction, int step);
double distPointLineE(const cv::Mat& p, cv::Mat& l);
void extractSegmentsE(const std::vector<cv::Point2i>& points, std::vector<SEGMENT>& segments);
void lineDetectionE(const cv::Mat& src, std::vector<SEGMENT>& segments_all);
void pointInboardTestE(const cv::Mat& src, cv::Point2i& pt);
inline void getAngleE(SEGMENT& seg);
void additionalOperationsOnSegmentE(const cv::Mat& src, SEGMENT& seg);
void drawSegmentE(cv::Mat& mat, const SEGMENT& seg, cv::Scalar bgr = cv::Scalar(0, 255, 0),
int thickness = 1, bool directed = true);
#endif/* __EYEM_EDLINES_H */
\ No newline at end of file
#include"eyemEdge.h"
void thinningIteration(cv::Mat& img, int iter)
{
CV_Assert(img.channels() == 1);
CV_Assert(img.depth() != sizeof(uchar));
CV_Assert(img.rows > 3 && img.cols > 3);
cv::Mat marker = cv::Mat::zeros(img.size(), CV_8UC1);
int nRows = img.rows;
int nCols = img.cols;
if (img.isContinuous()) {
nCols *= nRows;
nRows = 1;
}
int x, y;
uchar *pAbove;
uchar *pCurr;
uchar *pBelow;
uchar *nw, *no, *ne; // north (pAbove)
uchar *we, *me, *ea;
uchar *sw, *so, *se; // south (pBelow)
uchar *pDst;
// initialize row pointers
pAbove = NULL;
pCurr = img.ptr<uchar>(0);
pBelow = img.ptr<uchar>(1);
for (y = 1; y < img.rows - 1; ++y) {
// shift the rows up by one
pAbove = pCurr;
pCurr = pBelow;
pBelow = img.ptr<uchar>(y + 1);
pDst = marker.ptr<uchar>(y);
// initialize col pointers
no = &(pAbove[0]);
ne = &(pAbove[1]);
me = &(pCurr[0]);
ea = &(pCurr[1]);
so = &(pBelow[0]);
se = &(pBelow[1]);
for (x = 1; x < img.cols - 1; ++x) {
// shift col pointers left by one (scan left to right)
nw = no;
no = ne;
ne = &(pAbove[x + 1]);
we = me;
me = ea;
ea = &(pCurr[x + 1]);
sw = so;
so = se;
se = &(pBelow[x + 1]);
int A = (*no == 0 && *ne == 1) + (*ne == 0 && *ea == 1) +
(*ea == 0 && *se == 1) + (*se == 0 && *so == 1) +
(*so == 0 && *sw == 1) + (*sw == 0 && *we == 1) +
(*we == 0 && *nw == 1) + (*nw == 0 && *no == 1);
int B = *no + *ne + *ea + *se + *so + *sw + *we + *nw;
int m1 = iter == 0 ? (*no * *ea * *so) : (*no * *ea * *we);
int m2 = iter == 0 ? (*ea * *so * *we) : (*no * *so * *we);
if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
pDst[x] = 1;
}
}
img &= ~marker;
}
static void thinning(const cv::Mat& src, cv::Mat& dst)
{
dst = src.clone();
dst /= 255; // convert to binary image
cv::Mat prev = cv::Mat::zeros(dst.size(), CV_8UC1);
cv::Mat diff;
do {
thinningIteration(dst, 0);
thinningIteration(dst, 1);
cv::absdiff(dst, prev, diff);
dst.copyTo(prev);
} while (cv::countNonZero(diff) > 0);
dst *= 255;
}
int eyemEdgesPixel(EyemImage tpImage, double dThresh)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
int X = image.cols, Y = image.rows;
uchar *upF = image.data;
/*计算偏导*/
double *dpFx = (double *)malloc(X*Y * sizeof(double));
double *dpFy = (double *)malloc(X*Y * sizeof(double));
/*梯度幅值*/
double *dpMag = (double *)malloc(X*Y * sizeof(double));
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
{
for (int x = 1; x < X - 1; x++)
{
dpFx[(x)+(y)*X] = 0.5*((double)(upF[(x + 1) + (y)*X]) - (double)(upF[(x - 1) + (y)*X]));
dpFy[(x)+(y)*X] = 0.5*((double)(upF[(x)+(y + 1)*X]) - (double)(upF[(x)+(y - 1)*X]));
dpMag[(x)+(y)*X] = sqrt(dpFx[(x)+(y)*X] * dpFx[(x)+(y)*X] + dpFy[(x)+(y)*X] * dpFy[(x)+(y)*X]);
}
}
});
unsigned char *ucpLabel = (unsigned char *)malloc(X*Y * sizeof(unsigned char));
memset(ucpLabel, 0, X*Y * sizeof(unsigned char));
cv::Mat label = cv::Mat(Y, X, CV_8UC1, ucpLabel);
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
for (int x = 1; x < (X - 1); x++)
{
if (dpMag[(x)+(y)*X] > dThresh)
{
//判断边缘
if (abs(dpFy[(x)+(y)*X]) >= abs(dpFx[(x)+(y)*X]) &&
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X]))
{
ucpLabel[(x)+(y)*X] = 255;//垂直边缘-2
}
else if (abs(dpFx[(x)+(y)*X]) > abs(dpFy[(x)+(y)*X]) &&
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X]))
{
ucpLabel[(x)+(y)*X] = 255;//水平边缘-1
}
}
}
});
//标记连通域
cv::Mat labels;
int ilabel = cv::connectedComponents(label, labels);
//绘制连通域
std::vector<cv::Vec3b> labelColor(ilabel);
for (int i = 0; i < ilabel; i++)
{
labelColor[i] = cv::Vec3b(rand() % 256, rand() % 256, rand() % 256);
}
cv::Mat labelImage;
cv::cvtColor(image, labelImage, cv::COLOR_GRAY2BGR);
for (int y = 1; y < Y - 1; y++)
{
for (int x = 1; x < X - 1; x++)
{
int lb = labels.at<int>(y, x);
if (lb != 0)
{
labelImage.at<cv::Vec3b>(y, x) = labelColor[lb];
}
}
}
//释放资源
free((void *)ucpLabel);
free((void *)dpFx);
free((void *)dpFy);
free((void *)dpMag);
return FUNC_OK;
}
int eyemEdgesSubpixel(EyemImage tpImage, int iFilter, int iLow, int iHigh)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
int X = image.cols, Y = image.rows;
uchar *upF = image.data;
/*计算偏导*/
double *dpFx = (double *)malloc(X*Y * sizeof(double));
double *dpFy = (double *)malloc(X*Y * sizeof(double));
/*梯度幅值*/
double *dpMag = (double *)malloc(X*Y * sizeof(double));
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
{
for (int x = 1; x < X - 1; x++)
{
dpFx[(x)+(y)*X] = 0.5*((double)(upF[(x + 1) + (y)*X]) - (double)(upF[(x - 1) + (y)*X]));
dpFy[(x)+(y)*X] = 0.5*((double)(upF[(x)+(y + 1)*X]) - (double)(upF[(x)+(y - 1)*X]));
dpMag[(x)+(y)*X] = sqrt(dpFx[(x)+(y)*X] * dpFx[(x)+(y)*X] + dpFy[(x)+(y)*X] * dpFy[(x)+(y)*X]);
}
}
});
unsigned char *ucpLabel = (unsigned char *)malloc(X*Y * sizeof(unsigned char));
memset(ucpLabel, 0, X*Y * sizeof(unsigned char));
cv::Mat label = cv::Mat(Y, X, CV_8UC1, ucpLabel);
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
for (int x = 1; x < (X - 1); x++)
{
if (dpMag[(x)+(y)*X] > 25)
{
//判断边缘
if (abs(dpFy[(x)+(y)*X]) >= abs(dpFx[(x)+(y)*X]) &&
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X]))
{
ucpLabel[(x)+(y)*X] = 255;//垂直边缘-2
}
else if (abs(dpFx[(x)+(y)*X]) > abs(dpFy[(x)+(y)*X]) &&
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X]))
{
ucpLabel[(x)+(y)*X] = 255;//水平边缘-1
}
}
}
});
cv::Mat labels;
cv::connectedComponents(label, labels);
//所有边缘
EyemOcsDXY temp;
std::vector<EyemOcsDXY> edges;
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
for (int x = 1; x < (X - 1); x++)
{
if (ucpLabel[(x)+(y)*X] != 0)
{
//判断边缘
if (abs(dpFy[(x)+(y)*X]) >= abs(dpFx[(x)+(y)*X]) &&
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X]))
{
//垂直边缘
double a, b, c, u;
a = dpMag[(x)+(y - 1)*X];
b = dpMag[(x)+(y)*X];
c = dpMag[(x)+(y + 1)*X];
u = 0.5*(a - c) / (a - b - b + c);
temp.dX = (float)x + 0.5f;
temp.dY = (float)y + 0.5f + (float)u;
edges.push_back(temp);
}
else if (abs(dpFx[(x)+(y)*X]) > abs(dpFy[(x)+(y)*X]) &&
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X]))
{
//水平边缘
double a, b, c, u;
a = dpMag[(x - 1) + (y)*X];
b = dpMag[(x)+(y)*X];
c = dpMag[(x + 1) + (y)*X];
u = 0.5*(a - c) / (a - b - b + c);
temp.dX = (float)x + 0.5f + (float)u;
temp.dY = (float)y + 0.5f;
edges.push_back(temp);
}
}
}
});
//cv::RNG rng;
//cv::Mat show;
//cv::cvtColor(image.clone(), show, cv::COLOR_GRAY2BGR);
//int cnt = 0;
//for (int i = 0; i < contours.size(); i++)
//{
// cv::Vec3b color = cv::Vec3b(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
// for (int j = 0; j < contours[i].size(); j++)
// {
// cnt++;
// show.at<cv::Vec3b>(contours[i][j]) = color;
// }
// //drawContours(show, contours, i, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3);
//}
//释放资源
free((void *)ucpLabel);
free((void *)dpFx);
free((void *)dpFy);
free((void *)dpMag);
return FUNC_OK;
}
int eyemSobelAmp(EyemImage tpImage, EyemImage &ImaAmp)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
cv::Mat dx, dy;
cv::spatialGradient(image, dx, dy);
cv::Mat mag;
cv::magnitude(dx, dy, mag);
return FUNC_OK;
}
int eyemSkeleton(EyemImage tpImage, cv::Mat &skeleton)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
thinning(image, skeleton);
return FUNC_OK;
}
int eyemAutoCanny(EyemImage tpImage, double dSigma = 0.33)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
cv::Mat F;
cv::GaussianBlur(image, F, cv::Size(3, 3), 0, 0);
////get the median value of the matrix
//double v = medianMat(output);
////generate the thresholds
//int lower = (int)std::max(0.0, (1, 0 - sigma)*v);
//int upper = (int)std::min(255.0, (1, 0 + sigma)*v);
////apply canny operator
//cv::Canny(output, output, lower, upper, 3);
return FUNC_OK;
}
#pragma once
//
// eyemEdgeͷ
//
#ifndef __EYEM_EDGE_H
#define __EYEM_EDGE_H
#include "eyemLib.h"
#include "eyemGeneric.h"
#endif/* __EYEM_EDGE_H */
\ No newline at end of file
此文件的差异被折叠, 点击展开。
#pragma once
//
// eyemEdge1dͷ
//
#ifndef __EYEM_EDGE1D_H
#define __EYEM_EDGE1D_H
#include "eyemLib.h"
#include "eyemGeneric.h"
#endif/* __EYEM_EDGE1D_H */
\ No newline at end of file
此文件的差异被折叠, 点击展开。
#pragma once
//
// eyemFit·标头
//
#ifndef __EYEM_FIT_H
#define __EYEM_FIT_H
#include "eyemLib.h"
struct EyemOcsDXY2D {
double dE; //误差类似于计分功能,越小分数越高
double dX, dY; //坐标位置
bool bValid = true; //指示该点是否参与计算
EyemOcsDXY2D() {}
EyemOcsDXY2D(double dE, double dX, double dY, bool bValid) :dE(dE), dX(dX), dY(dY), bValid(bValid) {}
bool operator <(const EyemOcsDXY2D &te)const
{
return dE < te.dE;
}
bool operator >(const EyemOcsDXY2D &te)const
{
return dE > te.dE;
}
};
struct EyemOcsDXYZ3D {
double dE; //误差类似于计分功能,越小分数越高
double dX, dY, dZ; //坐标位置
bool bValid = true; //指示该点是否参与计算
EyemOcsDXYZ3D() {}
EyemOcsDXYZ3D(double dE, double dX, double dY, double dZ, bool bValid) :dE(dE), dX(dX), dY(dY), dZ(dZ), bValid(bValid) {}
bool operator <(const EyemOcsDXYZ3D &te)const
{
return dE < te.dE;
}
bool operator >(const EyemOcsDXYZ3D &te)const
{
return dE > te.dE;
}
};
#endif/* __EYEM_FIT_H */
\ No newline at end of file
#include "eyemGeneric.h"
cv::Mat convert(cv::Mat& src, const int depth)
{
cv::Mat ret;
src.convertTo(ret, depth);
return ret;
}
void spatialGradient(cv::Mat src, cv::Mat &dx, cv::Mat &dy)
{
cv::Sobel(src, dx, src.depth(), 1, 0);
cv::Sobel(src, dy, src.depth(), 0, 1);
}
\ No newline at end of file
#pragma once
//
// eyemEdge¡¤±êÍ·
//
#ifndef __EYEM_GENERIC_H
#define __EYEM_GENERIC_H
#include "eyemLib.h"
cv::Mat convert(cv::Mat &src, const int depth);
void spatialGradient(cv::Mat src, cv::Mat &dx, cv::Mat &dy);
#endif/* __EYEM_GENERIC_H */
\ No newline at end of file
#include "eyemLib.h"
int main()
{
//char* filename = "D:\\Matlabͼ\\circle_plate_04.png";
//cv::Mat src = cv::imread(filename, cv::IMREAD_GRAYSCALE);
//EyemImage tpImage;
//tpImage.iHeight = src.rows;
//tpImage.iWidth = src.cols;
//tpImage.ucpImage = src.data;
//EyemRect tpRoi;
//tpRoi.iXs = 0;
//tpRoi.iYs = 0;
//tpRoi.iWidth = src.cols;
//tpRoi.iHeight = src.rows;
//int blobNum;
//IntPtr intptr;
//EyemBinBlob *blobs;
//eyemBinBlob(tpImage, tpRoi, 120, EYEM_BIN_WHITE, 1200, &intptr, &blobs, &blobNum);
////must be dispose
//eyemBinFree(intptr);
return 0;
}
\ No newline at end of file
此文件的差异被折叠, 点击展开。
此文件类型无法预览
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{33D5F550-C799-4B05-8E14-ACA390DF5442}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>eyemLib</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;$(IncludePath)</IncludePath>
<LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\zxing-cpp-master\build\Debug;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>D:\opencv420\build\include;D:\opencv420\build\include\opencv2;D:\zxing-cpp-master\core\src;D:\zxing-cpp-master\opencv\src;$(IncludePath)</IncludePath>
<LibraryPath>D:\opencv420\build\x64\vc14\lib;D:\zxing-cpp-master\build\Release;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;HYCOMMONWINAPI_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WholeProgramOptimization>false</WholeProgramOptimization>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libzxing-debug.lib;libdmtx.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<OpenMPSupport>true</OpenMPSupport>
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libdmtx.lib;libzxing.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="eyemBarCode.h" />
<ClInclude Include="eyemBin.h" />
<ClInclude Include="eyemCalib.h" />
<ClInclude Include="eyemClp2d.h" />
<ClInclude Include="eyemEdge.h" />
<ClInclude Include="eyemEdge1d.h" />
<ClInclude Include="eyemEDLinesDetector.h" />
<ClInclude Include="eyemFit.h" />
<ClInclude Include="eyemGeneric.h" />
<ClInclude Include="eyemLib.h" />
<ClInclude Include="eyemMat.h" />
<ClInclude Include="eyemMath.h" />
<ClInclude Include="eyemMisc.h" />
<ClInclude Include="eyemSmooth.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="eyemBarCode.cpp" />
<ClCompile Include="eyemBin.cpp" />
<ClCompile Include="eyemCalib.cpp" />
<ClCompile Include="eyemCg.cpp" />
<ClCompile Include="eyemClp2d.cpp" />
<ClCompile Include="eyemClp3d.cpp" />
<ClCompile Include="eyemEdge.cpp" />
<ClCompile Include="eyemEdge1d.cpp" />
<ClCompile Include="eyemEDLinesDetector.cpp" />
<ClCompile Include="eyemFit.cpp" />
<ClCompile Include="eyemGeneric.cpp" />
<ClCompile Include="eyemLib.cpp" />
<ClCompile Include="eyemMat.cpp" />
<ClCompile Include="eyemMatch.cpp" />
<ClCompile Include="eyemMath.cpp" />
<ClCompile Include="eyemMisc.cpp" />
<ClCompile Include="eyemSmooth.cpp" />
<ClCompile Include="libopencv.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="eyemLib.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="eyemLib.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="eyemBin.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemEdge1d.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemFit.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemMisc.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemClp2d.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemMat.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemCalib.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="eyemMath.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemSmooth.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemEdge.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemGeneric.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemBarCode.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemEDLinesDetector.h">
<Filter>源文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="eyemLib.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="libopencv.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemMath.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemFit.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemClp2d.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemClp3d.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemCg.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemBin.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemEdge1d.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemMatch.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemCalib.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemSmooth.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemMisc.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemMat.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemEdge.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemGeneric.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemBarCode.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemEDLinesDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="eyemLib.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
\ No newline at end of file
#include "eyemMat.h"
//CvMat *eyemMatMallocMatrix(int iRows, int iCols, void *vpData)
//{
// CvMat *dpMat = cvCreateMat(iRows, iCols, CV_64F);
// cvInitMatHeader(dpMat, iRows, iCols, CV_64F, vpData);
// return dpMat;
//}
//
//void eyemMatFreeMatrix(CvMat *dpMat)
//{
// cvReleaseMat(&dpMat);
//}
//
//void eyemMatZero(CvMat *dpMat)
//{
// cvSetZero(dpMat);
//}
//
//void eyemMatCopy(CvMat *vpDst, CvMat *vpSrc)
//{
// vpDst = cvCloneMat(vpSrc);
//}
//
//void eyemMatAdd(CvMat *vpA, CvMat *vpB, CvMat *vpC)
//{
// cvAdd(vpA, vpB, vpC);
//}
\ No newline at end of file
#pragma once
//
// eyemMatͷ
//
#ifndef __EYEM_MAT_H
#define __EYEM_MAT_H
#include "eyemLib.h"
#endif/* __EYEM_MAT_H */
文件属性发生变化
#include "eyemMath.h"
double eyemMathCalcInnerProduct(int, double[], double[]);
void eyemMathCalcOuterProduct(double[], double[], double[]);
int eyemMathCalcAngle(int, double[], double[], double *);
double eyemMathCalcNorm(int, double[]);
double eyemMathCalcArgument(double[]);
int eyemMathNormalization(int, double[]);
int eyemMathStat(int, double[], double *, double *, double *);
double eyemMathMedianI(int, int *);
double eyemMathMedianD(int, double *);
int eyemMathOtsuThreshold1d(int, double[], double *);
double eyemMathAreaTriangle(double, double, double, double, double, double);
double eyemMathSignAreaTriangle(double, double, double, double, double, double);
void eyemMathRotatePoint(double, double, double, double, double, double *, double *);
void eyemMathCreateTransParam(int, double, double, double, double, double *, double *, double *);
void eyemMathTransCoordOfPoint(double, double, double, double, double, double *, double *);
void eyemMathInvTransCoordOfPoint(double, double, double, double, double, double *, double *);
void eyemMathComposeCoord(double, double, double, double, double, double, double *, double *, double *);
double eyemMathInvMatrixOfSyn3X3(double[][3], double[][3]);
void eyemMathInvCoord(double, double, double, double *, double *, double *);
double eyemMathGetDistFromPointToPoint(double, double, double, double);
double eyemMathGetDistFromPointToLine(double, double, double, double, double);
double eyemMathGetDistAndCrossPointFromPointToLine(double, double, double, double, double, double *, double *);
double eyemMathGetDistFromPointToCircle(double, double, double, double, double, double *, double *);
int eyemMathGetDistFromPointToEllipse(double, double, double, double, double, double, double, double *, double *, double *);
int eyemMathCrossPoint(double, double, double, double, double, double, double *, double *);
void eyemMathTransAbcToRq(double, double, double, double *, double *);
double eyemMathCrossAngle(double, double, double, double, double, double);
int eyemMathGetLineFrom2Points(double, double, double, double, double *, double *, double *);
void eyemMathGetOrthogonalLineFromLineAndPoint(double, double, double, double, double *, double *, double *);
int eyemMathCheckAngle(double, double, double);
double eyemMathAddAngle(int, int, double, double);
double eyemMathPrimeAngle(int, int, double);
double eyemMathExtremumOfQuadraticCurves(double, double, double, double *);
double eyemMathExtremumOfQuadraticSurface(double, double, double, double, double, double, double *, double *);
double eyemMathCrossCorrelation(int, double[], double[]);
int eyemMathAutoCorrelation(int, double[], int, double[]);
double eyemMathNormCorrelation(int, double[], double[]);
int eyemMathNormAutoCorrelation(int, double[], int, double[]);
int eyemMathSearchOf1DWithNormCorrelation(int, double[], int, double[], int *, double *);
int eyemMathQuadraticRoots(double[], double[]);
int eyemMathCubicRoots(double[], double[]);
int eyemMathQuarticRoots(double[], double[]);
double eyemMathHorner(int, double[], double);
void eyemMathTransCoord(double, double, double, double, double, double *, double *);
\ No newline at end of file
#pragma once
//
// eyemMathͷ
//
#ifndef __EYEM_MATH_H
#define __EYEM_MATH_H
#include "eyemLib.h"
#endif/* __EYEM_MATH_H */
此文件的差异被折叠, 点击展开。
#pragma once
//
// eyemMiscͷ
//
#ifndef __EYEM_MISC_H
#define __EYEM_MISC_H
#include <omp.h>
#include <io.h>
#include <direct.h>
#include "eyemLib.h"
constexpr double c = PI / 180.;
#endif/* __EYEM_MISC_H */
#include "eyemSmooth.h"
int eyemSmoothMean(EyemImage tpImage, int kSizew, int kSizeh, EyemImage *tpDstImg)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
cv::Mat dstImage;
cv::blur(image, dstImage, cv::Size(kSizew, kSizeh));
return FUNC_OK;
}
int eyemSmoothGaussian(EyemImage tpImage, int kSizew, int kSizeh, double dSigmaX, double dSigmaY, EyemImage *tpDstImg)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
cv::Mat dstImage;
cv::GaussianBlur(image, dstImage, cv::Size(kSizew, kSizeh), dSigmaX, dSigmaY);
return FUNC_OK;
}
int eyemSmoothMedian(EyemImage tpImage, int kSize, EyemImage *tpDstImg)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
cv::Mat dstImage;
cv::medianBlur(image, dstImage, kSize);
return FUNC_OK;
}
\ No newline at end of file
#pragma once
//
// eyemSmoothͷ
//
#ifndef __EYEM_SMOOTH_H
#define __EYEM_SMOOTH_H
#include "eyemLib.h"
#endif/* __EYEM_SMOOTH_H */
\ No newline at end of file
此文件类型无法预览
#ifdef _DEBUG
//#pragma comment( lib, "IlmImfd.lib" )
//#pragma comment( lib, "ippicvmt.lib" )
//#pragma comment( lib, "ippiwd.lib" )
//#pragma comment( lib, "ittnotifyd.lib" )
//#pragma comment( lib, "libjasperd.lib" )
//#pragma comment( lib, "libjpeg-turbod.lib" )
//#pragma comment( lib, "libpngd.lib" )
//#pragma comment( lib, "libprotobufd.lib" )
//#pragma comment( lib, "libtiffd.lib" )
//#pragma comment( lib, "libwebpd.lib" )
//#pragma comment( lib, "quircd.lib" )
//#pragma comment( lib, "zlibd.lib" )
#pragma comment( lib, "opencv_world420d.lib" )
#else
//#pragma comment( lib, "IlmImf.lib" )
//#pragma comment( lib, "ippicvmt.lib" )
//#pragma comment( lib, "ippiw.lib" )
//#pragma comment( lib, "ittnotify.lib" )
//#pragma comment( lib, "libjasper.lib" )
//#pragma comment( lib, "libjpeg-turbo.lib" )
//#pragma comment( lib, "libpng.lib" )
//#pragma comment( lib, "libprotobuf.lib" )
//#pragma comment( lib, "libtiff.lib" )
//#pragma comment( lib, "libwebp.lib" )
//#pragma comment( lib, "quirc.lib" )
//#pragma comment( lib, "zlib.lib" )
#pragma comment( lib, "opencv_world420.lib" )
#endif
此文件类型无法预览
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by eyemLib.rc
// ¶һĬֵ
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!