曲線擬合/平滑算法實現及優化[基於C語言]

用CVI編寫個小東西時,發現曲線的擬合已經到了1秒多才能完成一次曲線的擬合。

代碼如下:

static void curveFitt (double *pdst,const double *psrc,int len)
{
	const double wind_w=0.4;
	double mypower = pow(10,wind_w/2);
	memcpy(pdst,psrc,len*sizeof(double));
	
	//DEBUG("MYPOWER[%f]",mypower);
	for(int i=(int)mypower+1; i<= len-1 ; i++)
	{
		
		int index_start = (int)( ((double)i/mypower)+(double)1.0);
		int index_end = (int)((double)i*mypower)+1;
		index_end = (index_end>=(len-1))?(len-1):index_end;
		*(pdst+i)= mysum(psrc,index_start,index_end)/(index_end-index_start+1);

		//DEBUG("i[%d],START[%d],end[%d]\n\r",i,index_start,index_end);
	}
	
	return ;
}


//主函數調用處:
{
……
//曲線擬合
long time_s = GetTickCount();				
curveFitt(myFFTHdr.p_fftResult_im,myFFTHdr.p_fftResult_re,ifftPoint>>1);
long time_e = GetTickCount();
DEBUG("curve Fitt diffTime:%d\n\r",time_e-time_s);
……
}

實際效果如下(綠線是經過擬合的):

執行時間如下:

 

優化方向:

1.減少計算的點數,代碼如下:

typedef struct __curveData__ {
	int len;//點數
	double *pX;//x座標數組
	double *pY;//Y座標數組
}curveData;

//曲線平滑//
#define nPointOfCurveFitt 256 //平滑處理時建議的點數(最終並不一定取到)
#define wideOfFitt 0.4

static void curveFitt (curveData *pdst,curveData *psrc)
{
	double wind_w , wind_w2, mypower;
	int index_start,index_end;
	int i,j,i_tmp;
	wind_w = 0.4 ; //平滑窗的大小
	wind_w2 = log10(psrc->len)/nPointOfCurveFitt; //點數窗
	mypower = pow(10,wind_w/2);
	//mypower2 = pow(10,wind_w);
	j=0;
	//DEBUG("wind_w[%f],mypower[%f],\n\rdst_len[%d],src_len[%d]\n\r",wind_w,mypower,pdst->len,psrc->len);
	for(i=(int)mypower+1; i<= psrc->len-1 ;)
	{
		
		index_start = (int)( ((double)i/mypower)+(double)1.0);
		index_end = (int)((double)i*mypower)+1;
		index_end = (index_end>=(psrc->len-1))?(psrc->len-1):index_end;
		*(pdst->pX+j)= *(psrc->pX+(int)(index_end+index_start)/2);
		*(pdst->pY+j)= mysum(psrc->pY,index_start,index_end)/(index_end-index_start+1);
		
		i_tmp = (int)(pow(10,(log10(i)+wind_w2))+0.5);
		//DEBUG("i[%d],j[%d],i_tmp[%d],pdst->x[%f],pdst->y[%f]\n\r",i,j,i_tmp,*(pdst->pX+j),*(pdst->pY+j));
		//Sleep(1000);
		i=(i_tmp>i)?i_tmp:(i+1);
		j++;
		j=(j>=nPointOfCurveFitt)?nPointOfCurveFitt-1:j;
	}
	//DEBUG("%s\n\r",__func__);
	pdst->len = j;
	return ;
}

實際測試:

運行時間:

------

基本上256點都是在ms級,可以接受。【期待:錄音採集在100ms採集一次並運算一次】

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章