diff --git a/deploy/cpp_dll/.clang-format b/deploy/cpp_dll/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..8b5830627348c6bff12260b7d9adbd357f074718 --- /dev/null +++ b/deploy/cpp_dll/.clang-format @@ -0,0 +1,27 @@ +# This file is used by clang-format to autoformat paddle source code +# +# The clang-format is part of llvm toolchain. +# It need to install llvm and clang to format source code style. +# +# The basic usage is, +# clang-format -i -style=file PATH/TO/SOURCE/CODE +# +# The -style=file implicit use ".clang-format" file located in one of +# parent directory. +# The -i means inplace change. +# +# The document of clang-format is +# http://clang.llvm.org/docs/ClangFormat.html +# http://clang.llvm.org/docs/ClangFormatStyleOptions.html +--- +Language: Cpp +BasedOnStyle: Google +IndentWidth: 2 +TabWidth: 2 +ContinuationIndentWidth: 4 +AccessModifierOffset: -1 # The private/protected/public has no indent in class +Standard: Cpp11 +AllowAllParametersOfDeclarationOnNextLine: true +BinPackParameters: false +BinPackArguments: false +... diff --git a/deploy/cpp_dll/C#_dll/.vs/WindowsFormsApp1/v16/.suo b/deploy/cpp_dll/C#_dll/.vs/WindowsFormsApp1/v16/.suo new file mode 100644 index 0000000000000000000000000000000000000000..107fc2d51a82184287e0d23361ae2c69f5c3d9c9 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/.vs/WindowsFormsApp1/v16/.suo differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1.sln b/deploy/cpp_dll/C#_dll/WindowsFormsApp1.sln new file mode 100644 index 0000000000000000000000000000000000000000..536047309e1bc28b524f5f721bbeedbc1c04a5eb --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApp1", "WindowsFormsApp1\WindowsFormsApp1.csproj", "{39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Debug|x64.ActiveCfg = Debug|x64 + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Debug|x64.Build.0 = Debug|x64 + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Release|Any CPU.Build.0 = Release|Any CPU + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Release|x64.ActiveCfg = Release|x64 + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F9C00A5F-6C78-41A8-959B-6977B6C1D15E} + EndGlobalSection +EndGlobal diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/App.config b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/App.config new file mode 100644 index 0000000000000000000000000000000000000000..56efbc7b5f15b5166cc89dae0406895b57de0b67 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.Designer.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..b0c296e3723563924d020e3bc364dac3397ed747 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.Designer.cs @@ -0,0 +1,61 @@ +namespace WindowsFormsApp1 +{ + partial class Form1 + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(129, 72); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(129, 74); + this.button1.TabIndex = 0; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.button1); + this.Name = "Form1"; + this.Text = "Form1"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button1; + } +} + diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.cs new file mode 100644 index 0000000000000000000000000000000000000000..4f952de678f4b932164cfbbfbb54e14b353ad83f --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Runtime.InteropServices; +namespace WindowsFormsApp1 +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + } + [DllImport("detector.dll", EntryPoint = "Loadmodel", CharSet = CharSet.Ansi)] + public static extern void test(); + private void button1_Click(object sender, EventArgs e) + { + test(); + } + } +} diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.resx b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.resx new file mode 100644 index 0000000000000000000000000000000000000000..1af7de150c99c12dd67a509fe57c10d63e4eeb04 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Program.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Program.cs new file mode 100644 index 0000000000000000000000000000000000000000..4ef037cc0656057b9d6aad4299728bb9abfb3c4c --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WindowsFormsApp1 +{ + static class Program + { + /// + /// 应用程序的主入口点。 + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/AssemblyInfo.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000000000000000000000000000000000..0b5c000083d8e75ebaac6cd3f46afaf69294faf3 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("WindowsFormsApp1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WindowsFormsApp1")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("39044b60-f2a8-4b9f-8e65-9f87baec83bd")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Resources.Designer.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Resources.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..fda36f79743d08a957316480a25a4876540da62b --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本: 4.0.30319.42000 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,则所做更改将丢失。 +// +//------------------------------------------------------------------------------ + +namespace WindowsFormsApp1.Properties +{ + + + /// + /// 强类型资源类,用于查找本地化字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// 返回此类使用的缓存 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApp1.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 覆盖当前线程的 CurrentUICulture 属性 + /// 使用此强类型的资源类的资源查找。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Resources.resx b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Resources.resx new file mode 100644 index 0000000000000000000000000000000000000000..af7dbebbacef595e3089c01c05671016c21a8304 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Settings.Designer.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Settings.Designer.cs new file mode 100644 index 0000000000000000000000000000000000000000..438df21381ac484a2b9663978736c524d8e8f3bf --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace WindowsFormsApp1.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Settings.settings b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Settings.settings new file mode 100644 index 0000000000000000000000000000000000000000..39645652af62950ebf3b28ec3a5400dcec30b1c4 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/WindowsFormsApp1.csproj b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/WindowsFormsApp1.csproj new file mode 100644 index 0000000000000000000000000000000000000000..ca8638487c961c2f25cdbdb481eabbdbe76cfd54 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/WindowsFormsApp1.csproj @@ -0,0 +1,105 @@ + + + + + Debug + AnyCPU + {39044B60-F2A8-4B9F-8E65-9F87BAEC83BD} + WinExe + WindowsFormsApp1 + WindowsFormsApp1 + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + \ No newline at end of file diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.exe b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.exe new file mode 100644 index 0000000000000000000000000000000000000000..cd461533640c2f4a67b9e3ed81e2e2e3ced838ed Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.exe differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.exe.config b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.exe.config new file mode 100644 index 0000000000000000000000000000000000000000..56efbc7b5f15b5166cc89dae0406895b57de0b67 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.exe.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.pdb b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.pdb new file mode 100644 index 0000000000000000000000000000000000000000..83c7442aa2aeb6d5f9d15863438ad34051777886 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/bin/x64/Debug/WindowsFormsApp1.pdb differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs new file mode 100644 index 0000000000000000000000000000000000000000..3871b184d3f475a3c71d56db9f48c2a193080512 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/DesignTimeResolveAssemblyReferences.cache new file mode 100644 index 0000000000000000000000000000000000000000..e74e8158dd2d8e92134ef5c5918e556b8028445c Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000000000000000000000000000000000000..0fea49ca9c6d00f27bf3e78baa9247532717d26e Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/WindowsFormsApp1.csprojAssemblyReference.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/WindowsFormsApp1.csprojAssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..b9d4fdce2676c1ef993093dc0374e09865129e10 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/Debug/WindowsFormsApp1.csprojAssemblyReference.cache differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs new file mode 100644 index 0000000000000000000000000000000000000000..3871b184d3f475a3c71d56db9f48c2a193080512 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000000000000000000000000000000000000..42cabff7c8e1f2d796c567c91a8b115c539c6100 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.Form1.resources b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.Form1.resources new file mode 100644 index 0000000000000000000000000000000000000000..6c05a9776bd7cbae976fdcec7e3a254e93018279 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.Form1.resources differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.Properties.Resources.resources b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.Properties.Resources.resources new file mode 100644 index 0000000000000000000000000000000000000000..6c05a9776bd7cbae976fdcec7e3a254e93018279 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.Properties.Resources.resources differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.CoreCompileInputs.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000000000000000000000000000000000000..caaa81f121cb04592161198480ed44a40d9d676f --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +d63ae25ae22a16b1f83e8cb2d7c50f73cb438914 diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.FileListAbsolute.txt b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.FileListAbsolute.txt new file mode 100644 index 0000000000000000000000000000000000000000..805e28b41917b333392f20dc7ba1b5232cab3010 --- /dev/null +++ b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.FileListAbsolute.txt @@ -0,0 +1,10 @@ +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\bin\x64\Debug\WindowsFormsApp1.exe.config +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\bin\x64\Debug\WindowsFormsApp1.exe +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\bin\x64\Debug\WindowsFormsApp1.pdb +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.csprojAssemblyReference.cache +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.Form1.resources +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.Properties.Resources.resources +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.csproj.GenerateResource.cache +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.csproj.CoreCompileInputs.cache +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.exe +C:\Users\Zhiliang.Yu\Desktop\pp\WindowsFormsApp1\WindowsFormsApp1\obj\x64\Debug\WindowsFormsApp1.pdb diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.GenerateResource.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.GenerateResource.cache new file mode 100644 index 0000000000000000000000000000000000000000..065408060364cadc8574afa464c255d21de45fc9 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csproj.GenerateResource.cache differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csprojAssemblyReference.cache b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csprojAssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..cabaf84b764635b1fdee28373784c021694b96c4 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.csprojAssemblyReference.cache differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.exe b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.exe new file mode 100644 index 0000000000000000000000000000000000000000..cd461533640c2f4a67b9e3ed81e2e2e3ced838ed Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.exe differ diff --git a/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.pdb b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.pdb new file mode 100644 index 0000000000000000000000000000000000000000..83c7442aa2aeb6d5f9d15863438ad34051777886 Binary files /dev/null and b/deploy/cpp_dll/C#_dll/WindowsFormsApp1/obj/x64/Debug/WindowsFormsApp1.pdb differ diff --git a/deploy/cpp_dll/CMakeLists.txt b/deploy/cpp_dll/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e8fa9e012f9fce0729cd93b31c2373614ad3e745 --- /dev/null +++ b/deploy/cpp_dll/CMakeLists.txt @@ -0,0 +1,302 @@ +cmake_minimum_required(VERSION 3.0) +project(PaddleX CXX C) + +option(WITH_MKL "Compile demo with MKL/OpenBlas support,defaultuseMKL." ON) +option(WITH_GPU "Compile demo with GPU/CPU, default use CPU." ON) +option(WITH_STATIC_LIB "Compile demo with static/shared library, default use static." OFF) +option(WITH_TENSORRT "Compile demo with TensorRT." OFF) +option(WITH_ENCRYPTION "Compile demo with encryption tool." OFF) + +SET(TENSORRT_DIR "" CACHE PATH "Location of libraries") +SET(PADDLE_DIR "" CACHE PATH "Location of libraries") +SET(OPENCV_DIR "" CACHE PATH "Location of libraries") +SET(ENCRYPTION_DIR"" CACHE PATH "Location of libraries") +SET(CUDA_LIB "" CACHE PATH "Location of libraries") + +if (NOT WIN32) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/demo) +else() + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/paddlex_inference) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/paddlex_inference) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/paddlex_inference) +endif() + +if (NOT WIN32) + SET(YAML_BUILD_TYPE ON CACHE BOOL "yaml build shared library.") +else() + SET(YAML_BUILD_TYPE OFF CACHE BOOL "yaml build shared library.") +endif() +include(cmake/yaml-cpp.cmake) + +include_directories("${CMAKE_SOURCE_DIR}/") +include_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/yaml-cpp/src/ext-yaml-cpp/include") +link_directories("${CMAKE_CURRENT_BINARY_DIR}/ext/yaml-cpp/lib") + +macro(safe_set_static_flag) + foreach(flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) +endmacro() + + +if (WITH_ENCRYPTION) +add_definitions( -DWITH_ENCRYPTION=${WITH_ENCRYPTION}) +endif() + +if (WITH_MKL) + ADD_DEFINITIONS(-DUSE_MKL) +endif() + +if (NOT DEFINED PADDLE_DIR OR ${PADDLE_DIR} STREQUAL "") + message(FATAL_ERROR "please set PADDLE_DIR with -DPADDLE_DIR=/path/paddle_influence_dir") +endif() + +if (NOT DEFINED OPENCV_DIR OR ${OPENCV_DIR} STREQUAL "") + message(FATAL_ERROR "please set OPENCV_DIR with -DOPENCV_DIR=/path/opencv") +endif() + +include_directories("${CMAKE_SOURCE_DIR}/") +include_directories("${PADDLE_DIR}/") +include_directories("${PADDLE_DIR}/third_party/install/protobuf/include") +include_directories("${PADDLE_DIR}/third_party/install/glog/include") +include_directories("${PADDLE_DIR}/third_party/install/gflags/include") +include_directories("${PADDLE_DIR}/third_party/install/xxhash/include") +if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/include") + include_directories("${PADDLE_DIR}/third_party/install/snappy/include") +endif() +if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/include") + include_directories("${PADDLE_DIR}/third_party/install/snappystream/include") +endif() +include_directories("${PADDLE_DIR}/third_party/install/zlib/include") +include_directories("${PADDLE_DIR}/third_party/boost") +include_directories("${PADDLE_DIR}/third_party/eigen3") + +if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/lib") + link_directories("${PADDLE_DIR}/third_party/install/snappy/lib") +endif() +if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/lib") + link_directories("${PADDLE_DIR}/third_party/install/snappystream/lib") +endif() + +link_directories("${PADDLE_DIR}/third_party/install/zlib/lib") +link_directories("${PADDLE_DIR}/third_party/install/protobuf/lib") +link_directories("${PADDLE_DIR}/third_party/install/glog/lib") +link_directories("${PADDLE_DIR}/third_party/install/gflags/lib") +link_directories("${PADDLE_DIR}/third_party/install/xxhash/lib") +link_directories("${PADDLE_DIR}/paddle/lib/") +link_directories("${CMAKE_CURRENT_BINARY_DIR}") + +if (WIN32) + include_directories("${PADDLE_DIR}/paddle/fluid/inference") + include_directories("${PADDLE_DIR}/paddle/include") + link_directories("${PADDLE_DIR}/paddle/fluid/inference") + find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR}/build/ NO_DEFAULT_PATH) + unset(OpenCV_DIR CACHE) +else () + find_package(OpenCV REQUIRED PATHS ${OPENCV_DIR}/share/OpenCV NO_DEFAULT_PATH) + include_directories("${PADDLE_DIR}/paddle/include") + link_directories("${PADDLE_DIR}/paddle/lib") +endif () +include_directories(${OpenCV_INCLUDE_DIRS}) + +if (WIN32) + add_definitions("/DGOOGLE_GLOG_DLL_DECL=") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /bigobj /MTd") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /bigobj /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj /MTd") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /bigobj /MT") + if (WITH_STATIC_LIB) + safe_set_static_flag() + add_definitions(-DSTATIC_LIB) + endif() +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -o2 -fopenmp -std=c++11") + set(CMAKE_STATIC_LIBRARY_PREFIX "") +endif() + +if (WITH_GPU) + if (NOT DEFINED CUDA_LIB OR ${CUDA_LIB} STREQUAL "") + message(FATAL_ERROR "please set CUDA_LIB with -DCUDA_LIB=/path/cuda/lib64") + endif() + if (NOT WIN32) + if (NOT DEFINED CUDNN_LIB) + message(FATAL_ERROR "please set CUDNN_LIB with -DCUDNN_LIB=/path/cudnn/") + endif() + endif(NOT WIN32) +endif() + + +if (NOT WIN32) + if (WITH_TENSORRT AND WITH_GPU) + include_directories("${TENSORRT_DIR}/include") + link_directories("${TENSORRT_DIR}/lib") + endif() +endif(NOT WIN32) + +if (NOT WIN32) + set(NGRAPH_PATH "${PADDLE_DIR}/third_party/install/ngraph") + if(EXISTS ${NGRAPH_PATH}) + include(GNUInstallDirs) + include_directories("${NGRAPH_PATH}/include") + link_directories("${NGRAPH_PATH}/${CMAKE_INSTALL_LIBDIR}") + set(NGRAPH_LIB ${NGRAPH_PATH}/${CMAKE_INSTALL_LIBDIR}/libngraph${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() +endif() + +if(WITH_MKL) + include_directories("${PADDLE_DIR}/third_party/install/mklml/include") + if (WIN32) + set(MATH_LIB ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.lib + ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.lib) + else () + set(MATH_LIB ${PADDLE_DIR}/third_party/install/mklml/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} + ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5${CMAKE_SHARED_LIBRARY_SUFFIX}) + execute_process(COMMAND cp -r ${PADDLE_DIR}/third_party/install/mklml/lib/libmklml_intel${CMAKE_SHARED_LIBRARY_SUFFIX} /usr/lib) + endif () + set(MKLDNN_PATH "${PADDLE_DIR}/third_party/install/mkldnn") + if(EXISTS ${MKLDNN_PATH}) + include_directories("${MKLDNN_PATH}/include") + if (WIN32) + set(MKLDNN_LIB ${MKLDNN_PATH}/lib/mkldnn.lib) + else () + set(MKLDNN_LIB ${MKLDNN_PATH}/lib/libmkldnn.so.0) + endif () + endif() +else() + set(MATH_LIB ${PADDLE_DIR}/third_party/install/openblas/lib/libopenblas${CMAKE_STATIC_LIBRARY_SUFFIX}) +endif() + +if (WIN32) + if(EXISTS "${PADDLE_DIR}/paddle/fluid/inference/libpaddle_fluid${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(DEPS + ${PADDLE_DIR}/paddle/fluid/inference/libpaddle_fluid${CMAKE_STATIC_LIBRARY_SUFFIX}) + else() + set(DEPS + ${PADDLE_DIR}/paddle/lib/libpaddle_fluid${CMAKE_STATIC_LIBRARY_SUFFIX}) + endif() +endif() + +if(WITH_STATIC_LIB) + set(DEPS + ${PADDLE_DIR}/paddle/lib/libpaddle_fluid${CMAKE_STATIC_LIBRARY_SUFFIX}) +else() + set(DEPS + ${PADDLE_DIR}/paddle/lib/libpaddle_fluid${CMAKE_SHARED_LIBRARY_SUFFIX}) +endif() + +if (NOT WIN32) + set(DEPS ${DEPS} + ${MATH_LIB} ${MKLDNN_LIB} + glog gflags protobuf z xxhash yaml-cpp + ) + if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/lib") + set(DEPS ${DEPS} snappystream) + endif() + if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/lib") + set(DEPS ${DEPS} snappy) + endif() +else() + set(DEPS ${DEPS} + ${MATH_LIB} ${MKLDNN_LIB} + glog gflags_static libprotobuf zlibstatic xxhash libyaml-cppmt) + + set(DEPS ${DEPS} libcmt shlwapi) + if (EXISTS "${PADDLE_DIR}/third_party/install/snappy/lib") + set(DEPS ${DEPS} snappy) + endif() + if(EXISTS "${PADDLE_DIR}/third_party/install/snappystream/lib") + set(DEPS ${DEPS} snappystream) + endif() +endif(NOT WIN32) + +if(WITH_GPU) + if(NOT WIN32) + if (WITH_TENSORRT) + set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/libnvinfer${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(DEPS ${DEPS} ${TENSORRT_DIR}/lib/libnvinfer_plugin${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + set(DEPS ${DEPS} ${CUDA_LIB}/libcudart${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(DEPS ${DEPS} ${CUDNN_LIB}/libcudnn${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + set(DEPS ${DEPS} ${CUDA_LIB}/cudart${CMAKE_STATIC_LIBRARY_SUFFIX} ) + set(DEPS ${DEPS} ${CUDA_LIB}/cublas${CMAKE_STATIC_LIBRARY_SUFFIX} ) + set(DEPS ${DEPS} ${CUDA_LIB}/cudnn${CMAKE_STATIC_LIBRARY_SUFFIX}) + endif() +endif() + +if(WITH_ENCRYPTION) + if(NOT WIN32) + include_directories("${ENCRYPTION_DIR}/include") + link_directories("${ENCRYPTION_DIR}/lib") + set(DEPS ${DEPS} ${ENCRYPTION_DIR}/lib/libpmodel-decrypt${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + message(FATAL_ERROR "Encryption Tool don't support WINDOWS") + endif() +endif() + +if (NOT WIN32) + set(EXTERNAL_LIB "-ldl -lrt -lgomp -lz -lm -lpthread") + set(DEPS ${DEPS} ${EXTERNAL_LIB}) +endif() + +set(DEPS ${DEPS} ${OpenCV_LIBS}) +add_library(paddlex_inference SHARED src/visualize src/transforms.cpp src/paddlex.cpp) +ADD_DEPENDENCIES(paddlex_inference ext-yaml-cpp) +target_link_libraries(paddlex_inference ${DEPS}) + +add_executable(classifier demo/classifier.cpp src/transforms.cpp src/paddlex.cpp) +ADD_DEPENDENCIES(classifier ext-yaml-cpp) +target_link_libraries(classifier ${DEPS}) + +add_library(detector SHARED demo/detector.cpp src/transforms.cpp src/paddlex.cpp src/visualize.cpp) +ADD_DEPENDENCIES(detector ext-yaml-cpp) +target_link_libraries(detector ${DEPS}) + +add_executable(segmenter demo/segmenter.cpp src/transforms.cpp src/paddlex.cpp src/visualize.cpp) +ADD_DEPENDENCIES(segmenter ext-yaml-cpp) +target_link_libraries(segmenter ${DEPS}) + +if (WIN32 AND WITH_MKL) + add_custom_command(TARGET classifier POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./mklml.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./libiomp5md.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./mkldnn.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./release/mklml.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./release/libiomp5md.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./release/mkldnn.dll + ) + add_custom_command(TARGET detector POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./mklml.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./libiomp5md.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./mkldnn.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./release/mklml.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./release/libiomp5md.dll + ) + add_custom_command(TARGET segmenter POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./mklml.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./libiomp5md.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./mkldnn.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/mklml.dll ./release/mklml.dll + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mklml/lib/libiomp5md.dll ./release/libiomp5md.dll + + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PADDLE_DIR}/third_party/install/mkldnn/lib/mkldnn.dll ./release/mkldnn.dll + ) + +endif() + +file(COPY "${CMAKE_SOURCE_DIR}/include/paddlex/visualize.h" +DESTINATION "${CMAKE_BINARY_DIR}/include/" ) +file(COPY "${CMAKE_SOURCE_DIR}/include/paddlex/config_parser.h" +DESTINATION "${CMAKE_BINARY_DIR}/include/" ) +file(COPY "${CMAKE_SOURCE_DIR}/include/paddlex/transforms.h" +DESTINATION "${CMAKE_BINARY_DIR}/include/" ) +file(COPY "${CMAKE_SOURCE_DIR}/include/paddlex/results.h" +DESTINATION "${CMAKE_BINARY_DIR}/include/" ) +file(COPY "${CMAKE_SOURCE_DIR}/include/paddlex/paddlex.h" +DESTINATION "${CMAKE_BINARY_DIR}/include/" ) diff --git a/deploy/cpp_dll/CMakeSettings.json b/deploy/cpp_dll/CMakeSettings.json new file mode 100644 index 0000000000000000000000000000000000000000..4aa8fcc0e0a502f31828385223cf3da34ce90467 --- /dev/null +++ b/deploy/cpp_dll/CMakeSettings.json @@ -0,0 +1,47 @@ +{ + "configurations": [ + { + "name": "x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "-v", + "ctestCommandArgs": "", + "variables": [ + { + "name": "OPENCV_DIR", + "value": "C:/projects/opencv", + "type": "PATH" + }, + { + "name": "PADDLE_DIR", + "value": "C:/projects/fluid_install_dir_win_cpu_1.6/fluid_install_dir_win_cpu_1.6", + "type": "PATH" + }, + { + "name": "CMAKE_BUILD_TYPE", + "value": "Release", + "type": "STRING" + }, + { + "name": "WITH_STATIC_LIB", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_MKL", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_GPU", + "value": "False", + "type": "BOOL" + } + ] + } + ] +} \ No newline at end of file diff --git a/deploy/cpp_dll/cmake/yaml-cpp.cmake b/deploy/cpp_dll/cmake/yaml-cpp.cmake new file mode 100644 index 0000000000000000000000000000000000000000..2a3dbd7abfd11895ccd505e74d2c31d64ba65cbe --- /dev/null +++ b/deploy/cpp_dll/cmake/yaml-cpp.cmake @@ -0,0 +1,30 @@ +find_package(Git REQUIRED) + +include(ExternalProject) + +message("${CMAKE_BUILD_TYPE}") + +ExternalProject_Add( + ext-yaml-cpp + URL https://bj.bcebos.com/paddlex/deploy/deps/yaml-cpp.zip + URL_MD5 9542d6de397d1fbd649ed468cb5850e6 + CMAKE_ARGS + -DYAML_CPP_BUILD_TESTS=OFF + -DYAML_CPP_BUILD_TOOLS=OFF + -DYAML_CPP_INSTALL=OFF + -DYAML_CPP_BUILD_CONTRIB=OFF + -DMSVC_SHARED_RT=OFF + -DBUILD_SHARED_LIBS=${YAML_BUILD_TYPE} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG} + -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} + -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/ext/yaml-cpp/lib + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/ext/yaml-cpp/lib + PREFIX "${CMAKE_BINARY_DIR}/ext/yaml-cpp" + # Disable install step + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + LOG_BUILD 1 +) + diff --git a/deploy/cpp_dll/demo/classifier.cpp b/deploy/cpp_dll/demo/classifier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45df7ec9f1f8b146256825ea864ded8ca87a7842 --- /dev/null +++ b/deploy/cpp_dll/demo/classifier.cpp @@ -0,0 +1,75 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include +#include +#include +#include + +#include "include/paddlex/paddlex.h" + +DEFINE_string(model_dir, "", "Path of inference model"); +DEFINE_bool(use_gpu, false, "Infering with GPU or CPU"); +DEFINE_bool(use_trt, false, "Infering with TensorRT"); +DEFINE_int32(gpu_id, 0, "GPU card id"); +DEFINE_string(key, "", "key of encryption"); +DEFINE_string(image, "", "Path of test image file"); +DEFINE_string(image_list, "", "Path of test image list file"); + +int main(int argc, char** argv) { + // Parsing command-line + google::ParseCommandLineFlags(&argc, &argv, true); + + if (FLAGS_model_dir == "") { + std::cerr << "--model_dir need to be defined" << std::endl; + return -1; + } + if (FLAGS_image == "" & FLAGS_image_list == "") { + std::cerr << "--image or --image_list need to be defined" << std::endl; + return -1; + } + + // 加载模型 + PaddleX::Model model; + model.Init(FLAGS_model_dir, FLAGS_use_gpu, FLAGS_use_trt, FLAGS_gpu_id, FLAGS_key); + + // 进行预测 + if (FLAGS_image_list != "") { + std::ifstream inf(FLAGS_image_list); + if (!inf) { + std::cerr << "Fail to open file " << FLAGS_image_list << std::endl; + return -1; + } + std::string image_path; + while (getline(inf, image_path)) { + PaddleX::ClsResult result; + cv::Mat im = cv::imread(image_path, 1); + model.predict(im, &result); + std::cout << "Predict label: " << result.category + << ", label_id:" << result.category_id + << ", score: " << result.score << std::endl; + } + } else { + PaddleX::ClsResult result; + cv::Mat im = cv::imread(FLAGS_image, 1); + model.predict(im, &result); + std::cout << "Predict label: " << result.category + << ", label_id:" << result.category_id + << ", score: " << result.score << std::endl; + } + + return 0; +} diff --git a/deploy/cpp_dll/demo/detector.cpp b/deploy/cpp_dll/demo/detector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3fe617d3ce03b5f264cc3ac73c0bdf0aeed1510 --- /dev/null +++ b/deploy/cpp_dll/demo/detector.cpp @@ -0,0 +1,79 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include +#include +#include +#include + +#include "include/paddlex/paddlex.h" +#include "include/paddlex/visualize.h" + +namespace PaddleX { +std::string image; +void PredictImage(std::string image, PaddleX::DetResult result); + +void Loadmodel() { + std::string model_dir = "E:\\0608\\inference_model"; + std::string key = ""; + std::string image_list = ""; + std::string save_dir = "output"; + int gpu_id = 0; + bool use_trt = 0; + bool use_gpu = 1; + + // Load model and create a object detector + + PaddleX::DetResult result; + PredictImage(image, result); +} + +void PredictImage(std::string image, PaddleX::DetResult result) { + image = "E:\\0608\\pic\\test.jpg"; + cv::Mat im = cv::imread(image, 1); + + // PaddleX::DetResult* result; + std::string model_dir = "E:\\0608\\inference_model"; + std::string key = ""; + std::string image_list = ""; + + int gpu_id = 0; + bool use_trt = 0; + bool use_gpu = 1; + PaddleX::Model model; + model.Init(model_dir, use_gpu, use_trt, gpu_id, key); + model.predict(im, &result); + for (int i = 0; i < result.boxes.size(); ++i) { + std::cout << ", predict label: " << result.boxes[i].category + << ", label_id:" << result.boxes[i].category_id + << ", score: " << result.boxes[i].score + << ", box(xmin, ymin, w, h):(" << result.boxes[i].coordinate[0] + << ", " << result.boxes[i].coordinate[1] << ", " + << result.boxes[i].coordinate[2] << ", " + << result.boxes[i].coordinate[3] << ")" << std::endl; + } + + // 可视化 + auto colormap = PaddleX::GenerateColorMap(model.labels.size()); + cv::Mat vis_img = PaddleX::Visualize(im, result, model.labels, colormap, 0.5); + std::string save_dir = "output"; + std::string save_path = PaddleX::generate_save_path(save_dir, image); + + cv::imwrite(save_path, vis_img); + // result->clear(); + std::cout << "Visualized output saved as " << save_path << std::endl; +} +} // namespace PaddleX \ No newline at end of file diff --git a/deploy/cpp_dll/demo/segmenter.cpp b/deploy/cpp_dll/demo/segmenter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..687bb40bf821a2e408088df00133bf57f918d316 --- /dev/null +++ b/deploy/cpp_dll/demo/segmenter.cpp @@ -0,0 +1,87 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include +#include +#include +#include + +#include "include/paddlex/paddlex.h" +#include "include/paddlex/visualize.h" + +DEFINE_string(model_dir, "", "Path of inference model"); +DEFINE_bool(use_gpu, false, "Infering with GPU or CPU"); +DEFINE_bool(use_trt, false, "Infering with TensorRT"); +DEFINE_int32(gpu_id, 0, "GPU card id"); +DEFINE_string(key, "", "key of encryption"); +DEFINE_string(image, "", "Path of test image file"); +DEFINE_string(image_list, "", "Path of test image list file"); +DEFINE_string(save_dir, "output", "Path to save visualized image"); + +int main(int argc, char** argv) { + // 解析命令行参数 + google::ParseCommandLineFlags(&argc, &argv, true); + + if (FLAGS_model_dir == "") { + std::cerr << "--model_dir need to be defined" << std::endl; + return -1; + } + if (FLAGS_image == "" & FLAGS_image_list == "") { + std::cerr << "--image or --image_list need to be defined" << std::endl; + return -1; + } + + // 加载模型 + PaddleX::Model model; + model.Init(FLAGS_model_dir, FLAGS_use_gpu, FLAGS_use_trt, FLAGS_gpu_id, FLAGS_key); + + auto colormap = PaddleX::GenerateColorMap(model.labels.size()); + // 进行预测 + if (FLAGS_image_list != "") { + std::ifstream inf(FLAGS_image_list); + if (!inf) { + std::cerr << "Fail to open file " << FLAGS_image_list << std::endl; + return -1; + } + std::string image_path; + while (getline(inf, image_path)) { + PaddleX::SegResult result; + cv::Mat im = cv::imread(image_path, 1); + model.predict(im, &result); + // 可视化 + cv::Mat vis_img = + PaddleX::Visualize(im, result, model.labels, colormap); + std::string save_path = + PaddleX::generate_save_path(FLAGS_save_dir, image_path); + cv::imwrite(save_path, vis_img); + result.clear(); + std::cout << "Visualized output saved as " << save_path << std::endl; + } + } else { + PaddleX::SegResult result; + cv::Mat im = cv::imread(FLAGS_image, 1); + model.predict(im, &result); + // 可视化 + cv::Mat vis_img = PaddleX::Visualize(im, result, model.labels, colormap); + std::string save_path = + PaddleX::generate_save_path(FLAGS_save_dir, FLAGS_image); + cv::imwrite(save_path, vis_img); + result.clear(); + std::cout << "Visualized output saved as " << save_path << std::endl; + } + + return 0; +} diff --git a/deploy/cpp_dll/include/paddlex/config_parser.h b/deploy/cpp_dll/include/paddlex/config_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..7262945e92e55caa0e9297137900c885a6e5f4d4 --- /dev/null +++ b/deploy/cpp_dll/include/paddlex/config_parser.h @@ -0,0 +1,57 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#include + +#include "yaml-cpp/yaml.h" + +#ifdef _WIN32 +#define OS_PATH_SEP "\\" +#else +#define OS_PATH_SEP "/" +#endif + +namespace PaddleX { + +// Inference model configuration parser +class ConfigPaser { + public: + ConfigPaser() {} + + ~ConfigPaser() {} + + bool load_config(const std::string& model_dir, + const std::string& cfg = "model.yml") { + // Load as a YAML::Node + YAML::Node config; + config = YAML::LoadFile(model_dir + OS_PATH_SEP + cfg); + + if (config["Transforms"].IsDefined()) { + YAML::Node transforms_ = config["Transforms"]; + } else { + std::cerr << "There's no field 'Transforms' in model.yml" << std::endl; + return false; + } + return true; + } + + YAML::Node Transforms_; +}; + +} // namespace PaddleDetection diff --git a/deploy/cpp_dll/include/paddlex/paddlex.h b/deploy/cpp_dll/include/paddlex/paddlex.h new file mode 100644 index 0000000000000000000000000000000000000000..b63d505eb4abf52881742fa6ee8705c9cbdc1712 --- /dev/null +++ b/deploy/cpp_dll/include/paddlex/paddlex.h @@ -0,0 +1,81 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include + +#include "yaml-cpp/yaml.h" + +#ifdef _WIN32 +#define OS_PATH_SEP "\\" +#else +#define OS_PATH_SEP "/" +#endif + +#include "paddle_inference_api.h" // NOLINT + +#include "config_parser.h" +#include "results.h" +#include "transforms.h" + +#ifdef WITH_ENCRYPTION +#include "paddle_model_decrypt.h" +#include "model_code.h" +#endif + +namespace PaddleX { +extern "C" __declspec(dllexport) void Loadmodel(); +void Loadmodel(); +class Model { + public: + void Init(const std::string& model_dir, + bool use_gpu = false, + bool use_trt = false, + int gpu_id = 0, + std::string key = "") { + create_predictor(model_dir, use_gpu, use_trt, gpu_id, key); + } + + void create_predictor(const std::string& model_dir, + bool use_gpu = false, + bool use_trt = false, + int gpu_id = 0, + std::string key = ""); + + bool load_config(const std::string& model_dir); + + bool preprocess(const cv::Mat& input_im, ImageBlob* blob); + + bool predict(const cv::Mat& im, ClsResult* result); + + bool predict(const cv::Mat& im, DetResult* result); + + bool predict(const cv::Mat& im, SegResult* result); + + bool postprocess(SegResult* result); + + bool postprocess(DetResult* result); + + std::string type; + std::string name; + std::map labels; + Transforms transforms_; + ImageBlob inputs_; + std::vector outputs_; + std::unique_ptr predictor_; +}; +} // namespce of PaddleX diff --git a/deploy/cpp_dll/include/paddlex/results.h b/deploy/cpp_dll/include/paddlex/results.h new file mode 100644 index 0000000000000000000000000000000000000000..9291b109f898720a776cfb1ac75aba9620aa9171 --- /dev/null +++ b/deploy/cpp_dll/include/paddlex/results.h @@ -0,0 +1,72 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include + +namespace PaddleX { + +template +struct Mask { + std::vector data; + std::vector shape; + void clear() { + data.clear(); + shape.clear(); + } +}; + +struct Box { + int category_id; + std::string category; + float score; + std::vector coordinate; + Mask mask; +}; + +class BaseResult { + public: + std::string type = "base"; +}; + +class ClsResult : public BaseResult { + public: + int category_id; + std::string category; + float score; + std::string type = "cls"; +}; + +class DetResult : public BaseResult { + public: + std::vector boxes; + int mask_resolution; + std::string type = "det"; + void clear() { boxes.clear(); } +}; + +class SegResult : public BaseResult { + public: + Mask label_map; + Mask score_map; + std::string type = "seg"; + void clear() { + label_map.clear(); + score_map.clear(); + } +}; +} // namespace PaddleX diff --git a/deploy/cpp_dll/include/paddlex/transforms.h b/deploy/cpp_dll/include/paddlex/transforms.h new file mode 100644 index 0000000000000000000000000000000000000000..33913e18fcfe67eee9c0aa8f93e5449f2a221aed --- /dev/null +++ b/deploy/cpp_dll/include/paddlex/transforms.h @@ -0,0 +1,190 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace PaddleX { + +// Object for storing all preprocessed data +class ImageBlob { + public: + // Original image height and width + std::vector ori_im_size_ = std::vector(2); + // Newest image height and width after process + std::vector new_im_size_ = std::vector(2); + // Image height and width before resize + std::vector> im_size_before_resize_; + // Reshape order + std::vector reshape_order_; + // Resize scale + float scale = 1.0; + // Buffer for image data after preprocessing + std::vector im_data_; + + void clear() { + ori_im_size_.clear(); + new_im_size_.clear(); + im_size_before_resize_.clear(); + reshape_order_.clear(); + im_data_.clear(); + } +}; + +// Abstraction of preprocessing opration class +class Transform { + public: + virtual void Init(const YAML::Node& item) = 0; + virtual bool Run(cv::Mat* im, ImageBlob* data) = 0; +}; + +class Normalize : public Transform { + public: + virtual void Init(const YAML::Node& item) { + mean_ = item["mean"].as>(); + std_ = item["std"].as>(); + } + + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + std::vector mean_; + std::vector std_; +}; + +class ResizeByShort : public Transform { + public: + virtual void Init(const YAML::Node& item) { + short_size_ = item["short_size"].as(); + if (item["max_size"].IsDefined()) { + max_size_ = item["max_size"].as(); + } else { + max_size_ = -1; + } + } + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + float GenerateScale(const cv::Mat& im); + int short_size_; + int max_size_; +}; + +class ResizeByLong : public Transform { + public: + virtual void Init(const YAML::Node& item) { + long_size_ = item["long_size"].as(); + } + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + int long_size_; +}; + +class Resize : public Transform { + public: + virtual void Init(const YAML::Node& item) { + if (item["target_size"].IsScalar()) { + height_ = item["target_size"].as(); + width_ = item["target_size"].as(); + interp_ = item["interp"].as(); + } else if (item["target_size"].IsSequence()) { + std::vector target_size = item["target_size"].as>(); + width_ = target_size[0]; + height_ = target_size[1]; + } + if (height_ <= 0 || width_ <= 0) { + std::cerr << "[Resize] target_size should greater than 0" << std::endl; + exit(-1); + } + } + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + int height_; + int width_; + std::string interp_; +}; + +class CenterCrop : public Transform { + public: + virtual void Init(const YAML::Node& item) { + if (item["crop_size"].IsScalar()) { + height_ = item["crop_size"].as(); + width_ = item["crop_size"].as(); + } else if (item["crop_size"].IsSequence()) { + std::vector crop_size = item["crop_size"].as>(); + width_ = crop_size[0]; + height_ = crop_size[1]; + } + } + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + int height_; + int width_; +}; + +class Padding : public Transform { + public: + virtual void Init(const YAML::Node& item) { + if (item["coarsest_stride"].IsDefined()) { + coarsest_stride_ = item["coarsest_stride"].as(); + if (coarsest_stride_ < 1) { + std::cerr << "[Padding] coarest_stride should greater than 0" + << std::endl; + exit(-1); + } + } + if (item["target_size"].IsDefined()) { + if (item["target_size"].IsScalar()) { + width_ = item["target_size"].as(); + height_ = item["target_size"].as(); + } else if (item["target_size"].IsSequence()) { + width_ = item["target_size"].as>()[0]; + height_ = item["target_size"].as>()[1]; + } + } + } + virtual bool Run(cv::Mat* im, ImageBlob* data); + + private: + int coarsest_stride_ = -1; + int width_ = 0; + int height_ = 0; +}; + +class Transforms { + public: + void Init(const YAML::Node& node, bool to_rgb = true); + std::shared_ptr CreateTransform(const std::string& name); + bool Run(cv::Mat* im, ImageBlob* data); + + private: + std::vector> transforms_; + bool to_rgb_ = true; +}; + +} // namespace PaddleX diff --git a/deploy/cpp_dll/include/paddlex/visualize.h b/deploy/cpp_dll/include/paddlex/visualize.h new file mode 100644 index 0000000000000000000000000000000000000000..7a6888b4e499a8ed0bc3bca0c16334f96ff8cd8e --- /dev/null +++ b/deploy/cpp_dll/include/paddlex/visualize.h @@ -0,0 +1,62 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#ifdef _WIN32 +#include +#include +#else // Linux/Unix +#include +#include +#include +#include +#include +#endif +#include + +#include +#include +#include + +#include "include/paddlex/results.h" + +#ifdef _WIN32 +#define OS_PATH_SEP "\\" +#else +#define OS_PATH_SEP "/" +#endif + +namespace PaddleX { + +// Generate visualization colormap for each class +std::vector GenerateColorMap(int num_class); + +cv::Mat Visualize(const cv::Mat& img, + const DetResult& results, + const std::map& labels, + const std::vector& colormap, + float threshold = 0.5); + +cv::Mat Visualize(const cv::Mat& img, + const SegResult& result, + const std::map& labels, + const std::vector& colormap); + +std::string generate_save_path(const std::string& save_dir, + const std::string& file_path); +} // namespce of PaddleX diff --git a/deploy/cpp_dll/scripts/bootstrap.sh b/deploy/cpp_dll/scripts/bootstrap.sh new file mode 100644 index 0000000000000000000000000000000000000000..283d75928a68a507d852ec61eb89e115e581146f --- /dev/null +++ b/deploy/cpp_dll/scripts/bootstrap.sh @@ -0,0 +1,18 @@ +# download pre-compiled paddle encrypt +ENCRYPTION_URL=https://bj.bcebos.com/paddlex/tools/paddlex-encryption.zip +if [ ! -d "./paddlex-encryption" ]; then + wget -c ${ENCRYPTION_URL} + unzip paddlex-encryption.zip + rm -rf paddlex-encryption.zip +fi + +# download pre-compiled opencv lib +OPENCV_URL=https://paddleseg.bj.bcebos.com/deploy/docker/opencv3gcc4.8.tar.bz2 +if [ ! -d "./deps/opencv3gcc4.8" ]; then + mkdir -p deps + cd deps + wget -c ${OPENCV_URL} + tar xvfj opencv3gcc4.8.tar.bz2 + rm -rf opencv3gcc4.8.tar.bz2 + cd .. +fi diff --git a/deploy/cpp_dll/scripts/build.sh b/deploy/cpp_dll/scripts/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..74ab96a32466b6351def8f9abc3275954cdc1e06 --- /dev/null +++ b/deploy/cpp_dll/scripts/build.sh @@ -0,0 +1,45 @@ +# 是否使用GPU(即是否使用 CUDA) +WITH_GPU=OFF +# 使用MKL or openblas +WITH_MKL=ON +# 是否集成 TensorRT(仅WITH_GPU=ON 有效) +WITH_TENSORRT=OFF +# TensorRT 的路径 +TENSORRT_DIR=/path/to/TensorRT/ +# Paddle 预测库路径 +PADDLE_DIR=/docker/jiangjiajun/PaddleDetection/deploy/cpp/fluid_inference +# Paddle 的预测库是否使用静态库来编译 +# 使用TensorRT时,Paddle的预测库通常为动态库 +WITH_STATIC_LIB=OFF +# CUDA 的 lib 路径 +CUDA_LIB=/usr/local/cuda/lib64 +# CUDNN 的 lib 路径 +CUDNN_LIB=/usr/local/cuda/lib64 + +# 是否加载加密后的模型 +WITH_ENCRYPTION=ON +# 加密工具的路径, 如果使用自带预编译版本可不修改 +sh $(pwd)/scripts/bootstrap.sh # 下载预编译版本的加密工具 +ENCRYPTION_DIR=$(pwd)/paddlex-encryption + +# OPENCV 路径, 如果使用自带预编译版本可不修改 +sh $(pwd)/scripts/bootstrap.sh # 下载预编译版本的opencv +OPENCV_DIR=$(pwd)/deps/opencv3gcc4.8/ + +# 以下无需改动 +rm -rf build +mkdir -p build +cd build +cmake .. \ + -DWITH_GPU=${WITH_GPU} \ + -DWITH_MKL=${WITH_MKL} \ + -DWITH_TENSORRT=${WITH_TENSORRT} \ + -DWITH_ENCRYPTION=${WITH_ENCRYPTION} \ + -DTENSORRT_DIR=${TENSORRT_DIR} \ + -DPADDLE_DIR=${PADDLE_DIR} \ + -DWITH_STATIC_LIB=${WITH_STATIC_LIB} \ + -DCUDA_LIB=${CUDA_LIB} \ + -DCUDNN_LIB=${CUDNN_LIB} \ + -DENCRYPTION_DIR=${ENCRYPTION_DIR} \ + -DOPENCV_DIR=${OPENCV_DIR} +make diff --git a/deploy/cpp_dll/src/paddlex.cpp b/deploy/cpp_dll/src/paddlex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..132d0e190d7b4795b24d188b9606743c9701d384 --- /dev/null +++ b/deploy/cpp_dll/src/paddlex.cpp @@ -0,0 +1,358 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "include/paddlex/paddlex.h" + +namespace PaddleX { + +void Model::create_predictor(const std::string& model_dir, + bool use_gpu, + bool use_trt, + int gpu_id, + std::string key) { + // 读取配置文件 + if (!load_config(model_dir)) { + std::cerr << "Parse file 'model.yml' failed!" << std::endl; + exit(-1); + } + paddle::AnalysisConfig config; + std::string model_file = model_dir + OS_PATH_SEP + "__model__"; + std::string params_file = model_dir + OS_PATH_SEP + "__params__"; +#ifdef WITH_ENCRYPTION + if (key != ""){ + model_file = model_dir + OS_PATH_SEP + "__model__.encrypted"; + params_file = model_dir + OS_PATH_SEP + "__params__.encrypted"; + paddle_security_load_model(&config, key.c_str(), model_file.c_str(), params_file.c_str()); + } +#endif + if (key == ""){ + config.SetModel(model_file, params_file); + } + if (use_gpu) { + config.EnableUseGpu(100, gpu_id); + } else { + config.DisableGpu(); + } + config.SwitchUseFeedFetchOps(false); + config.SwitchSpecifyInputNames(true); + // 开启内存优化 + config.EnableMemoryOptim(); + if (use_trt) { + config.EnableTensorRtEngine( + 1 << 20 /* workspace_size*/, + 32 /* max_batch_size*/, + 20 /* min_subgraph_size*/, + paddle::AnalysisConfig::Precision::kFloat32 /* precision*/, + true /* use_static*/, + false /* use_calib_mode*/); + } + predictor_ = std::move(CreatePaddlePredictor(config)); +} + +bool Model::load_config(const std::string& model_dir) { + std::string yaml_file = model_dir + OS_PATH_SEP + "model.yml"; + YAML::Node config = YAML::LoadFile(yaml_file); + type = config["_Attributes"]["model_type"].as(); + name = config["Model"].as(); + std::string version = config["version"].as(); + if (version[0] == '0') { + std::cerr << "[Init] Version of the loaded model is lower than 1.0.0, deployment " + << "cannot be done, please refer to " + << "https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/tutorials/deploy/upgrade_version.md " + << "to transfer version." + << std::endl; + return false; + } + bool to_rgb = true; + if (config["TransformsMode"].IsDefined()) { + std::string mode = config["TransformsMode"].as(); + if (mode == "BGR") { + to_rgb = false; + } else if (mode != "RGB") { + std::cerr << "[Init] Only 'RGB' or 'BGR' is supported for TransformsMode" + << std::endl; + return false; + } + } + // 构建数据处理流 + transforms_.Init(config["Transforms"], to_rgb); + // 读入label list + labels.clear(); + for (const auto& item : config["_Attributes"]["labels"]) { + int index = labels.size(); + labels[index] = item.as(); + } + return true; +} + +bool Model::preprocess(const cv::Mat& input_im, ImageBlob* blob) { + cv::Mat im = input_im.clone(); + if (!transforms_.Run(&im, blob)) { + return false; + } + return true; +} + +bool Model::predict(const cv::Mat& im, ClsResult* result) { + inputs_.clear(); + if (type == "detector") { + std::cerr << "Loading model is a 'detector', DetResult should be passed to " + "function predict()!" + << std::endl; + return false; + } else if (type == "segmenter") { + std::cerr << "Loading model is a 'segmenter', SegResult should be passed " + "to function predict()!" + << std::endl; + return false; + } + // 处理输入图像 + if (!preprocess(im, &inputs_)) { + std::cerr << "Preprocess failed!" << std::endl; + return false; + } + // 使用加载的模型进行预测 + auto in_tensor = predictor_->GetInputTensor("image"); + int h = inputs_.new_im_size_[0]; + int w = inputs_.new_im_size_[1]; + in_tensor->Reshape({1, 3, h, w}); + in_tensor->copy_from_cpu(inputs_.im_data_.data()); + predictor_->ZeroCopyRun(); + // 取出模型的输出结果 + auto output_names = predictor_->GetOutputNames(); + auto output_tensor = predictor_->GetOutputTensor(output_names[0]); + std::vector output_shape = output_tensor->shape(); + int size = 1; + for (const auto& i : output_shape) { + size *= i; + } + outputs_.resize(size); + output_tensor->copy_to_cpu(outputs_.data()); + // 对模型输出结果进行后处理 + auto ptr = std::max_element(std::begin(outputs_), std::end(outputs_)); + result->category_id = std::distance(std::begin(outputs_), ptr); + result->score = *ptr; + result->category = labels[result->category_id]; +} + +bool Model::predict(const cv::Mat& im, DetResult* result) { + result->clear(); + inputs_.clear(); + if (type == "classifier") { + std::cerr << "Loading model is a 'classifier', ClsResult should be passed " + "to function predict()!" + << std::endl; + return false; + } else if (type == "segmenter") { + std::cerr << "Loading model is a 'segmenter', SegResult should be passed " + "to function predict()!" + << std::endl; + return false; + } + + // 处理输入图像 + if (!preprocess(im, &inputs_)) { + std::cerr << "Preprocess failed!" << std::endl; + return false; + } + + int h = inputs_.new_im_size_[0]; + int w = inputs_.new_im_size_[1]; + auto im_tensor = predictor_->GetInputTensor("image"); + im_tensor->Reshape({1, 3, h, w}); + im_tensor->copy_from_cpu(inputs_.im_data_.data()); + if (name == "YOLOv3") { + auto im_size_tensor = predictor_->GetInputTensor("im_size"); + im_size_tensor->Reshape({1, 2}); + im_size_tensor->copy_from_cpu(inputs_.ori_im_size_.data()); + } else if (name == "FasterRCNN" || name == "MaskRCNN") { + auto im_info_tensor = predictor_->GetInputTensor("im_info"); + auto im_shape_tensor = predictor_->GetInputTensor("im_shape"); + im_info_tensor->Reshape({1, 3}); + im_shape_tensor->Reshape({1, 3}); + float ori_h = static_cast(inputs_.ori_im_size_[0]); + float ori_w = static_cast(inputs_.ori_im_size_[1]); + float new_h = static_cast(inputs_.new_im_size_[0]); + float new_w = static_cast(inputs_.new_im_size_[1]); + float im_info[] = {new_h, new_w, inputs_.scale}; + float im_shape[] = {ori_h, ori_w, 1.0}; + im_info_tensor->copy_from_cpu(im_info); + im_shape_tensor->copy_from_cpu(im_shape); + } + // 使用加载的模型进行预测 + predictor_->ZeroCopyRun(); + + std::vector output_box; + auto output_names = predictor_->GetOutputNames(); + auto output_box_tensor = predictor_->GetOutputTensor(output_names[0]); + std::vector output_box_shape = output_box_tensor->shape(); + int size = 1; + for (const auto& i : output_box_shape) { + size *= i; + } + output_box.resize(size); + output_box_tensor->copy_to_cpu(output_box.data()); + if (size < 6) { + std::cerr << "[WARNING] There's no object detected." << std::endl; + return true; + } + int num_boxes = size / 6; + // 解析预测框box + for (int i = 0; i < num_boxes; ++i) { + Box box; + box.category_id = static_cast(round(output_box[i * 6])); + box.category = labels[box.category_id]; + box.score = output_box[i * 6 + 1]; + float xmin = output_box[i * 6 + 2]; + float ymin = output_box[i * 6 + 3]; + float xmax = output_box[i * 6 + 4]; + float ymax = output_box[i * 6 + 5]; + float w = xmax - xmin + 1; + float h = ymax - ymin + 1; + box.coordinate = {xmin, ymin, w, h}; + result->boxes.push_back(std::move(box)); + } + // 实例分割需解析mask + if (name == "MaskRCNN") { + std::vector output_mask; + auto output_mask_tensor = predictor_->GetOutputTensor(output_names[1]); + std::vector output_mask_shape = output_mask_tensor->shape(); + int masks_size = 1; + for (const auto& i : output_mask_shape) { + masks_size *= i; + } + int mask_pixels = output_mask_shape[2] * output_mask_shape[3]; + int classes = output_mask_shape[1]; + output_mask.resize(masks_size); + output_mask_tensor->copy_to_cpu(output_mask.data()); + result->mask_resolution = output_mask_shape[2]; + for (int i = 0; i < result->boxes.size(); ++i) { + Box* box = &result->boxes[i]; + auto begin_mask = + output_mask.begin() + (i * classes + box->category_id) * mask_pixels; + auto end_mask = begin_mask + mask_pixels; + box->mask.data.assign(begin_mask, end_mask); + box->mask.shape = {static_cast(box->coordinate[2]), + static_cast(box->coordinate[3])}; + } + } +} + +bool Model::predict(const cv::Mat& im, SegResult* result) { + result->clear(); + inputs_.clear(); + if (type == "classifier") { + std::cerr << "Loading model is a 'classifier', ClsResult should be passed " + "to function predict()!" + << std::endl; + return false; + } else if (type == "detector") { + std::cerr << "Loading model is a 'detector', DetResult should be passed to " + "function predict()!" + << std::endl; + return false; + } + + // 处理输入图像 + if (!preprocess(im, &inputs_)) { + std::cerr << "Preprocess failed!" << std::endl; + return false; + } + + int h = inputs_.new_im_size_[0]; + int w = inputs_.new_im_size_[1]; + auto im_tensor = predictor_->GetInputTensor("image"); + im_tensor->Reshape({1, 3, h, w}); + im_tensor->copy_from_cpu(inputs_.im_data_.data()); + + // 使用加载的模型进行预测 + predictor_->ZeroCopyRun(); + + // 获取预测置信度,经过argmax后的labelmap + auto output_names = predictor_->GetOutputNames(); + auto output_label_tensor = predictor_->GetOutputTensor(output_names[0]); + std::vector output_label_shape = output_label_tensor->shape(); + int size = 1; + for (const auto& i : output_label_shape) { + size *= i; + result->label_map.shape.push_back(i); + } + result->label_map.data.resize(size); + output_label_tensor->copy_to_cpu(result->label_map.data.data()); + + // 获取预测置信度scoremap + auto output_score_tensor = predictor_->GetOutputTensor(output_names[1]); + std::vector output_score_shape = output_score_tensor->shape(); + size = 1; + for (const auto& i : output_score_shape) { + size *= i; + result->score_map.shape.push_back(i); + } + result->score_map.data.resize(size); + output_score_tensor->copy_to_cpu(result->score_map.data.data()); + + // 解析输出结果到原图大小 + std::vector label_map(result->label_map.data.begin(), + result->label_map.data.end()); + cv::Mat mask_label(result->label_map.shape[1], + result->label_map.shape[2], + CV_8UC1, + label_map.data()); + + cv::Mat mask_score(result->score_map.shape[2], + result->score_map.shape[3], + CV_32FC1, + result->score_map.data.data()); + int idx = 1; + int len_postprocess = inputs_.im_size_before_resize_.size(); + for (std::vector::reverse_iterator iter = + inputs_.reshape_order_.rbegin(); + iter != inputs_.reshape_order_.rend(); + ++iter) { + if (*iter == "padding") { + auto before_shape = inputs_.im_size_before_resize_[len_postprocess - idx]; + inputs_.im_size_before_resize_.pop_back(); + auto padding_w = before_shape[0]; + auto padding_h = before_shape[1]; + mask_label = mask_label(cv::Rect(0, 0, padding_w, padding_h)); + mask_score = mask_score(cv::Rect(0, 0, padding_w, padding_h)); + } else if (*iter == "resize") { + auto before_shape = inputs_.im_size_before_resize_[len_postprocess - idx]; + inputs_.im_size_before_resize_.pop_back(); + auto resize_w = before_shape[0]; + auto resize_h = before_shape[1]; + cv::resize(mask_label, + mask_label, + cv::Size(resize_h, resize_w), + 0, + 0, + cv::INTER_NEAREST); + cv::resize(mask_score, + mask_score, + cv::Size(resize_h, resize_w), + 0, + 0, + cv::INTER_NEAREST); + } + ++idx; + } + result->label_map.data.assign(mask_label.begin(), + mask_label.end()); + result->label_map.shape = {mask_label.rows, mask_label.cols}; + result->score_map.data.assign(mask_score.begin(), + mask_score.end()); + result->score_map.shape = {mask_score.rows, mask_score.cols}; +} + +} // namespce of PaddleX diff --git a/deploy/cpp_dll/src/transforms.cpp b/deploy/cpp_dll/src/transforms.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e884d70d6c6828f0522112ba605eff1821d65fe --- /dev/null +++ b/deploy/cpp_dll/src/transforms.cpp @@ -0,0 +1,222 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "include/paddlex/transforms.h" + +namespace PaddleX { + +std::map interpolations = {{"LINEAR", cv::INTER_LINEAR}, + {"NEAREST", cv::INTER_NEAREST}, + {"AREA", cv::INTER_AREA}, + {"CUBIC", cv::INTER_CUBIC}, + {"LANCZOS4", cv::INTER_LANCZOS4}}; + +bool Normalize::Run(cv::Mat* im, ImageBlob* data) { + for (int h = 0; h < im->rows; h++) { + for (int w = 0; w < im->cols; w++) { + im->at(h, w)[0] = + (im->at(h, w)[0] / 255.0 - mean_[0]) / std_[0]; + im->at(h, w)[1] = + (im->at(h, w)[1] / 255.0 - mean_[1]) / std_[1]; + im->at(h, w)[2] = + (im->at(h, w)[2] / 255.0 - mean_[2]) / std_[2]; + } + } + return true; +} + +float ResizeByShort::GenerateScale(const cv::Mat& im) { + int origin_w = im.cols; + int origin_h = im.rows; + int im_size_max = std::max(origin_w, origin_h); + int im_size_min = std::min(origin_w, origin_h); + float scale = + static_cast(short_size_) / static_cast(im_size_min); + if (max_size_ > 0) { + if (round(scale * im_size_max) > max_size_) { + scale = static_cast(max_size_) / static_cast(im_size_max); + } + } + return scale; +} + +bool ResizeByShort::Run(cv::Mat* im, ImageBlob* data) { + data->im_size_before_resize_.push_back({im->rows, im->cols}); + data->reshape_order_.push_back("resize"); + + float scale = GenerateScale(*im); + int width = static_cast(scale * im->cols); + int height = static_cast(scale * im->rows); + cv::resize(*im, *im, cv::Size(width, height), 0, 0, cv::INTER_LINEAR); + + data->new_im_size_[0] = im->rows; + data->new_im_size_[1] = im->cols; + data->scale = scale; + return true; +} + +bool CenterCrop::Run(cv::Mat* im, ImageBlob* data) { + int height = static_cast(im->rows); + int width = static_cast(im->cols); + if (height < height_ || width < width_) { + std::cerr << "[CenterCrop] Image size less than crop size" << std::endl; + return false; + } + int offset_x = static_cast((width - width_) / 2); + int offset_y = static_cast((height - height_) / 2); + cv::Rect crop_roi(offset_x, offset_y, width_, height_); + *im = (*im)(crop_roi); + data->new_im_size_[0] = im->rows; + data->new_im_size_[1] = im->cols; + return true; +} + +bool Padding::Run(cv::Mat* im, ImageBlob* data) { + data->im_size_before_resize_.push_back({im->rows, im->cols}); + data->reshape_order_.push_back("padding"); + + int padding_w = 0; + int padding_h = 0; + if (width_ > 1 & height_ > 1) { + padding_w = width_ - im->cols; + padding_h = height_ - im->rows; + } else if (coarsest_stride_ > 1) { + padding_h = + ceil(im->rows * 1.0 / coarsest_stride_) * coarsest_stride_ - im->rows; + padding_w = + ceil(im->cols * 1.0 / coarsest_stride_) * coarsest_stride_ - im->cols; + } + + if (padding_h < 0 || padding_w < 0) { + std::cerr << "[Padding] Computed padding_h=" << padding_h + << ", padding_w=" << padding_w + << ", but they should be greater than 0." << std::endl; + return false; + } + cv::copyMakeBorder( + *im, *im, 0, padding_h, 0, padding_w, cv::BORDER_CONSTANT, cv::Scalar(0)); + data->new_im_size_[0] = im->rows; + data->new_im_size_[1] = im->cols; + return true; +} + +bool ResizeByLong::Run(cv::Mat* im, ImageBlob* data) { + if (long_size_ <= 0) { + std::cerr << "[ResizeByLong] long_size should be greater than 0" + << std::endl; + return false; + } + data->im_size_before_resize_.push_back({im->rows, im->cols}); + data->reshape_order_.push_back("resize"); + int origin_w = im->cols; + int origin_h = im->rows; + + int im_size_max = std::max(origin_w, origin_h); + float scale = + static_cast(long_size_) / static_cast(im_size_max); + cv::resize(*im, *im, cv::Size(), scale, scale, cv::INTER_NEAREST); + data->new_im_size_[0] = im->rows; + data->new_im_size_[1] = im->cols; + data->scale = scale; + return true; +} + +bool Resize::Run(cv::Mat* im, ImageBlob* data) { + if (width_ <= 0 || height_ <= 0) { + std::cerr << "[Resize] width and height should be greater than 0" + << std::endl; + return false; + } + if (interpolations.count(interp_) <= 0) { + std::cerr << "[Resize] Invalid interpolation method: '" << interp_ << "'" + << std::endl; + return false; + } + data->im_size_before_resize_.push_back({im->rows, im->cols}); + data->reshape_order_.push_back("resize"); + + cv::resize( + *im, *im, cv::Size(width_, height_), 0, 0, interpolations[interp_]); + data->new_im_size_[0] = im->rows; + data->new_im_size_[1] = im->cols; + return true; +} + +void Transforms::Init(const YAML::Node& transforms_node, bool to_rgb) { + transforms_.clear(); + to_rgb_ = to_rgb; + for (const auto& item : transforms_node) { + std::string name = item.begin()->first.as(); + std::cout << "trans name: " << name << std::endl; + std::shared_ptr transform = CreateTransform(name); + transform->Init(item.begin()->second); + transforms_.push_back(transform); + } +} + +std::shared_ptr Transforms::CreateTransform( + const std::string& transform_name) { + if (transform_name == "Normalize") { + return std::make_shared(); + } else if (transform_name == "ResizeByShort") { + return std::make_shared(); + } else if (transform_name == "CenterCrop") { + return std::make_shared(); + } else if (transform_name == "Resize") { + return std::make_shared(); + } else if (transform_name == "Padding") { + return std::make_shared(); + } else if (transform_name == "ResizeByLong") { + return std::make_shared(); + } else { + std::cerr << "There's unexpected transform(name='" << transform_name + << "')." << std::endl; + exit(-1); + } +} + +bool Transforms::Run(cv::Mat* im, ImageBlob* data) { + // 按照transforms中预处理算子顺序处理图像 + if (to_rgb_) { + cv::cvtColor(*im, *im, cv::COLOR_BGR2RGB); + } + (*im).convertTo(*im, CV_32FC3); + data->ori_im_size_[0] = im->rows; + data->ori_im_size_[1] = im->cols; + data->new_im_size_[0] = im->rows; + data->new_im_size_[1] = im->cols; + for (int i = 0; i < transforms_.size(); ++i) { + if (!transforms_[i]->Run(im, data)) { + std::cerr << "Apply transforms to image failed!" << std::endl; + return false; + } + } + + // 将图像由NHWC转为NCHW格式 + // 同时转为连续的内存块存储到ImageBlob + int h = im->rows; + int w = im->cols; + int c = im->channels(); + (data->im_data_).resize(c * h * w); + float* ptr = (data->im_data_).data(); + for (int i = 0; i < c; ++i) { + cv::extractChannel(*im, cv::Mat(h, w, CV_32FC1, ptr + i * h * w), i); + } + return true; +} +} // namespace PaddleX diff --git a/deploy/cpp_dll/src/visualize.cpp b/deploy/cpp_dll/src/visualize.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c399f4e3fd0f522df770e387f58a38d04554985 --- /dev/null +++ b/deploy/cpp_dll/src/visualize.cpp @@ -0,0 +1,148 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "include/paddlex/visualize.h" + +namespace PaddleX { +std::vector GenerateColorMap(int num_class) { + auto colormap = std::vector(3 * num_class, 0); + for (int i = 0; i < num_class; ++i) { + int j = 0; + int lab = i; + while (lab) { + colormap[i * 3] |= (((lab >> 0) & 1) << (7 - j)); + colormap[i * 3 + 1] |= (((lab >> 1) & 1) << (7 - j)); + colormap[i * 3 + 2] |= (((lab >> 2) & 1) << (7 - j)); + ++j; + lab >>= 3; + } + } + return colormap; +} + +cv::Mat Visualize(const cv::Mat& img, + const DetResult& result, + const std::map& labels, + const std::vector& colormap, + float threshold) { + cv::Mat vis_img = img.clone(); + auto boxes = result.boxes; + for (int i = 0; i < boxes.size(); ++i) { + if (boxes[i].score < threshold) { + continue; + } + cv::Rect roi = cv::Rect(boxes[i].coordinate[0], + boxes[i].coordinate[1], + boxes[i].coordinate[2], + boxes[i].coordinate[3]); + + // 生成预测框和标题 + std::string text = boxes[i].category; + int c1 = colormap[3 * boxes[i].category_id + 0]; + int c2 = colormap[3 * boxes[i].category_id + 1]; + int c3 = colormap[3 * boxes[i].category_id + 2]; + cv::Scalar roi_color = cv::Scalar(c1, c2, c3); + text += std::to_string(static_cast(boxes[i].score * 100)) + "%"; + int font_face = cv::FONT_HERSHEY_SIMPLEX; + double font_scale = 0.5f; + float thickness = 0.5; + cv::Size text_size = + cv::getTextSize(text, font_face, font_scale, thickness, nullptr); + cv::Point origin; + origin.x = roi.x; + origin.y = roi.y; + + // 生成预测框标题的背景 + cv::Rect text_back = cv::Rect(boxes[i].coordinate[0], + boxes[i].coordinate[1] - text_size.height, + text_size.width, + text_size.height); + + // 绘图和文字 + cv::rectangle(vis_img, roi, roi_color, 2); + cv::rectangle(vis_img, text_back, roi_color, -1); + cv::putText(vis_img, + text, + origin, + font_face, + font_scale, + cv::Scalar(255, 255, 255), + thickness); + + // 生成实例分割mask + if (boxes[i].mask.data.size() == 0) { + continue; + } + cv::Mat bin_mask(result.mask_resolution, + result.mask_resolution, + CV_32FC1, + boxes[i].mask.data.data()); + cv::resize(bin_mask, + bin_mask, + cv::Size(boxes[i].mask.shape[0], boxes[i].mask.shape[1])); + cv::threshold(bin_mask, bin_mask, 0.5, 1, cv::THRESH_BINARY); + cv::Mat full_mask = cv::Mat::zeros(vis_img.size(), CV_8UC1); + bin_mask.copyTo(full_mask(roi)); + cv::Mat mask_ch[3]; + mask_ch[0] = full_mask * c1; + mask_ch[1] = full_mask * c2; + mask_ch[2] = full_mask * c3; + cv::Mat mask; + cv::merge(mask_ch, 3, mask); + cv::addWeighted(vis_img, 1, mask, 0.5, 0, vis_img); + } + return vis_img; +} + +cv::Mat Visualize(const cv::Mat& img, + const SegResult& result, + const std::map& labels, + const std::vector& colormap) { + std::vector label_map(result.label_map.data.begin(), + result.label_map.data.end()); + cv::Mat mask(result.label_map.shape[0], + result.label_map.shape[1], + CV_8UC1, + label_map.data()); + cv::Mat color_mask = cv::Mat::zeros( + result.label_map.shape[0], result.label_map.shape[1], CV_8UC3); + int rows = img.rows; + int cols = img.cols; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + int category_id = static_cast(mask.at(i, j)); + color_mask.at(i, j)[0] = colormap[3 * category_id + 0]; + color_mask.at(i, j)[1] = colormap[3 * category_id + 1]; + color_mask.at(i, j)[2] = colormap[3 * category_id + 2]; + } + } + return color_mask; +} + +std::string generate_save_path(const std::string& save_dir, + const std::string& file_path) { + if (access(save_dir.c_str(), 0) < 0) { +#ifdef _WIN32 + mkdir(save_dir.c_str()); +#else + if (mkdir(save_dir.c_str(), S_IRWXU) < 0) { + std::cerr << "Fail to create " << save_dir << "directory." << std::endl; + } +#endif + } + int pos = file_path.find_last_of(OS_PATH_SEP); + std::string image_name(file_path.substr(pos + 1)); + return save_dir + OS_PATH_SEP + image_name; +} +} // namespace of PaddleX diff --git a/deploy/cpp_dll/test_dll.py b/deploy/cpp_dll/test_dll.py new file mode 100644 index 0000000000000000000000000000000000000000..a50af298cf8db4f69ec3a8c840059aef85171a91 --- /dev/null +++ b/deploy/cpp_dll/test_dll.py @@ -0,0 +1,3 @@ +from ctypes import * +dll=CDLL("./detector.dll") +print(dll.Loadmodel()) \ No newline at end of file