一维数组重采样

Ttile:  一维数组重采样

Author: Kagula

Date: 2016-12-26

介绍:有两种方法各有优缺点,方法一处理速度慢,16k长度第二代Core i3上需要400ms+,方法二为了提高性能,牺牲了边界精度。

方法一:MN缓存法

假充源是M个元素的数组,目标是N个元素的数组,中间建个含M*N个元素的数组,通过中间数组来建立映射关系,具体代码如下 :

	auto funcResampling = [](unsigned short *pDst, unsigned destLen,
			unsigned short *pSrc, unsigned srcLen){
			for (unsigned indexD = 0; indexD < destLen; indexD++)
			{
				unsigned nCount = 0;
				for (unsigned j = 0; j < srcLen; j++)
				{
					unsigned indexM = indexD*srcLen + j;
					unsigned indexS = indexM / destLen;
					nCount += pSrc[indexS];
				}//end for

				pDst[indexD] = nCount / (float)srcLen;
			}//end for		
		};


 

方法二:步进法

缺陷是,余数精确不是很好控制,需改进。

#include 
#include 
using namespace std;

/*
Title:重采样测试
Author:kagula
Date:2016-12-23
Environment: VS2013 Update5
*/

void testDownResampling()
{
	auto funcDownResampling = [](std::vector &vecDest,
		std::vector &vecSrc){
		unsigned step = vecSrc.size() / vecDest.size();
		unsigned step_reminder = vecSrc.size() % vecDest.size();

		unsigned nCount = 0;
		unsigned indexD = 0;

		//整数部份
		for (indexD = 0; indexD < vecDest.size() - 1; indexD++)
		{
			nCount = 0;
			for (unsigned indexOffset = 0; indexOffset < step; indexOffset++)
			{
				nCount += vecSrc[indexD * step + indexOffset];
			}//end for

			vecDest[indexD] = nCount / step;//ignore reminder.
		}//end for

		//余数部份
		nCount = 0;
		indexD = vecDest.size() - 1;
		for (unsigned indexOffset = 0; indexOffset < step + step_reminder; indexOffset++)
		{
			nCount += vecSrc[indexD * step + indexOffset];
		}//for
		vecDest[indexD] = nCount / (step + step_reminder);
	};//function

	vector vecSrc(4);
	for (int i = 0; i < 4; i++)
	{
		vecSrc[i] = i;
	}

	vector vecDest(2);

	funcDownResampling(vecDest, vecSrc);

	for (unsigned i = 0; i < vecDest.size(); i++)
	{
		cout << vecDest[i] << endl;
	}
}


void testUpResampling()
{
	auto funcUpResampling = [](std::vector &vecDest,
		std::vector &vecSrc){
		unsigned step = vecDest.size() / vecSrc.size() ;
		unsigned step_reminder = vecDest.size() % vecSrc.size();

		//整数部份
		unsigned indexD = 0;
		for (; indexD < vecDest.size(); indexD++)
		{
			unsigned indexS = indexD / step;
			if (indexS>step)
				break;

			vecDest[indexD] = vecSrc[indexS];
		}

		//余数部份
		unsigned offset = 0;
		for (; indexD < vecDest.size(); indexD++,offset++)
		{
			unsigned indexS = indexD / step;
			indexS = indexS * step + offset;
			vecDest[indexD] = vecSrc[vecSrc.size() - 1];
		}

	};//function

	vector vecSrc(4);
	for (int i = 0; i < 4; i++)
	{
		vecSrc[i] = i;
	}

	vector vecDest(4);

	funcUpResampling(vecDest, vecSrc);

	for (unsigned i = 0; i < vecDest.size(); i++)
	{
		cout << vecDest[i] << endl;
	}
}

int main(int argc, char** argv)
{
	cout << "测试下采样" << endl;
	testDownResampling();

	cout << "测试上采样" << endl;//大于原信号
	//能用,但是处理余数感觉还是不够精确,
	//将来考虑Src和Dest都归一化后,Dest从源找最接近值的办法去实现。
	testUpResampling();

	cout << "input any character to continue..." << endl;
	system("pause");

	return 0;
}


 

你可能感兴趣的:(C++,性能或算法)