From 48f3d4d7f83c15a6d4d8f22b1eecec2a1978077b Mon Sep 17 00:00:00 2001 From: kradchen Date: Tue, 13 Jun 2023 14:24:05 +0800 Subject: [PATCH] preprocessAScanBlockForReflection Test passed (left with Accuracy problem) --- .../preprocessAScanBlockForReflection.cpp | 439 ++++++++++++++++++ .../preprocessAScanBlockForReflection.h | 26 ++ test/Reconstruction_Test.cpp | 49 +- 3 files changed, 506 insertions(+), 8 deletions(-) create mode 100644 src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.cpp create mode 100644 src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.h diff --git a/src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.cpp b/src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.cpp new file mode 100644 index 0000000..f7dfc7d --- /dev/null +++ b/src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.cpp @@ -0,0 +1,439 @@ +#include "preprocessAScanBlockForReflection.h" + +#include "Function.h" +#include "Function1D.h" +#include "Function2D.h" +#include "Function3D.h" +#include "Matrix.h" +#include "common/dataBlockCreation/removeDataFromArrays.h" +#include "config/config.h" +#include +#include +#include +#include +#include +#include +#include +#include +namespace Recon { + + Aurora::Matrix _createDiffVector(const Aurora::Matrix & aMatrix, double beginValue,double endValue){ + auto r = Aurora::zeros(1,aMatrix.getDataSize()+1); + r[0] = beginValue; + for (size_t i = 1; i < aMatrix.getDataSize(); i++) + { + r[i] = aMatrix[i] - aMatrix[i-1]; + } + r[aMatrix.getDataSize()] = endValue; + return r; + } + + /** + * @brief + * + * @param aMatrix + * @param op add 0, sub 1 + * @return Aurora::Matrix + */ + Aurora::Matrix _blockOp(const Aurora::Matrix & aMatrix,int op){ + if (aMatrix.isComplex()){ + std::cerr<<"MatrixColDiff not support complex!"<1?aMatrix.getDataSize()-1:1, + aMatrix.getDimSize(0)>1?1:aMatrix.getDimSize(1)-1); + if (op == 1)vdSubI(result.getDataSize(),aMatrix.getData() , 1, aMatrix.getData()+1,1,result.getData(),1); + if (op == 0)vdAddI(result.getDataSize(),aMatrix.getData()+1 , 1, aMatrix.getData(),1,result.getData(),1); + return result; + } + else{ + std::cerr<<"un expect operation!"< performSignalProcessing( + const Aurora::Matrix &blockedAScans, + const Aurora::Matrix &blockedSL, + const Aurora::Matrix &blockedRL, + const Aurora::Matrix &blockedSenderPosition, + const Aurora::Matrix &blockedReceiverPosition, + const Aurora::Matrix &blockedGain, const Aurora::Matrix &blockedChannels, + ExpInfo &info, const PreComputes &preComputes) { + std::vector result; + auto t = size(blockedAScans); + size_t nSamples = (int)t[0]; + size_t nAScans = (int)t[1]; + auto valid = Aurora::ones(blockedAScans.getDimSize(1),1); + { + auto blockedGain_t = blockedGain.deepCopy(); + Aurora::nantoval(blockedGain_t, 0); + valid = valid*blockedGain_t; + } + + auto _blockedAScans = blockedAScans/blockedGain; + if (reflectParams::removeDCOffset == 1) + { + _blockedAScans = _blockedAScans-Aurora::mean(_blockedAScans); + } + int winLength = 100; + if (reflectParams::removeDCOffset == 1) + { + auto meanAS = mean(_blockedAScans.block(0,winLength-1,_blockedAScans.getDimSize(0) -1 -winLength)); + _blockedAScans = _blockedAScans-meanAS.getScalar(); + } + _blockedAScans.setBlockValue(0,0,winLength-1,0); + _blockedAScans.setBlockValue(0,_blockedAScans.getDimSize(0)-winLength-1,_blockedAScans.getDimSize(0)-1,0); + auto maxVal = max(abs(_blockedAScans)); + auto stdVal = Aurora::std(_blockedAScans); + auto meanVal = Aurora::mean(abs(_blockedAScans)); + auto ascanMapValue = meanVal*stdVal; + auto temp = (stdVal == 0) * (maxVal != 0); + Aurora::compareSet(valid,temp,1,0,Aurora::EQ); + if (reflectParams::findDefects==1) + { + valid = valid*(maxVal/meanVal >= reflectParams::epsilon); + } + // debugOutput.maxVal = maxVal; + // debugOutput.stdVal = stdVal; + // debugOutput.meanVal = meanVal; + // debugOutput.snr = maxVal ./ meanVal; + // debugOutput.snrPass = (maxVal./meanVal) < flags.dataSelection.epsilon; + if (reflectParams::suppressSameHead == 1) + { + for (size_t i = 0; i < blockedSL.getDataSize(); i++) + { + if (blockedSL[i] == blockedRL[i]) + { + auto begin_ptr = _blockedAScans.getData()+i*_blockedAScans.getDimSize(0); + int count = reflectParams::suppressSameHeadLength* sizeof(double); + std::memset(begin_ptr,0,count); + } + } + + } + auto fx = fft(_blockedAScans); + Aurora::Matrix fh; + if (reflectParams::useCorrelation && reflectParams::matchedFilterCeAScan) + { + if (!preComputes.measuredCEUsed) + { + fh = preComputes.matchedFilter.block(1, 0, nAScans-1); + } + else{ + fh = preComputes.matchedFilter(Aurora::$,blockedChannels[0]-1).toMatrix(); + } + double* value1 = Aurora::malloc(fx.getDataSize()); + vdMulI(fx.getDataSize(), fx.getData(), 2, fh.getData(), 2, value1, 1); + double* value2 = Aurora::malloc(fx.getDataSize()); + vdMulI(fx.getDataSize(), fx.getData() + 1, 2, fh.getData() + 1, 2, value2, 1); + double* realData = Aurora::malloc(fx.getDataSize()); + vdAdd(fx.getDataSize(), value1, value2, realData); + Aurora::Matrix real = Aurora::Matrix::New(realData, fx.getDimSize(0), fx.getDimSize(1)); + + vdMulI(fx.getDataSize(), fx.getData() + 1, 2, fh.getData(), 2, value1, 1); + vdMulI(fx.getDataSize(), fx.getData(), 2, fh.getData() + 1, 2, value2, 1); + double* imagData = Aurora::malloc(fx.getDataSize()); + vdSub(fx.getDataSize(), value1, value2, imagData); + Aurora::Matrix image = Aurora::Matrix::New(imagData, fx.getDimSize(0), fx.getDimSize(1)); + + double* complexData = Aurora::malloc(real.getDataSize(), true); + cblas_dcopy(real.getDataSize(), real.getData(), 1 , complexData ,2); + cblas_dcopy(image.getDataSize(), image.getData(), 1 , complexData + 1 ,2); + Aurora::Matrix complex = Aurora::Matrix::New(complexData, real.getDimSize(0), real.getDimSize(1), 1, Aurora::Complex); + _blockedAScans = Aurora::real(ifft(complex)); + + _blockedAScans.setBlockValue(0, 0, winLength-1, 0); + _blockedAScans.setBlockValue(0, _blockedAScans.getDimSize(0)-winLength, _blockedAScans.getDimSize(0)-1, 0); + _blockedAScans = fft(_blockedAScans); + } + else{ + _blockedAScans = fx; + } + auto exponent = offsetSignalFourier(preComputes, nSamples); + // exponent.forceReshape(1, exponent.getDataSize(), 1); + _blockedAScans =_blockedAScans*exponent; + _blockedAScans = real(ifft(_blockedAScans)); + if (reflectParams::removeTransmissionSignal == 1) { + auto distanceEPosRPos = + sqrt( + ((blockedSenderPosition(0, Aurora::$).toMatrix() - blockedReceiverPosition(0, Aurora::$).toMatrix())^2) + + ((blockedSenderPosition(1, Aurora::$).toMatrix() - blockedReceiverPosition(1, Aurora::$).toMatrix())^2) + + ((blockedSenderPosition(2, Aurora::$).toMatrix() -blockedReceiverPosition(2, Aurora::$).toMatrix())^2)); + auto windowLength = reflectParams::windowLength; + auto start = round((distanceEPosRPos/reflectParams::expectedUSSpeedRange[1])*reflectParams::aScanReconstructionFrequency); + auto ende = round((distanceEPosRPos/reflectParams::expectedUSSpeedRange[0])*reflectParams::aScanReconstructionFrequency); + auto area = ceil(reflectParams::expectedPulseLength*info.Wavelength+1); + start = start- round(area*0.1); + ende = ende + round(area*0.9); + Aurora::compareSet(start, 1, 2, Aurora::NG); + Aurora::compareSet(start,nSamples,nSamples,Aurora::GT); + Aurora::compareSet(ende,nSamples,nSamples,Aurora::GT); + + for (size_t idx = 0; idx < nAScans; idx++) + { + auto partData = _blockedAScans(Aurora::$,idx).toMatrix().block(0, start[idx]-1, ende[idx]-1); + + auto l_partData = partData.getDataSize(); + auto energyMove = _createDiffVector(partData,partData[0],0); + energyMove = _blockOp(energyMove,0); + energyMove = (energyMove^2)*0.5; + auto energyPot = partData^2; + + auto energySum = energyMove + energyPot; + + auto mean_energySum = Aurora::zeros(l_partData + windowLength,1); + for (size_t i = 0; i < windowLength; i++) + { + double* begin = mean_energySum.getData() + i; + int length = l_partData; + vdAddI(length, energySum.getData(), 1, begin, 1, begin, 1); + } + mean_energySum = mean_energySum.block(0,windowLength/2-1,mean_energySum.getDataSize()-1-round((windowLength-0.001)/2)); + + auto g = _createDiffVector(mean_energySum,0,0); + g = _blockOp(g,0); + auto f = _createDiffVector(g,g[0],0); + f = _blockOp(f,0); + Aurora::compareSet(f, 0, 0, Aurora::LT); + Aurora::compareSet(f,g,0,0,Aurora::NG); + Aurora::compareSet(f,0,0,Aurora::NG); + auto mean_energySum_f = f; + long scheitelRow=0,scheitelCol=0; + max(g,Aurora::Column,scheitelRow,scheitelCol); + long indexRow=0, indexCol=0; + //不知道对不对??? + auto scheitel = scheitelRow+scheitelCol; + max(mean_energySum_f.block(0,0,scheitel),Aurora::Column,indexRow,indexCol); + size_t index = indexRow+indexCol; + double median_mean_energySum = Aurora::median(mean_energySum).getScalar(); + bool flag = false; + if (mean_energySum[index] > median_mean_energySum) + { + for (size_t i = index; i > 0 ; i--) + { + if(mean_energySum[i] hIndex; + for (size_t i = 0; i < hIndex_s.getDataSize(); i++) + { + if (hIndex_s[i]>0)hIndex.push_back(i); + } + if (hIndex.empty()){ + hIndex.push_back(mean_energySum.getDataSize()-scheitel-1); + } + int index2 = hIndex[0]+scheitel-1+10; + //???存在没有index???matlab中有这一分支 + auto sig_begin = index + start[idx] ; + //在这里+1 调整会matlab的index便于后续计算的正确性 + auto sig_end = index2 + start[idx] +1; + + winLength = sig_end+winLength+200-sig_begin+1; + auto win = generateGaussWindow(winLength); + double* begin = _blockedAScans.getData() + (size_t)sig_begin-1; + int length = winLength; + auto winReverse = Aurora::zeros(1,win.getDataSize()); + std::reverse_copy(win.getData(), win.getData()+win.getDataSize(), winReverse.getData()); + vdMulI(length, begin, 1, winReverse.getData(), 1, begin, 1); + winLength = sig_end; + win = generateGaussWindow(winLength); + begin = _blockedAScans.getData() ; + length = sig_end; + vdMulI(length, begin, 1, win.getData(), 1, begin, 1); + } + } + _blockedAScans = fft(_blockedAScans); + if(reflectParams::useOptPulse==1){ + auto n = nSamples; + auto nHalf = round((double)n/2); + _blockedAScans(0,Aurora::$) = std::complex{0,0}; + _blockedAScans.setBlockComplexValue(0,nHalf,_blockedAScans.getDimSize(0)-1, std::complex{0,0}); + _blockedAScans.setBlock(0,1,nHalf-1,_blockedAScans.block(0,1,nHalf-1)*2); + + + _blockedAScans = ifft(_blockedAScans, n); + + _blockedAScans = abs(_blockedAScans.block(0,0,nSamples-1)); + auto help = _blockedAScans.deepCopy(); + help(0,Aurora::$) = 0; + help.setBlock(0, 1, help.getDimSize(0)-1, _blockOp(_blockedAScans, 1)); + { + auto help_bbegin = help.block(0, 0, help.getDimSize(0)-2); + auto help_bend = help.block(0, 1, help.getDimSize(0)-1); + help_bend = (help_bend>0)*(help_bbegin<0); + auto tempBlock = Aurora::zeros(_blockedAScans.getDimSize(0),_blockedAScans.getDimSize(1),_blockedAScans.getDimSize(2)); + tempBlock.setBlock(0, 0, tempBlock.getDimSize(0)-2, help_bend); + _blockedAScans = _blockedAScans*tempBlock; + } + help = _blockedAScans.deepCopy(); + Aurora::compareSet(help,0,0,Aurora::LT); + + + if(reflectParams::limitNumPulsesTo>0) + { + + if(size(help,1)>reflectParams::limitNumPulsesTo) + { + auto help2 = Aurora::sort(help); + auto temp = repmat(help2(help2.getDimSize(0)-reflectParams::limitNumPulsesTo,Aurora::$).toMatrix(),help.getDimSize(0),1); + Aurora::compareSet(help,temp,0,Aurora::LT); + } + + } + + if(reflectParams::normalizePeaks) + { + Aurora::compareSet(help,0,1,Aurora::GT); + } + + + + help= real(ifft(fft(help)*(preComputes.sincPeak_ft.block(1,0,nAScans-1)))); + Aurora::compareSet(_blockedAScans,0,help,Aurora::NL); + + } + else{ + _blockedAScans = real(ifft(_blockedAScans)); + } + result.push_back(_blockedAScans); + + result.push_back(valid); + ascanMapValue[0] = (float)ascanMapValue[0]; + result.push_back(ascanMapValue); + return result; + } + + + preprocessAScanRResult preprocessAScanBlockForReflection( + Aurora::Matrix &AscanBlock, const Aurora::Matrix &blockedMP, + const Aurora::Matrix &blockedSL, const Aurora::Matrix &blockedSN, + const Aurora::Matrix &blockedRL, const Aurora::Matrix &blockedRN, + const Aurora::Matrix &blockedSenderPosition, + const Aurora::Matrix &blockedReceiverPosition, + const Aurora::Matrix &blockedGain, const Aurora::Matrix &blockedChannels, + ExpInfo &info, const PreComputes &preComputes) + { + preprocessAScanRResult result; + auto valid = Aurora::zeros(1, blockedMP.getDataSize()) ; + auto ascanMapValue = Aurora::zeros(1, blockedMP.getDataSize()) ; + // auto dOutMaxVal = Aurora::zeros(1, blockedMP.getDataSize()) ; + // auto dOutStdVal = Aurora::zeros(1, blockedMP.getDataSize()) ; + // auto dOutMeanVal = Aurora::zeros(1, blockedMP.getDataSize()) ; + // auto dOutSnr = Aurora::zeros(1, blockedMP.getDataSize()) ; + // auto dOutSnrPass = Aurora::zeros(1, blockedMP.getDataSize()) ; + + switch (reflectParams::version) { + case 1: + std::cerr<<"error USCT II only!!"< treshold99; + // debugOutput.maxVal = dOutMaxVal; + // debugOutput.stdVal = dOutStdVal; + // debugOutput.meanVal = dOutMeanVal; + // debugOutput.snr = dOutSnr; + // debugOutput.snrPass = dOutSnrPass; + } + result.AscanBlock = AscanBlock; + result.usedData = valid; + return result; + } +} // namespace Recon diff --git a/src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.h b/src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.h new file mode 100644 index 0000000..d3ae9ce --- /dev/null +++ b/src/reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.h @@ -0,0 +1,26 @@ +#ifndef __PREPROCESSASCANBLOCKFORREFLECTION_H__ +#define __PREPROCESSASCANBLOCKFORREFLECTION_H__ +#include "Matrix.h" +#include "common/getMeasurementMetaData.h" +#include +namespace Recon { + struct preprocessAScanRResult { + Aurora::Matrix AscanBlock; + Aurora::Matrix usedData; + }; + struct ExpInfo{ + size_t Wavelength; + size_t expectedAScanLength; + }; + + preprocessAScanRResult preprocessAScanBlockForReflection( + Aurora::Matrix &AscanBlock, const Aurora::Matrix &mpBlock, + const Aurora::Matrix &slBlock, const Aurora::Matrix &snBlock, + const Aurora::Matrix &rlBlock, const Aurora::Matrix &rnBlock, + const Aurora::Matrix &senderPositionBlock, + const Aurora::Matrix &receiverPositionBlock, + const Aurora::Matrix &gainBlock, const Aurora::Matrix &channelBlock, + ExpInfo& info, const PreComputes &preComputes); +} + +#endif // __PREPROCESSASCANBLOCKFORREFLECTION_H__ \ No newline at end of file diff --git a/test/Reconstruction_Test.cpp b/test/Reconstruction_Test.cpp index de2a39b..8e1ccd2 100644 --- a/test/Reconstruction_Test.cpp +++ b/test/Reconstruction_Test.cpp @@ -8,6 +8,7 @@ #include "Matrix.h" #include "Sparse.h" #include "config/config.h" +#include "reflectionReconstruction/preprocessData/preprocessAScanBlockForReflection.h" #include "transmissionReconstruction/reconstruction/buildMatrix/DGradient.h" #include "transmissionReconstruction/reconstruction/buildMatrix/FMM.h" #include "transmissionReconstruction/reconstruction/buildMatrix/buildMatrix.h" @@ -46,16 +47,48 @@ protected: }; TEST_F(Reconstruction_Test, determineOptimalPulse) { - Recon::reflectParams::imageResolution = 8.6381e-04; - Recon::reflectParams::optPulseFactor = 24; - auto result = Recon::determineOptimalPulse(1.0000e-07,3000); - EXPECT_EQ(3000, result.getDataSize()); - ASSERT_DOUBLE_AE(result[2], 0.0025); - ASSERT_DOUBLE_AE(result[4], 0.0078); + Recon::reflectParams::imageResolution = 8.925316499483377e-04; + Recon::reflectParams::optPulseFactor = 48; + auto result = Recon::determineOptimalPulse(1.0000e-07,4096); + EXPECT_EQ(4096, result.getDataSize()); + MatlabReader m2("/home/krad/TestData/sincPeakft.mat"); + auto f1 = m2.read("sincPeak_ft"); + for(size_t i=0; i