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