第三代软件开发-全新波形抓取算法
[toc]
关键字: Qt
、Qml
、抓波
、截获
、波形
项目介绍
欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。
在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。
在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。
无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!
重要说明☝
☀该专栏在第三代软开发更新完将涨价
全新波形抓取算法
嘿嘿嘿,如果有碰巧看过我之前的抓波算法的话,那么可以在看看这里,这个版本是针对送检使用的演示版本,针对是信号发生器产出的纯净波形。在实际使用中发现不管怎么调节参数都不理想。所以诞生了新的抓博算法。
链接在这里:https://dreamlife.blog.csdn.net/article/details/128716820
新的抓博算法简单除暴,直接判断峰峰值是否超过阈值,如果超过阈值了,那就行波形分析,入股没有继续抓博。核心算法如下:
/**
* @brief XXXX::wavesCatch 提取波峰函数
* @param iAisle
*/
bool XXXX::wavesCatch(int iAisle)
{
// @ld
m_wavesStartIndex = 0;
m_wavesEndIndex = 0;
m_yData.resize(m_windowDataSize - m_stimeNumber);
m_yData.at(0) = m_windowData[iAisle+1].at(0+m_stimeNumber);
m_yData.at(1) = m_windowData[iAisle+1].at(1+m_stimeNumber);
for(int i=2;i<m_windowDataSize-m_stimeNumber;i++)
{
m_yData.at(i) = (m_windowData[iAisle+1].at(i+m_stimeNumber)+m_windowData[iAisle+1].at(i-1+m_stimeNumber)+m_windowData[iAisle+1].at(i-2+m_stimeNumber))/3;
}
m_wavesMaxIndex = m_wavesMaxIndex - m_stimeNumber;
m_wavesMinIndex = m_wavesMinIndex - m_stimeNumber;
//
if(m_wavesMaxIndex<m_wavesMinIndex)
{
// m_wavesStartIndex
for(int iStart=m_wavesMaxIndex-2;iStart>=2;iStart--)
{
// 在平均值附近
if(qAbs(m_yData.at(iStart) - m_wavesAvg) <= 0.15*qAbs(m_wavesMax - m_wavesAvg))
{
// B.极小值
if((m_yData.at(iStart)<=m_yData.at(iStart+1) && m_yData.at(iStart) <= m_yData.at(iStart-1))
// 找到快速增加点
|| (m_yData.at(iStart+2) > m_yData.at(iStart+1) > m_yData.at(iStart)
&& (m_yData.at(iStart+2) -m_yData.at(iStart+1)) > 5*(m_yData.at(iStart+1) -m_yData.at(iStart))))
{
m_wavesStartIndex = iStart;
break;
}
}
}
for(int iEnd=m_wavesMinIndex+2;iEnd<int(m_yData.size())-2;iEnd++)
{
// 在平均值附近
if(qAbs(m_yData.at(iEnd) - m_wavesAvg) <= 0.15*qAbs(m_wavesAvg - m_wavesMin))
{
// B.极大值
if((m_yData.at(iEnd)>=m_yData.at(iEnd+1) && m_yData.at(iEnd) >= m_yData.at(iEnd-1))
// 找到平缓点
|| (m_yData.at(iEnd-2) < m_yData.at(iEnd-1) < m_yData.at(iEnd)
&& (m_yData.at(iEnd-1) -m_yData.at(iEnd-2)) > 5*(m_yData.at(iEnd) -m_yData.at(iEnd-1))))
{
m_wavesEndIndex = iEnd;
break;
}
}
}
}
else
{
for(int iStart=m_wavesMinIndex-2;iStart>=2;iStart--)
{
// 在平均值附近
if(qAbs(m_yData.at(iStart) - m_wavesAvg) <= 0.15*qAbs(m_wavesAvg - m_wavesMin))
{
// B.极大值
if((m_yData.at(iStart)>=m_yData.at(iStart+1) && m_yData.at(iStart) >= m_yData.at(iStart-1))
// 找到快速增加点
|| (m_yData.at(iStart+2) < m_yData.at(iStart+1) < m_yData.at(iStart)
&& (m_yData.at(iStart+1) -m_yData.at(iStart+2)) > 5*(m_yData.at(iStart) -m_yData.at(iStart-1))))
{
m_wavesStartIndex = iStart;
break;
}
}
}
for(int iEnd=m_wavesMaxIndex+2;iEnd<int(m_yData.size())-1;iEnd++)
{
// 在平均值附近
if(qAbs(m_yData.at(iEnd) - m_wavesAvg) <= 0.15*qAbs(m_wavesMax - m_wavesAvg))
{
// B.极小值
if((m_yData.at(iEnd)<=m_yData.at(iEnd+1) && m_yData.at(iEnd) <= m_yData.at(iEnd-1))
// 找到平缓点
|| (m_yData.at(iEnd-2) > m_yData.at(iEnd-1) > m_yData.at(iEnd)
&& (m_yData.at(iEnd-2) -m_yData.at(iEnd-1)) > 5*(m_yData.at(iEnd-1) -m_yData.at(iEnd))))
{
m_wavesEndIndex = iEnd;
break;
}
}
}
}
if(m_wavesStartIndex == 0 || m_wavesEndIndex == 0)
return false;
emit signal_wavesCatched(iAisle,m_wavesStartIndex+m_stimeNumber,m_wavesMaxIndex+m_stimeNumber,m_wavesMinIndex+m_stimeNumber,m_wavesEndIndex+m_stimeNumber);
return true;
}
大致流程图如下:
代码小解
首先,我们对一些参数做了重置,这样保证我们开始的是一样的
m_wavesStartIndex = 0; m_wavesEndIndex = 0; m_yData.resize(m_windowDataSize - m_stimeNumber);
紧接着,我们对我们的数据进行一个简单的平滑处理
m_yData.at(0) = m_windowData[iAisle+1].at(0+m_stimeNumber); m_yData.at(1) = m_windowData[iAisle+1].at(1+m_stimeNumber); for(int i=2;i<m_windowDataSize-m_stimeNumber;i++) { m_yData.at(i) = (m_windowData[iAisle+1].at(i+m_stimeNumber)+m_windowData[iAisle+1].at(i-1+m_stimeNumber)+m_windowData[iAisle+1].at(i-2+m_stimeNumber))/3; }
接下来,我们需要把我们之前算好的极大值和极小值做一个坐标转换
m_wavesMaxIndex = m_wavesMaxIndex - m_stimeNumber; m_wavesMinIndex = m_wavesMinIndex - m_stimeNumber;
接下来,我们通过判断极大值和极小值对应的坐标就可以判断出波峰在前还是波谷在前了,
if(m_wavesMaxIndex<m_wavesMinIndex)
分别再找起点和重点
for(int iStart=m_wavesMaxIndex-2;iStart>=2;iStart--) { // 在平均值附近 if(qAbs(m_yData.at(iStart) - m_wavesAvg) <= 0.15*qAbs(m_wavesMax - m_wavesAvg)) { // B.极小值 if((m_yData.at(iStart)<=m_yData.at(iStart+1) && m_yData.at(iStart) <= m_yData.at(iStart-1)) // 找到快速增加点 || (m_yData.at(iStart+2) > m_yData.at(iStart+1) > m_yData.at(iStart) && (m_yData.at(iStart+2) -m_yData.at(iStart+1)) > 5*(m_yData.at(iStart+1) -m_yData.at(iStart)))) { m_wavesStartIndex = iStart; break; } } } for(int iEnd=m_wavesMinIndex+2;iEnd<int(m_yData.size())-2;iEnd++) { // 在平均值附近 if(qAbs(m_yData.at(iEnd) - m_wavesAvg) <= 0.15*qAbs(m_wavesAvg - m_wavesMin)) { // B.极大值 if((m_yData.at(iEnd)>=m_yData.at(iEnd+1) && m_yData.at(iEnd) >= m_yData.at(iEnd-1)) // 找到平缓点 || (m_yData.at(iEnd-2) < m_yData.at(iEnd-1) < m_yData.at(iEnd) && (m_yData.at(iEnd-1) -m_yData.at(iEnd-2)) > 5*(m_yData.at(iEnd) -m_yData.at(iEnd-1)))) { m_wavesEndIndex = iEnd; break; } } }
判定一下波形特征,符合波形特征,就发出信号,同时返回true;不符合波形特征就返回False
if(m_wavesStartIndex == 0 || m_wavesEndIndex == 0) return false; emit signal_wavesCatched(iAisle,m_wavesStartIndex+m_stimeNumber,m_wavesMaxIndex+m_stimeNumber,m_wavesMinIndex+m_stimeNumber,m_wavesEndIndex+m_stimeNumber); return true;