50 changed files with 2062 additions and 0 deletions
-
919hs_err_pid2456.log
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/FileContentIndex/2270b3c9-5d67-4e03-9758-59f046769474.vsidx
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/FileContentIndex/243d118b-9d07-4083-8e3b-f236ad9c2979.vsidx
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/FileContentIndex/30e4e9f3-18f7-40aa-b301-8b65b533f8e9.vsidx
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/FileContentIndex/6cafa410-fb9d-4673-9694-4211e982e203.vsidx
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/FileContentIndex/bdbc7a49-cf3d-4790-9cac-d369f5504243.vsidx
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/.suo
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/Browse.VC.db
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/Solution.VC.db
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/44e68d184a412966/LOGGER.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/574016c32a77b833/OPT_ALGO.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/6968a1d6e2fbb0b6/COM_IFLYTOP_A800_UTILS_SCANRESULTANALYSISALGO.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/84c0eda70c4eb593/COM_IFLYTOP_A800_UTILS_SCANRESULTANALYSISALGO.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/87e525de9906ee01/MAIN.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/a55d8f98aadcd463/COM_DREAMWORKS_BODITECH_UTILS_MYOPTALGO.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/c4ab269b9841c983/OPT_ALGO.ipch
-
BINlib-algo/.vs/boditech-opt-algo-java-lib/v17/ipch/AutoPCH/f95a4ae92349b5b3/COM_DREAMWORKS_BODITECH_UTILS_MYOPTALGO.ipch
-
31lib-algo/boditech-opt-algo-java-lib.sln
-
145lib-algo/boditech-opt-algo-java-lib.vcxproj
-
39lib-algo/boditech-opt-algo-java-lib.vcxproj.filters
-
4lib-algo/boditech-opt-algo-java-lib.vcxproj.user
-
80lib-algo/com_iflytop_a800_utils_ScanResultAnalysisAlgo.cpp
-
21lib-algo/com_iflytop_a800_utils_ScanResultAnalysisAlgo.h
-
2lib-algo/generate_header.ps1
-
13lib-algo/logger.cpp
-
10lib-algo/logger.hpp
-
567lib-algo/opt_algo.cpp
-
209lib-algo/opt_algo.hpp
-
BINlib-algo/x64/Debug/boditech-opt-algo-java-lib.dll
-
11lib-algo/x64/Debug/boditech-opt-algo-java-lib.dll.recipe
-
BINlib-algo/x64/Debug/boditech-opt-algo-java-lib.exp
-
BINlib-algo/x64/Debug/boditech-opt-algo-java-lib.ilk
-
BINlib-algo/x64/Debug/boditech-opt-algo-java-lib.lib
-
5lib-algo/x64/Debug/boditech-opt-algo-java-lib.log
-
BINlib-algo/x64/Debug/boditech-opt-algo-java-lib.pdb
-
1lib-algo/x64/Debug/boditech-opt-algo-java-lib.vcxproj.FileListAbsolute.txt
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/CL.command.1.tlog
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/CL.read.1.tlog
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/CL.write.1.tlog
-
3lib-algo/x64/Debug/boditech.e660ba62.tlog/Cl.items.tlog
-
2lib-algo/x64/Debug/boditech.e660ba62.tlog/boditech-opt-algo-java-lib.lastbuildstate
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/link.command.1.tlog
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/link.read.1.tlog
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/link.write.1.tlog
-
BINlib-algo/x64/Debug/boditech.e660ba62.tlog/link.write.2u.tlog
-
BINlib-algo/x64/Debug/com_iflytop_a800_utils_ScanResultAnalysisAlgo.obj
-
BINlib-algo/x64/Debug/logger.obj
-
BINlib-algo/x64/Debug/opt_algo.obj
-
BINlib-algo/x64/Debug/vc143.idb
-
BINlib-algo/x64/Debug/vc143.pdb
919
hs_err_pid2456.log
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,31 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
|
# Visual Studio Version 17 |
||||
|
VisualStudioVersion = 17.8.34330.188 |
||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boditech-opt-algo-java-lib", "boditech-opt-algo-java-lib.vcxproj", "{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|x64 = Debug|x64 |
||||
|
Debug|x86 = Debug|x86 |
||||
|
Release|x64 = Release|x64 |
||||
|
Release|x86 = Release|x86 |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Debug|x64.ActiveCfg = Debug|x64 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Debug|x64.Build.0 = Debug|x64 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Debug|x86.ActiveCfg = Debug|Win32 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Debug|x86.Build.0 = Debug|Win32 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Release|x64.ActiveCfg = Release|x64 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Release|x64.Build.0 = Release|x64 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Release|x86.ActiveCfg = Release|Win32 |
||||
|
{E660BA62-4A7D-493F-BF6F-19BBFCA8C964}.Release|x86.Build.0 = Release|Win32 |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
|
SolutionGuid = {92F47F9D-3C1A-4B0F-B38A-86E7C7E06C8B} |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
@ -0,0 +1,145 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project DefaultTargets="Build" 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"> |
||||
|
<VCProjectVersion>17.0</VCProjectVersion> |
||||
|
<Keyword>Win32Proj</Keyword> |
||||
|
<ProjectGuid>{e660ba62-4a7d-493f-bf6f-19bbfca8c964}</ProjectGuid> |
||||
|
<RootNamespace>boditechoptalgojavalib</RootNamespace> |
||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
|
<ConfigurationType>Application</ConfigurationType> |
||||
|
<UseDebugLibraries>true</UseDebugLibraries> |
||||
|
<PlatformToolset>v143</PlatformToolset> |
||||
|
<CharacterSet>Unicode</CharacterSet> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
|
<ConfigurationType>Application</ConfigurationType> |
||||
|
<UseDebugLibraries>false</UseDebugLibraries> |
||||
|
<PlatformToolset>v143</PlatformToolset> |
||||
|
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||
|
<CharacterSet>Unicode</CharacterSet> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<UseDebugLibraries>true</UseDebugLibraries> |
||||
|
<PlatformToolset>v143</PlatformToolset> |
||||
|
<CharacterSet>Unicode</CharacterSet> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |
||||
|
<ConfigurationType>Application</ConfigurationType> |
||||
|
<UseDebugLibraries>false</UseDebugLibraries> |
||||
|
<PlatformToolset>v143</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|x64'"> |
||||
|
<ExternalIncludePath>D:\ProgramFiles\JDK\18\include;D:\ProgramFiles\JDK\18\include\win32;$(ExternalIncludePath)</ExternalIncludePath> |
||||
|
</PropertyGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
|
<ClCompile> |
||||
|
<WarningLevel>Level3</WarningLevel> |
||||
|
<SDLCheck>true</SDLCheck> |
||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<ConformanceMode>true</ConformanceMode> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<SubSystem>Console</SubSystem> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
|
<ClCompile> |
||||
|
<WarningLevel>Level3</WarningLevel> |
||||
|
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
|
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
|
<SDLCheck>true</SDLCheck> |
||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<ConformanceMode>true</ConformanceMode> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<SubSystem>Console</SubSystem> |
||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
|
<OptimizeReferences>true</OptimizeReferences> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||
|
<ClCompile> |
||||
|
<WarningLevel>Level3</WarningLevel> |
||||
|
<SDLCheck>true</SDLCheck> |
||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<ConformanceMode>true</ConformanceMode> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<SubSystem>Console</SubSystem> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||
|
<ClCompile> |
||||
|
<WarningLevel>Level3</WarningLevel> |
||||
|
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
|
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
|
<SDLCheck>true</SDLCheck> |
||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<ConformanceMode>true</ConformanceMode> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<SubSystem>Console</SubSystem> |
||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
|
<OptimizeReferences>true</OptimizeReferences> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemGroup> |
||||
|
<ClInclude Include="com_iflytop_a800_utils_ScanResultAnalysisAlgo.h" /> |
||||
|
<ClInclude Include="logger.hpp" /> |
||||
|
<ClInclude Include="opt_algo.hpp" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ClCompile Include="com_iflytop_a800_utils_ScanResultAnalysisAlgo.cpp" /> |
||||
|
<ClCompile Include="logger.cpp" /> |
||||
|
<ClCompile Include="opt_algo.cpp" /> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
|
<ImportGroup Label="ExtensionTargets"> |
||||
|
</ImportGroup> |
||||
|
</Project> |
@ -0,0 +1,39 @@ |
|||||
|
<?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;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions> |
||||
|
</Filter> |
||||
|
<Filter Include="头文件"> |
||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> |
||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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="opt_algo.hpp"> |
||||
|
<Filter>头文件</Filter> |
||||
|
</ClInclude> |
||||
|
<ClInclude Include="logger.hpp"> |
||||
|
<Filter>头文件</Filter> |
||||
|
</ClInclude> |
||||
|
<ClInclude Include="com_iflytop_a800_utils_ScanResultAnalysisAlgo.h"> |
||||
|
<Filter>头文件</Filter> |
||||
|
</ClInclude> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ClCompile Include="opt_algo.cpp"> |
||||
|
<Filter>源文件</Filter> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="logger.cpp"> |
||||
|
<Filter>源文件</Filter> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="com_iflytop_a800_utils_ScanResultAnalysisAlgo.cpp"> |
||||
|
<Filter>源文件</Filter> |
||||
|
</ClCompile> |
||||
|
</ItemGroup> |
||||
|
</Project> |
@ -0,0 +1,4 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup /> |
||||
|
</Project> |
@ -0,0 +1,80 @@ |
|||||
|
#include <jni.h>
|
||||
|
#include "com_iflytop_a800_utils_ScanResultAnalysisAlgo.h"
|
||||
|
#include "opt_algo.hpp"
|
||||
|
using namespace opt_algo; |
||||
|
/*
|
||||
|
* Class: com_dreamworks_boditech_utils_MyOptAlgo |
||||
|
* Method: calculate |
||||
|
* Signature: ([FI)V |
||||
|
*/ |
||||
|
JNIEXPORT jobject JNICALL Java_com_iflytop_a800_utils_ScanResultAnalysisAlgo_calculate(JNIEnv* env, jobject, jfloatArray data, jint peakNum) { |
||||
|
jsize dataLen = env->GetArrayLength(data); |
||||
|
jfloat * dataElements = env->GetFloatArrayElements(data, nullptr); |
||||
|
|
||||
|
vector<float> originVal; |
||||
|
originVal.reserve(dataLen); |
||||
|
for (int i = 0; i < dataLen; ++i) { |
||||
|
originVal.push_back(dataElements[i]); |
||||
|
} |
||||
|
env->ReleaseFloatArrayElements(data, dataElements, JNI_ABORT); |
||||
|
|
||||
|
shared_ptr<AlgoResult> algoResult; |
||||
|
algoResult = OptAlgo::calculate(originVal, peakNum); |
||||
|
if (nullptr == algoResult) { |
||||
|
return nullptr; |
||||
|
} |
||||
|
|
||||
|
// setup result
|
||||
|
jclass resultClass = env->FindClass("com/iflytop/a800/utils/ScanResultAnalysisAlgo$AlgoResult"); |
||||
|
jmethodID resultConstructor = env->GetMethodID(resultClass, "<init>", "()V"); |
||||
|
jobject resultObject = env->NewObject(resultClass, resultConstructor); |
||||
|
|
||||
|
// peak num
|
||||
|
jfieldID resultPeakNumFieldID = env->GetFieldID(resultClass, "peakNum", "I"); |
||||
|
env->SetIntField(resultObject, resultPeakNumFieldID, algoResult->peakNum); |
||||
|
|
||||
|
// lineAvg250
|
||||
|
jfloatArray lineAvg250 = env->NewFloatArray(250); |
||||
|
jfloat lineAvg250Values[250]; |
||||
|
for (int i = 0; i < 250; ++i) { |
||||
|
lineAvg250Values[i] = algoResult->lineContext->avg250[i]; |
||||
|
} |
||||
|
env->SetFloatArrayRegion(lineAvg250, 0, 250, lineAvg250Values); |
||||
|
jfieldID lineAvg250FieldID = env->GetFieldID(resultClass, "lineAvg250", "[F"); |
||||
|
env->SetObjectField(resultObject, lineAvg250FieldID, lineAvg250); |
||||
|
|
||||
|
// PeakInfos
|
||||
|
jint maxPeakInfoCount = 5; |
||||
|
jclass resultPeakInfoClass = env->FindClass("com/iflytop/a800/utils/ScanResultAnalysisAlgo$AlgoResult$PeakInfo"); |
||||
|
jobjectArray resultPeakInfoArray = env->NewObjectArray(maxPeakInfoCount, resultPeakInfoClass, nullptr); |
||||
|
for (int i = 0; i < maxPeakInfoCount; ++i) { |
||||
|
jmethodID resultPeakInfoConstructor = env->GetMethodID(resultPeakInfoClass, "<init>", "()V"); |
||||
|
jobject resultPeakInfo = env->NewObject(resultPeakInfoClass, resultPeakInfoConstructor); |
||||
|
// findPeak
|
||||
|
jfieldID findPeakFieldID = env->GetFieldID(resultPeakInfoClass, "findPeak", "Z"); |
||||
|
env->SetBooleanField(resultPeakInfo, findPeakFieldID, algoResult->peakInfo[i]->find_peak ? JNI_TRUE : JNI_FALSE); |
||||
|
// peakFullArea
|
||||
|
jfieldID peakFullAreaFieldID = env->GetFieldID(resultPeakInfoClass, "peakFullArea", "F"); |
||||
|
env->SetFloatField(resultPeakInfo, peakFullAreaFieldID, algoResult->peakInfo[i]->peak_full_area); |
||||
|
// peakBaseLineArea
|
||||
|
jfieldID peakBaseLineAreaFieldID = env->GetFieldID(resultPeakInfoClass, "peakBaseLineArea", "F"); |
||||
|
env->SetFloatField(resultPeakInfo, peakBaseLineAreaFieldID, algoResult->peakInfo[i]->peak_base_line_area); |
||||
|
// area
|
||||
|
jfieldID areaFieldID = env->GetFieldID(resultPeakInfoClass, "area", "F"); |
||||
|
env->SetFloatField(resultPeakInfo, areaFieldID, algoResult->peakInfo[i]->area); |
||||
|
// peakPos
|
||||
|
jfieldID peakPosFieldID = env->GetFieldID(resultPeakInfoClass, "peakPos", "I"); |
||||
|
env->SetIntField(resultPeakInfo, peakPosFieldID, algoResult->peakInfo[i]->peak_pos); |
||||
|
// peakStartPos
|
||||
|
jfieldID peakStartPosFieldID = env->GetFieldID(resultPeakInfoClass, "peakStartPos", "I"); |
||||
|
env->SetIntField(resultPeakInfo, peakStartPosFieldID, algoResult->peakInfo[i]->peak_start_pos); |
||||
|
// peakEndPos
|
||||
|
jfieldID peakEndPosFieldID = env->GetFieldID(resultPeakInfoClass, "peakEndPos", "I"); |
||||
|
env->SetIntField(resultPeakInfo, peakEndPosFieldID, algoResult->peakInfo[i]->peak_end_pos); |
||||
|
env->SetObjectArrayElement(resultPeakInfoArray, i, resultPeakInfo); |
||||
|
} |
||||
|
jfieldID resultPeakInfoFieldID = env->GetFieldID(resultClass, "peakInfos", "[Lcom/iflytop/a800/utils/ScanResultAnalysisAlgo$AlgoResult$PeakInfo;"); |
||||
|
env->SetObjectField(resultObject, resultPeakInfoFieldID, resultPeakInfoArray); |
||||
|
|
||||
|
return resultObject; |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */ |
||||
|
#include <jni.h> |
||||
|
/* Header for class com_iflytop_a800_utils_ScanResultAnalysisAlgo */ |
||||
|
|
||||
|
#ifndef _Included_com_iflytop_a800_utils_ScanResultAnalysisAlgo |
||||
|
#define _Included_com_iflytop_a800_utils_ScanResultAnalysisAlgo |
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
/* |
||||
|
* Class: com_iflytop_a800_utils_ScanResultAnalysisAlgo |
||||
|
* Method: calculate |
||||
|
* Signature: ([FI)Lcom/iflytop/a800/utils/ScanResultAnalysisAlgo/AlgoResult; |
||||
|
*/ |
||||
|
JNIEXPORT jobject JNICALL Java_com_iflytop_a800_utils_ScanResultAnalysisAlgo_calculate |
||||
|
(JNIEnv *, jobject, jfloatArray, jint); |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
#endif |
@ -0,0 +1,2 @@ |
|||||
|
javac ..\src\main\java\com\iflytop\a800\utils\ScanResultAnalysisAlgo.java -h . |
||||
|
rm ..\src\main\java\com\iflytop\a800\utils\ScanResultAnalysisAlgo*.class |
@ -0,0 +1,13 @@ |
|||||
|
#include "logger.hpp"
|
||||
|
|
||||
|
#include <stdarg.h>
|
||||
|
#include <stdio.h>
|
||||
|
|
||||
|
void zos_log(const char *fmt, ...) { |
||||
|
va_list args; |
||||
|
va_start(args, fmt); |
||||
|
char buf[1024] = {0}; |
||||
|
vsnprintf(buf, sizeof(buf), fmt, args); |
||||
|
printf("%s", buf); |
||||
|
va_end(args); |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
#pragma once
|
||||
|
#include <stdint.h>
|
||||
|
|
||||
|
void zos_log(const char *fmt, ...); |
||||
|
|
||||
|
#define ZLOGI(TAG, fmt, ...) zos_log("INFO [%-10s] " fmt "\n", TAG, ##__VA_ARGS__);
|
||||
|
#define ZLOGD(TAG, fmt, ...) zos_log("DEBU [%-10s] " fmt "\n", TAG, ##__VA_ARGS__);
|
||||
|
#define ZLOGE(TAG, fmt, ...) zos_log("ERRO [%-10s] " fmt "\n", TAG, ##__VA_ARGS__);
|
||||
|
#define ZLOGW(TAG, fmt, ...) zos_log("WARN [%-10s] " fmt "\n", TAG, ##__VA_ARGS__);
|
@ -0,0 +1,567 @@ |
|||||
|
#include "opt_algo.hpp"
|
||||
|
#include "logger.hpp"
|
||||
|
|
||||
|
using namespace opt_algo; |
||||
|
using namespace std; |
||||
|
|
||||
|
#define TAG "OptAlgo"
|
||||
|
|
||||
|
#define BASE_LINE_SLOPE_SAMPLE_POS 240
|
||||
|
#define VERSION 1
|
||||
|
static void algo_assert(bool condition, const char* msg) { |
||||
|
if (!condition) { |
||||
|
ZLOGE(TAG, "algo_assert:%s", msg); |
||||
|
throw std::runtime_error(msg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int OptAlgo::getAlgoVersion() { return VERSION; } |
||||
|
|
||||
|
int OptAlgo::calculate_peak_num(vector<float>& ogigin_val) { |
||||
|
float avg = 0; |
||||
|
int peakNum = 0; |
||||
|
|
||||
|
for (size_t i = 0; i < ogigin_val.size(); i++) { |
||||
|
avg += ogigin_val[i]; |
||||
|
} |
||||
|
avg = avg / ogigin_val.size(); |
||||
|
|
||||
|
bool findPeak = false; |
||||
|
for (size_t i = 0; i < ogigin_val.size(); i++) { |
||||
|
if (!findPeak && ogigin_val[i] > avg) { |
||||
|
findPeak = true; |
||||
|
peakNum++; |
||||
|
} |
||||
|
|
||||
|
if (findPeak && ogigin_val[i] < avg) { |
||||
|
findPeak = false; |
||||
|
} |
||||
|
} |
||||
|
return peakNum; |
||||
|
} |
||||
|
|
||||
|
shared_ptr<AlgoResult> OptAlgo::calculate(vector<float> ogigin_val, int peaknum) { |
||||
|
shared_ptr<AlgoResult> algoResult = make_shared<AlgoResult>(); |
||||
|
|
||||
|
algoResult->ogigin_val = ogigin_val; |
||||
|
|
||||
|
algoResult->supper_val = super_sampling(ogigin_val, ogigin_val.size(), 5); // pointNum:1200*5=6000
|
||||
|
algoResult->supper_median_val = median_filtering(algoResult->supper_val, 25); // pointNum:6000
|
||||
|
algoResult->supper_smooth_sub_val = sub_sampling(algoResult->supper_median_val, 6); // pointNum:6000/6=1000
|
||||
|
|
||||
|
algoResult->lineContext->raw = sub_sampling(algoResult->supper_median_val, 6); |
||||
|
algoResult->lineContext->avg = smooth_windows(algoResult->supper_smooth_sub_val, 13); |
||||
|
vector<float> diffpreprocess = least_square_method_differentiate(algoResult->supper_smooth_sub_val, 13); |
||||
|
algoResult->lineContext->diff = smooth_windows(diffpreprocess, 13); |
||||
|
algoResult->lineContext->agvline = find_avg_line(algoResult->supper_smooth_sub_val); |
||||
|
|
||||
|
algoResult->lineContext->raw250 = sub_sampling(algoResult->lineContext->raw, 4); |
||||
|
algoResult->lineContext->avg250 = sub_sampling(algoResult->lineContext->avg, 4); |
||||
|
algoResult->lineContext->diff250 = sub_sampling(algoResult->lineContext->diff, 4); |
||||
|
|
||||
|
/**
|
||||
|
* @brief |
||||
|
* |
||||
|
* 当前系统中反应的结果一共5种 |
||||
|
* |
||||
|
* 峰数量2: |
||||
|
* 80,120 |
||||
|
* 峰数量3: |
||||
|
* 40,80,120 |
||||
|
* 峰的数量4: |
||||
|
* 40,80,120,160 |
||||
|
* 峰的数量5: |
||||
|
* 40,80,120,160,200 |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
/**
|
||||
|
* @brief |
||||
|
* 这几取曲线在绝对坐标40(10*4)位置的曲率,因为按照巴迪泰给的项目参考,在前坐标40(250个点的情况),是第一个峰,所以 |
||||
|
* 这里假设坐标10位置是第一个峰的前置位置,然后取曲线在这个位置的斜率,作为基线斜率。 |
||||
|
*/ |
||||
|
|
||||
|
// int baseline_sample_pos = 0;
|
||||
|
vector<int> slop_smaple_xstart; |
||||
|
if (peaknum == 2) { |
||||
|
slop_smaple_xstart.push_back(10 * 4); |
||||
|
slop_smaple_xstart.push_back(20 * 4); |
||||
|
slop_smaple_xstart.push_back(200 * 4); |
||||
|
} else if (peaknum == 3) { |
||||
|
slop_smaple_xstart.push_back(10 * 4); |
||||
|
slop_smaple_xstart.push_back(200 * 4); |
||||
|
slop_smaple_xstart.push_back(235 * 4); |
||||
|
|
||||
|
} else if (peaknum == 4) { |
||||
|
slop_smaple_xstart.push_back(10 * 4); |
||||
|
slop_smaple_xstart.push_back(200 * 4); |
||||
|
slop_smaple_xstart.push_back(235 * 4); |
||||
|
|
||||
|
} else if (peaknum == 5) { |
||||
|
slop_smaple_xstart.push_back(10 * 4); |
||||
|
slop_smaple_xstart.push_back(235 * 4); |
||||
|
} |
||||
|
|
||||
|
linear_least_squares_muti_windos(&algoResult->lineContext->avg[0], (int)algoResult->lineContext->avg.size(), slop_smaple_xstart, |
||||
|
5 * 4, //
|
||||
|
algoResult->lineContext->baseline_slope, //
|
||||
|
algoResult->lineContext->baseline_intercept); |
||||
|
|
||||
|
for (size_t i = 0; i < peaknum; i++) { |
||||
|
Error_t ret = k_ecode_ok; |
||||
|
if (i == 0) { |
||||
|
if (peaknum == 2) { |
||||
|
ret = findpeak(algoResult->lineContext, 80 * 4, 80 * 4, algoResult->peakInfo[0]); |
||||
|
} else if (peaknum == 3) { |
||||
|
ret = findpeak(algoResult->lineContext, 40 * 4, 80 * 4, algoResult->peakInfo[0]); |
||||
|
} else if (peaknum == 4) { |
||||
|
ret = findpeak(algoResult->lineContext, 40 * 4, 80 * 4, algoResult->peakInfo[0]); |
||||
|
} else if (peaknum == 5) { |
||||
|
ret = findpeak(algoResult->lineContext, 40 * 4, 80 * 4, algoResult->peakInfo[0]); |
||||
|
} |
||||
|
} else { |
||||
|
ret = findpeak(algoResult->lineContext, algoResult->peakInfo[i - 1]->peak_end_pos, 80 * 4, algoResult->peakInfo[i]); |
||||
|
} |
||||
|
|
||||
|
if (ret != k_ecode_ok) { |
||||
|
algoResult->error_code = ret; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
algoResult->peakNum = peaknum; |
||||
|
return algoResult; |
||||
|
} |
||||
|
|
||||
|
vector<float> OptAlgo::differentiate(vector<float>& inputRaw) { |
||||
|
/**
|
||||
|
* @brief |
||||
|
* 巴迪泰源码,对原始数据添加了一些微小的值,原因未知 |
||||
|
*/ |
||||
|
for (int i = 0; i <= inputRaw.size() - 8; i += 8) { |
||||
|
inputRaw[i + 1] = inputRaw[i + 1] + 0.001f; |
||||
|
inputRaw[i + 2] = inputRaw[i + 2] + 0.002f; |
||||
|
inputRaw[i + 3] = inputRaw[i + 3] + 0.003f; |
||||
|
inputRaw[i + 4] = inputRaw[i + 4] + 0.004f; |
||||
|
inputRaw[i + 5] = inputRaw[i + 5] + 0.005f; |
||||
|
inputRaw[i + 6] = inputRaw[i + 6] + 0.004f; |
||||
|
inputRaw[i + 7] = inputRaw[i + 7] + 0.003f; |
||||
|
inputRaw[i + 8] = inputRaw[i + 8] + 0.002f; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief |
||||
|
* @Warning: 此处求导和巴迪泰的存在差异, |
||||
|
* 巴迪泰的是当前数值减去下一个数值, |
||||
|
* 而此处是当前数值减去上一个数值 |
||||
|
*/ |
||||
|
|
||||
|
vector<float> differentiateRaw(inputRaw.size(), 0); |
||||
|
for (size_t i = 1; i < differentiateRaw.size(); i++) { |
||||
|
differentiateRaw[i] = inputRaw[i] - inputRaw[i - 1]; |
||||
|
} |
||||
|
differentiateRaw[0] = differentiateRaw[1]; |
||||
|
return differentiateRaw; |
||||
|
} |
||||
|
|
||||
|
vector<float> OptAlgo::least_square_method_differentiate(vector<float>& inputRaw, int windows_size) { |
||||
|
algo_assert(windows_size > 0, "windows_size <= 0"); |
||||
|
algo_assert(windows_size % 2 == 1, "windows_size is not odd"); |
||||
|
|
||||
|
vector<float> differentiateRaw(inputRaw.size(), 0); |
||||
|
vector<float> windowsRaw(windows_size, 0); |
||||
|
int windows_size_half = (windows_size - 1) / 2; |
||||
|
|
||||
|
for (int index = windows_size_half; index < inputRaw.size() - windows_size_half; index++) { |
||||
|
windowsRaw = getwindowspoint(inputRaw, index, windows_size); |
||||
|
float intercept = 0; |
||||
|
linear_least_squares(windowsRaw.data(), windows_size, differentiateRaw[index], intercept); |
||||
|
} |
||||
|
|
||||
|
for (size_t i = 0; i < windows_size_half; i++) { |
||||
|
differentiateRaw[i] = differentiateRaw[windows_size_half]; |
||||
|
} |
||||
|
|
||||
|
for (size_t i = inputRaw.size() - windows_size_half; i < inputRaw.size(); i++) { |
||||
|
differentiateRaw[i] = differentiateRaw[inputRaw.size() - windows_size_half - 1]; |
||||
|
} |
||||
|
return differentiateRaw; |
||||
|
} |
||||
|
/**
|
||||
|
* @brief 最小二乘法求解曲线斜率 |
||||
|
* |
||||
|
* @param val Y轴数据 |
||||
|
* @param size Y轴数据长度 |
||||
|
* @return float 斜率 |
||||
|
*/ |
||||
|
|
||||
|
void OptAlgo::linear_least_squares(vector<float>& x, vector<float>& y, float& slope, float& intercept) { |
||||
|
size_t n = x.size(); |
||||
|
double sumX = 0.0, sumY = 0.0, sumXY = 0.0, sumXX = 0.0; |
||||
|
for (size_t i = 0; i < n; ++i) { |
||||
|
sumX += x[i]; |
||||
|
sumY += y[i]; |
||||
|
sumXY += x[i] * y[i]; |
||||
|
sumXX += x[i] * x[i]; |
||||
|
} |
||||
|
double xMean = sumX / n; |
||||
|
double yMean = sumY / n; |
||||
|
|
||||
|
algo_assert(!feq((sumXX - n * xMean * xMean), 0, 0.0001), "sumXX - n * xMean * xMean == 0"); |
||||
|
slope = (sumXY - n * xMean * yMean) / (sumXX - n * xMean * xMean); |
||||
|
intercept = yMean - slope * xMean; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
void OptAlgo::linear_least_squares(float* y, int size, float& slope, float& intercept) { |
||||
|
vector<float> xpoint(size, 0); |
||||
|
vector<float> ypoint(size, 0); |
||||
|
|
||||
|
for (size_t i = 0; i < size; i++) { |
||||
|
xpoint[i] = i; |
||||
|
ypoint[i] = y[i]; |
||||
|
} |
||||
|
return linear_least_squares(xpoint, ypoint, slope, intercept); |
||||
|
} |
||||
|
|
||||
|
void OptAlgo::linear_least_squares_muti_windos(float* y, int size, vector<int> startx, int windowssize, float& slope, float& intercept) { |
||||
|
vector<float> xpoint; |
||||
|
vector<float> ypoint; |
||||
|
|
||||
|
// ZLOGI(TAG, "xxxxx%d", startx.size());
|
||||
|
|
||||
|
for (size_t i = 0; i < startx.size(); i++) { |
||||
|
int xstart = startx[i]; |
||||
|
|
||||
|
for (size_t xindex = xstart; xindex < (xstart + windowssize); xindex++) { |
||||
|
// ZLOGI(TAG, "xindex:%d y:%f", xindex, y[xindex]);
|
||||
|
xpoint.push_back(xindex); |
||||
|
ypoint.push_back(y[xindex]); |
||||
|
} |
||||
|
} |
||||
|
return linear_least_squares(xpoint, ypoint, slope, intercept); |
||||
|
} |
||||
|
|
||||
|
vector<float> OptAlgo::super_sampling(vector<float>& inputRaw, int32_t nInputLength, int32_t nUpSampleRate) { |
||||
|
/**
|
||||
|
* @brief |
||||
|
* |
||||
|
*/ |
||||
|
int nOutputLength = nInputLength * nUpSampleRate; |
||||
|
vector<float> upSamplingRaw(nOutputLength, 0); |
||||
|
|
||||
|
for (int si = 0, di = 0; si < nInputLength - 1; di++) { |
||||
|
float a = upSamplingRaw[di * nUpSampleRate] = (float)inputRaw[si]; |
||||
|
float b = upSamplingRaw[(di + 1) * nUpSampleRate] = (float)inputRaw[++si]; |
||||
|
|
||||
|
float nSlope = (b - a) / nUpSampleRate; |
||||
|
|
||||
|
for (int i = 0; i < nUpSampleRate - 1; i++) { |
||||
|
int baseIndex = (di * nUpSampleRate) + i; |
||||
|
upSamplingRaw[baseIndex + 1] = upSamplingRaw[baseIndex] + nSlope; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return upSamplingRaw; |
||||
|
} |
||||
|
|
||||
|
vector<float> OptAlgo::sub_sampling(vector<float>& inputRaw, int nSubSampleRate) { |
||||
|
int nSum = 0; |
||||
|
float fAvg = 0; |
||||
|
int subIndex = 0; |
||||
|
int nOutputLength = inputRaw.size() / nSubSampleRate; |
||||
|
|
||||
|
vector<float> subSampledRaw(nOutputLength, 0); |
||||
|
|
||||
|
for (int index = 0; index < inputRaw.size(); index++) { |
||||
|
if (index % nSubSampleRate == 0 && index > 0) { |
||||
|
fAvg = nSum / nSubSampleRate; |
||||
|
if (subIndex < subSampledRaw.size()) { |
||||
|
subSampledRaw[subIndex++] = fAvg; |
||||
|
} else { |
||||
|
int empty = 0; |
||||
|
} |
||||
|
nSum = 0; |
||||
|
} |
||||
|
nSum += inputRaw[index]; |
||||
|
} |
||||
|
subSampledRaw[subSampledRaw.size() - 1] = subSampledRaw[subSampledRaw.size() - 2]; |
||||
|
return subSampledRaw; |
||||
|
} |
||||
|
|
||||
|
vector<float> OptAlgo::smooth_windows(vector<float>& inputRaw, int windows_size) { |
||||
|
vector<float> smoothRaw(inputRaw.size(), 0); |
||||
|
int windows_size_half = (windows_size - 1) / 2; |
||||
|
|
||||
|
for (int index = windows_size_half; index < inputRaw.size() - windows_size_half; index++) { |
||||
|
float sum = 0; |
||||
|
for (int i = index - windows_size_half; i <= index + windows_size_half; i++) { |
||||
|
sum += inputRaw[i]; |
||||
|
} |
||||
|
smoothRaw[index] = sum / windows_size; |
||||
|
} |
||||
|
|
||||
|
for (size_t i = 0; i < windows_size_half; i++) { |
||||
|
smoothRaw[i] = smoothRaw[windows_size_half]; |
||||
|
} |
||||
|
|
||||
|
for (size_t i = inputRaw.size() - windows_size_half; i < inputRaw.size(); i++) { |
||||
|
smoothRaw[i] = smoothRaw[inputRaw.size() - windows_size_half - 1]; |
||||
|
} |
||||
|
|
||||
|
return smoothRaw; |
||||
|
} |
||||
|
vector<float> OptAlgo::median_filtering(vector<float>& inputRaw, int windows_size) { |
||||
|
vector<float> medianRaw(inputRaw.size(), 0); |
||||
|
vector<float> windows(windows_size, 0); |
||||
|
|
||||
|
int windows_size_half = (windows_size - 1) / 2; |
||||
|
|
||||
|
for (int index = windows_size_half; index < inputRaw.size() - windows_size_half; index++) { |
||||
|
for (int i = 0; i < windows_size; i++) { |
||||
|
windows[i] = inputRaw[index + i - windows_size_half]; |
||||
|
} |
||||
|
sort_vector(windows); // 从小到大顺序排序
|
||||
|
medianRaw[index] = windows[windows_size_half + 1]; |
||||
|
} |
||||
|
|
||||
|
for (size_t i = 0; i < windows_size_half; i++) { |
||||
|
medianRaw[i] = medianRaw[windows_size_half]; |
||||
|
} |
||||
|
|
||||
|
for (size_t i = inputRaw.size() - windows_size_half; i < inputRaw.size(); i++) { |
||||
|
medianRaw[i] = medianRaw[inputRaw.size() - windows_size_half - 1]; |
||||
|
} |
||||
|
|
||||
|
return medianRaw; |
||||
|
} |
||||
|
|
||||
|
/**
|
||||
|
* @brief 求数据的均值 |
||||
|
* |
||||
|
* @param inputRaw |
||||
|
* @return float |
||||
|
*/ |
||||
|
float OptAlgo::find_avg_line(vector<float>& inputRaw) { |
||||
|
float base_min = 500; |
||||
|
float fsum = 0; |
||||
|
int cnt = 0; |
||||
|
|
||||
|
int range = inputRaw.size(); |
||||
|
|
||||
|
do { |
||||
|
fsum = cnt = 0; |
||||
|
for (int i = 1; i < range; i++) { |
||||
|
if (inputRaw[i] < base_min) { |
||||
|
fsum += inputRaw[i]; |
||||
|
cnt++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
base_min = base_min + 50; |
||||
|
} while (cnt < range - 15 * inputRaw.size() / 250); |
||||
|
|
||||
|
float fbase = fsum / cnt; |
||||
|
return fbase; |
||||
|
} |
||||
|
bool OptAlgo::feq(float a, float b, float epsilon) { |
||||
|
float dv = a - b; |
||||
|
if (dv < 0) dv = -dv; |
||||
|
return dv <= epsilon; |
||||
|
} |
||||
|
|
||||
|
Error_t OptAlgo::findpeak(shared_ptr<LineContext> lineContext, int32_t search_start, int32_t peakwindth, |
||||
|
shared_ptr<PeakInfo> retpeak) { //
|
||||
|
|
||||
|
/**
|
||||
|
* @brief 查找峰的位置 |
||||
|
* |
||||
|
* 思路: |
||||
|
* 搜索所有大于均值的点,当点满足,其数值大于附近一定数量的点时,认为是峰的位置 |
||||
|
* |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
ZLOGI(TAG, "findpeak start:%d windth:%d", search_start, peakwindth); |
||||
|
|
||||
|
// judge_win_size
|
||||
|
int judge_win_size = 2 * (lineContext->avg.size() / 250) + 1; |
||||
|
|
||||
|
int peakoff = //
|
||||
|
sub_find_peak(lineContext, search_start, peakwindth, judge_win_size); |
||||
|
if (peakoff < 0) return k_ecode_can_not_find_peak; |
||||
|
|
||||
|
retpeak->peak_pos = peakoff; |
||||
|
|
||||
|
/**
|
||||
|
* @brief 查找峰的起始位置 |
||||
|
* |
||||
|
* 思路: |
||||
|
* 从峰的位置开始,向前搜索,找到一个点,其值小于平均值。 |
||||
|
* 然后继续向前搜索,找到一个点,斜率接近基线斜率。 |
||||
|
* |
||||
|
*/ |
||||
|
int peak_start_pos = find_peak_endpoint(lineContext, retpeak->peak_pos, -1, peakwindth / 2); |
||||
|
int peak_end_pos = find_peak_endpoint(lineContext, retpeak->peak_pos, 1, peakwindth / 2); |
||||
|
|
||||
|
if (peak_start_pos < 0) return k_ecode_can_not_find_peak_start; |
||||
|
if (peak_end_pos < 0) return k_ecode_can_not_find_peak_end; |
||||
|
|
||||
|
retpeak->peak_start_pos = peak_start_pos; |
||||
|
retpeak->peak_end_pos = peak_end_pos; |
||||
|
|
||||
|
/**
|
||||
|
* @brief |
||||
|
* 计算峰的面积 |
||||
|
*/ |
||||
|
|
||||
|
float peak_full_area = 0; |
||||
|
for (int i = peak_start_pos; i <= peak_end_pos; i++) { |
||||
|
peak_full_area += lineContext->raw[i]; |
||||
|
} |
||||
|
|
||||
|
float peak_base_line_area = 0; |
||||
|
|
||||
|
#if 1
|
||||
|
peak_base_line_area = //
|
||||
|
(lineContext->raw[peak_start_pos] + lineContext->raw[peak_end_pos]) * 0.5 * (peak_end_pos - peak_start_pos + 1); |
||||
|
#else
|
||||
|
for (int i = peak_start_pos; i <= peak_end_pos; i++) { |
||||
|
peak_base_line_area += i * lineContext->baseline_slope + lineContext->baseline_intercept; |
||||
|
} |
||||
|
#endif
|
||||
|
|
||||
|
retpeak->peak_full_area = peak_full_area; |
||||
|
retpeak->peak_base_line_area = peak_base_line_area; |
||||
|
retpeak->area = peak_full_area - peak_base_line_area; |
||||
|
if (retpeak->area <= 0) retpeak->area = 0; |
||||
|
retpeak->find_peak = true; |
||||
|
|
||||
|
return k_ecode_ok; |
||||
|
} |
||||
|
|
||||
|
int OptAlgo::find_peak_endpoint(shared_ptr<LineContext> lineContext, |
||||
|
int peakpos, //
|
||||
|
int search_direction, //
|
||||
|
int search_windows) { |
||||
|
/**
|
||||
|
* @brief |
||||
|
* 通过波峰的位置查找波峰的起始位置 |
||||
|
* |
||||
|
* 逻辑: |
||||
|
* 1. 从波峰的位置开始,向前搜索,找到一个点,其值小于平均值。 |
||||
|
* 2. 然后继续向前搜索,找到一个点,斜率接近基线斜率。 |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
int off = -1; |
||||
|
ZLOGI(TAG, "find peakend top_pos:%d direction:%d windows:%d", peakpos, search_direction, search_windows); |
||||
|
|
||||
|
//
|
||||
|
algo_assert(search_windows > 0, "search_windows <= 0"); |
||||
|
algo_assert(search_direction == 1 || search_direction == -1, "search_direction != 1 && search_direction != -1"); |
||||
|
//
|
||||
|
int index_dval = search_direction >= 0 ? 1 : -1; |
||||
|
int search_start = peakpos; |
||||
|
int search_end = peakpos + search_direction * search_windows; |
||||
|
|
||||
|
algo_assert(search_end >= 0, "search_end < 0"); |
||||
|
algo_assert(lineContext->avg.size() > search_end, "lineContext->avg.size() <= search_start"); |
||||
|
|
||||
|
for (int i = search_start; i != search_end; i += index_dval) { |
||||
|
float now = lineContext->avg[i]; |
||||
|
if (now >= lineContext->agvline) continue; |
||||
|
|
||||
|
if (search_direction == 1) { |
||||
|
if (feq(lineContext->diff[i], lineContext->baseline_slope, 0.3) || lineContext->diff[i] >= lineContext->baseline_slope) { |
||||
|
off = i; |
||||
|
break; |
||||
|
} |
||||
|
} else { |
||||
|
if (feq(lineContext->diff[i], lineContext->baseline_slope, 0.3) || lineContext->diff[i] <= lineContext->baseline_slope) { |
||||
|
off = i; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return off; |
||||
|
} |
||||
|
|
||||
|
int OptAlgo::sub_find_peak(shared_ptr<LineContext> lineContext, int start_off, int windos_size, int judge_win_size) { //
|
||||
|
ZLOGI(TAG, "sub_find_peak %d %d %d", start_off, windos_size, judge_win_size); |
||||
|
float maxv = 0; |
||||
|
int peakoff = -1; |
||||
|
bool findmax = false; |
||||
|
for (size_t index = 0; index < windos_size; index++) { |
||||
|
int off = index + start_off; |
||||
|
// 从窗口的一半大小开始判断
|
||||
|
if (findmax && lineContext->avg[off] <= lineContext->agvline) break; |
||||
|
if (off < judge_win_size / 2) continue; |
||||
|
// 查找的点要大于基线
|
||||
|
if (lineContext->avg[off] <= lineContext->agvline) continue; |
||||
|
// 判断的
|
||||
|
if ((off + judge_win_size / 2) > (lineContext->avg.size() - 1)) break; |
||||
|
// 找到最大的峰值,这里判断用于去除一个波峰中的某个临时的小波峰
|
||||
|
if (maxv > lineContext->avg[off]) continue; |
||||
|
|
||||
|
/**
|
||||
|
* @brief 检查当前位置的点,是否是附近最大的点 |
||||
|
*/ |
||||
|
if (is_maxval_in_windows(&(lineContext->avg[off]), judge_win_size)) { |
||||
|
findmax = true; |
||||
|
maxv = lineContext->avg[off]; |
||||
|
peakoff = off; |
||||
|
} |
||||
|
} |
||||
|
return peakoff; |
||||
|
} |
||||
|
|
||||
|
bool OptAlgo::is_maxval_in_windows(float* val, int windows_size) { |
||||
|
algo_assert(windows_size > 0, "windows_size <= 0"); |
||||
|
algo_assert(windows_size % 2 == 1, "windows_size is not odd"); |
||||
|
|
||||
|
bool ret = true; |
||||
|
float* valstartpos = val - windows_size / 2; |
||||
|
for (size_t i = 0; i < windows_size; i++) { |
||||
|
if (&valstartpos[i] == val) continue; |
||||
|
|
||||
|
if (valstartpos[i] > *val) { |
||||
|
ret = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return ret; |
||||
|
} |
||||
|
|
||||
|
float OptAlgo::get_avg_in_windows(vector<float>& src, int off, int windows) { |
||||
|
float sum = 0; |
||||
|
algo_assert(windows % 2 == 1, "windows is not odd"); |
||||
|
for (int i = off - windows / 2; i <= off + windows / 2; i++) { |
||||
|
sum += src[i]; |
||||
|
} |
||||
|
return sum / windows; |
||||
|
} |
||||
|
|
||||
|
void OptAlgo::sort_vector(vector<float>& src) { |
||||
|
// 实现冒泡排序
|
||||
|
for (int i = 0; i < src.size(); i++) { |
||||
|
for (int j = 0; j < src.size() - i - 1; j++) { |
||||
|
if (src[j] > src[j + 1]) { |
||||
|
float temp = src[j]; |
||||
|
src[j] = src[j + 1]; |
||||
|
src[j + 1] = temp; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
vector<float> OptAlgo::getwindowspoint(vector<float>& src, int off, int windows) { |
||||
|
vector<float> ret(windows, 0); |
||||
|
int retindex = 0; |
||||
|
for (int i = off - windows / 2; i <= off + windows / 2; i++) { |
||||
|
ret[retindex] = src[i]; |
||||
|
retindex++; |
||||
|
} |
||||
|
return ret; |
||||
|
} |
@ -0,0 +1,209 @@ |
|||||
|
#pragma once
|
||||
|
#include <fstream>
|
||||
|
#include <functional>
|
||||
|
#include <iostream>
|
||||
|
#include <list>
|
||||
|
#include <map>
|
||||
|
#include <memory>
|
||||
|
#include <set>
|
||||
|
#include <sstream>
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
namespace opt_algo { |
||||
|
using namespace std; |
||||
|
|
||||
|
|
||||
|
typedef enum { |
||||
|
k250, |
||||
|
k1000, |
||||
|
} ProcessPointNumType_t; |
||||
|
|
||||
|
typedef enum { |
||||
|
k_ecode_ok = 0, |
||||
|
k_ecode_can_not_find_peak = 1, |
||||
|
k_ecode_can_not_find_peak_start = 2, |
||||
|
k_ecode_can_not_find_peak_end = 3, |
||||
|
} Error_t; |
||||
|
|
||||
|
class LineContext { |
||||
|
public: |
||||
|
vector<float> raw; //
|
||||
|
vector<float> avg; //
|
||||
|
vector<float> diff; //
|
||||
|
float agvline; //
|
||||
|
float baseline_slope; //
|
||||
|
float baseline_intercept; //
|
||||
|
|
||||
|
vector<float> raw250; //
|
||||
|
vector<float> avg250; //
|
||||
|
vector<float> diff250; //
|
||||
|
}; |
||||
|
|
||||
|
class PeakInfo { |
||||
|
public: |
||||
|
bool find_peak; |
||||
|
float peak_full_area; |
||||
|
float peak_base_line_area; |
||||
|
float area; |
||||
|
int peak_pos; |
||||
|
int peak_start_pos; |
||||
|
int peak_end_pos; |
||||
|
}; |
||||
|
|
||||
|
class AlgoResult { |
||||
|
public: |
||||
|
/**
|
||||
|
* @brief |
||||
|
* 原始数据处理逻辑: |
||||
|
* 1) 1200点中值滤波 |
||||
|
* 2) 1200点线性填充到6000点 |
||||
|
* 3) 6000点窗口平滑滤波 |
||||
|
* 4) 6000点均值压缩到1000点 |
||||
|
* |
||||
|
* 5) 1000点 13点滑动均值滤波 |
||||
|
* 6) 1000点 20点最小二乘法求斜率 |
||||
|
* |
||||
|
* 7) 找峰 |
||||
|
* 8)找峰起始位 |
||||
|
* 9) 找峰结束位 |
||||
|
* |
||||
|
*/ |
||||
|
AlgoResult() { |
||||
|
error_code = k_ecode_ok; |
||||
|
lineContext = make_shared<LineContext>(); |
||||
|
for (int i = 0; i < 5; i++) { |
||||
|
peakInfo[i] = make_shared<PeakInfo>(); |
||||
|
} |
||||
|
} |
||||
|
vector<float> ogigin_val; // 1200
|
||||
|
vector<float> supper_val; // 原始数据,线性填充,1200*5=6000
|
||||
|
vector<float> supper_median_val; // supper_val 窗口平滑滤波,6000
|
||||
|
vector<float> supper_smooth_sub_val; // supper_smooth_val 均值压缩,6000/6=1000
|
||||
|
|
||||
|
shared_ptr<LineContext> lineContext; // supper_smooth_sub_val 13点滑动均值滤波,1000
|
||||
|
|
||||
|
Error_t error_code; // 错误码
|
||||
|
|
||||
|
// result
|
||||
|
shared_ptr<PeakInfo> peakInfo[5]; |
||||
|
int peakNum; |
||||
|
}; |
||||
|
|
||||
|
class OptAlgo { |
||||
|
public: |
||||
|
/**
|
||||
|
* @brief |
||||
|
* |
||||
|
* @param context |
||||
|
* @param pconfig |
||||
|
* @param ogigin_val expect 1200 |
||||
|
*/ |
||||
|
static shared_ptr<AlgoResult> calculate(vector<float> ogigin_val, int peaknum); |
||||
|
static int calculate_peak_num(vector<float>& ogigin_val); |
||||
|
|
||||
|
static int getAlgoVersion(); |
||||
|
|
||||
|
private: |
||||
|
static Error_t findpeak(shared_ptr<LineContext> lineContext, int32_t search_start, int32_t peakwindth, shared_ptr<PeakInfo> retpeak); |
||||
|
static int sub_find_peak(shared_ptr<LineContext> lineContext, int start_off, int windos_size, int judge_win_size); |
||||
|
static int find_peak_endpoint(shared_ptr<LineContext> lineContext, int peakpos, int search_direction, int search_windows); |
||||
|
|
||||
|
private: |
||||
|
/*******************************************************************************
|
||||
|
* 基础方法 * |
||||
|
*******************************************************************************/ |
||||
|
|
||||
|
/**
|
||||
|
* @brief 过采样原始数据 |
||||
|
* |
||||
|
* @param inputRaw |
||||
|
* @param nInputLength |
||||
|
* @param nUpSampleRate |
||||
|
* @return vector<float> |
||||
|
*/ |
||||
|
static vector<float> super_sampling(vector<float>& inputRaw, int32_t nInputLength, int32_t nUpSampleRate); |
||||
|
/**
|
||||
|
* @brief 均值压缩数据 |
||||
|
* |
||||
|
* @param inputRaw |
||||
|
* @param nSubSampleRate |
||||
|
* @return vector<float> |
||||
|
*/ |
||||
|
static vector<float> sub_sampling(vector<float>& inputRaw, int nSubSampleRate); |
||||
|
/**
|
||||
|
* @brief 移动窗口平滑数据 |
||||
|
* |
||||
|
* @param inputRaw |
||||
|
* @param windows_size |
||||
|
* @return vector<float> |
||||
|
*/ |
||||
|
static vector<float> smooth_windows(vector<float>& inputRaw, int windows_size); |
||||
|
|
||||
|
/**
|
||||
|
* @brief 移动窗口平滑数据 |
||||
|
* |
||||
|
* @param inputRaw |
||||
|
* @param windows_size |
||||
|
* @return vector<float> |
||||
|
*/ |
||||
|
static vector<float> median_filtering(vector<float>& inputRaw, int windows_size); |
||||
|
/**
|
||||
|
* @brief 计算均值线 |
||||
|
* |
||||
|
* @param inputRaw |
||||
|
* @return float |
||||
|
*/ |
||||
|
static float find_avg_line(vector<float>& inputRaw); |
||||
|
/**
|
||||
|
* @brief 简单曲线求导 |
||||
|
* |
||||
|
* @param inputRaw 原始数据 |
||||
|
* @return vector<float> 和原始数据等长导数曲线 |
||||
|
*/ |
||||
|
static vector<float> differentiate(vector<float>& inputRaw); |
||||
|
/**
|
||||
|
* @brief 最小二乘法求导 |
||||
|
* |
||||
|
* @param inputRaw 原始数据 |
||||
|
* @param windows_size 窗口大小 |
||||
|
* @return vector<float> 和原始数据等长导数曲线 |
||||
|
*/ |
||||
|
static vector<float> least_square_method_differentiate(vector<float>& inputRaw, int windows_size); |
||||
|
|
||||
|
/**
|
||||
|
* @brief 当前数值是否是窗口内最大值(往前windsize/2,往后windowsize/2) |
||||
|
* |
||||
|
* @param val 当前数值指针 |
||||
|
* @param windows_size 窗口大小,必须是奇数 |
||||
|
* @return true |
||||
|
* @return false |
||||
|
*/ |
||||
|
static bool is_maxval_in_windows(float* val, int windows_size); |
||||
|
/**
|
||||
|
* @brief 比较两个浮点数是否相等 |
||||
|
* |
||||
|
* @param a |
||||
|
* @param b |
||||
|
* @param epsilon |
||||
|
* @return true |
||||
|
* @return false |
||||
|
*/ |
||||
|
static bool feq(float a, float b, float epsilon = 0.00001); |
||||
|
/**
|
||||
|
* @brief 最小二乘法 求一次函数斜率 |
||||
|
* |
||||
|
* @param val |
||||
|
* @param size |
||||
|
* @return float |
||||
|
*/ |
||||
|
static void linear_least_squares(vector<float>& x, vector<float>& y, float& slope, float& intercept); |
||||
|
static void linear_least_squares(float* y, int size, float& slope, float& intercept); |
||||
|
static void linear_least_squares_muti_windos(float* y, int size, vector<int> startx, int windowssize, float& slope, float& intercept); |
||||
|
|
||||
|
static float get_avg_in_windows(vector<float>& src, int off, int windows); |
||||
|
|
||||
|
static void sort_vector(vector<float>& src); |
||||
|
static vector<float> getwindowspoint(vector<float>& src, int off, int windows); |
||||
|
}; |
||||
|
|
||||
|
} // namespace opt_algo
|
@ -0,0 +1,11 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project> |
||||
|
<ProjectOutputs> |
||||
|
<ProjectOutput> |
||||
|
<FullPath>D:\Sige5193\boditech-a800\lib-algo\x64\Debug\boditech-opt-algo-java-lib.dll</FullPath> |
||||
|
</ProjectOutput> |
||||
|
</ProjectOutputs> |
||||
|
<ContentFiles /> |
||||
|
<SatelliteDlls /> |
||||
|
<NonRecipeFileRefs /> |
||||
|
</Project> |
@ -0,0 +1,5 @@ |
|||||
|
com_iflytop_a800_utils_ScanResultAnalysisAlgo.cpp |
||||
|
D:\Sige5193\boditech-a800\lib-algo\opt_algo.hpp(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 |
||||
|
(编译源文件“com_iflytop_a800_utils_ScanResultAnalysisAlgo.cpp”) |
||||
|
|
||||
|
boditech-opt-algo-java-lib.vcxproj -> D:\Sige5193\boditech-a800\lib-algo\x64\Debug\boditech-opt-algo-java-lib.dll |
@ -0,0 +1 @@ |
|||||
|
D:\Sige5193\boditech-a800\lib-algo\x64\Debug\boditech-opt-algo-java-lib.dll |
@ -0,0 +1,3 @@ |
|||||
|
D:\Sige5193\boditech-a800\lib-algo\com_iflytop_a800_utils_ScanResultAnalysisAlgo.cpp;D:\Sige5193\boditech-a800\lib-algo\x64\Debug\com_iflytop_a800_utils_ScanResultAnalysisAlgo.obj |
||||
|
D:\Sige5193\boditech-a800\lib-algo\logger.cpp;D:\Sige5193\boditech-a800\lib-algo\x64\Debug\logger.obj |
||||
|
D:\Sige5193\boditech-a800\lib-algo\opt_algo.cpp;D:\Sige5193\boditech-a800\lib-algo\x64\Debug\opt_algo.obj |
@ -0,0 +1,2 @@ |
|||||
|
PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.38.33130:TargetPlatformVersion=10.0.22621.0: |
||||
|
Debug|x64|D:\Sige5193\boditech-a800\lib-algo\| |
Write
Preview
Loading…
Cancel
Save
Reference in new issue