c++实现PCA(BIL, BSQ, BIP三种格式数据)

pca主成份分析:将协方差变形: cov(x,y) = 1/(n-1)*( 求和xi*yi - n*x*y)

BSQ格式:

 
//将协方差变形: cov(x,y) = 1/(n-1)*( 求和xi*yi - n*x*y)

template <typename T>   
void BSQCovAndMeanOMP(HANDLE hReadFile,ulong HW,ulong Width,ulong Height,int Bands,double* mean,double* cov,CProgressCtrl* bar)
{
	ulong readBytes = 0;
	ulong BT = Bands * sizeof(T);
	long proSize = SIZE16M;
	if(GetMemoryInfoG() >= 2) proSize = SIZE32M;
	int kernel = GetKCount();
	MALLOC2(double,meanK,kernel,Bands);
	MALLOC2(double,covK,kernel,(1 + Bands) * Bands /2); //分配上三角
	long k = proSize / BT; //BT比小于16M
	ulong offsetT = (HW - k) * sizeof(T);
	ulong KT = k * sizeof(T);
	T* pTImg = (T*)malloc(Bands * KT);
	ulong BenOffset = 0;
	ulong HW2 = HW / k;
	for (ulong y = 0; y < HW2; y++)
	{
		bar->SetPos(int(3 + y*1.0/HW2 *80));//设定进度条位置99%
		SetFilePointer(hReadFile ,BenOffset,NULL,FILE_BEGIN);
		T* pTBuf = pTImg;
		//读
		for (int i = 0; i < Bands; i++)
		{
			ReadFile(hReadFile,(LPVOID)pTBuf,KT,&readBytes,NULL);
			pTBuf += k;
			SetFilePointer(hReadFile ,offsetT,NULL,FILE_CURRENT);
		}
		#pragma omp parallel for num_threads(kernel)
		for (long ik = 0; ik < k; ik++)
		{
			int kId = omp_get_thread_num();
			double* pCovK = covK[kId];
			double* pMeanK = meanK[kId];
			T* pIBuf = pTImg + ik;
			T* pJBuf = NULL;
			for (int i = 0; i < Bands; i++)
			{
				pJBuf = pIBuf;
				for (int j = i; j < Bands; j++)
				{
					*pCovK++ += *pIBuf * *pJBuf;
					pJBuf += k;
				}
				pMeanK[i] += *pIBuf;
				pIBuf += k;
			}
		}
		BenOffset += KT;
	}
	k = HW - k * HW2;
	if (k != 0)
	{
		SetFilePointer(hReadFile ,BenOffset,NULL,FILE_BEGIN);
		KT = k * sizeof(T);
		offsetT = (HW - k) * sizeof(T);
		T* pTBuf = pTImg;
		//读
		for (int i = 0; i < Bands; i++)
		{
			ReadFile(hReadFile,(LPVOID)pTBuf,KT,&readBytes,NULL);
			pTBuf += k;
			SetFilePointer(hReadFile ,offsetT,NULL,FILE_CURRENT);
		}
		if (k < kernel) kernel = k;
		#pragma omp parallel for num_threads(kernel)
		for (long ik = 0; ik < k; ik++)
		{
			int kId = omp_get_thread_num();
			double* pCovK = covK[kId];
			double* pMeanK = meanK[kId];
			T* pIBuf = pTImg + ik;
			T* pJBuf = NULL;
			for (int i = 0; i < Bands; i++)
			{
				pJBuf = pIBuf;
				for (int j = i; j < Bands; j++)
				{
					*pCovK++ += *pIBuf * *pJBuf;
					pJBuf += k;
				}
				pMeanK[i] += *pIBuf;
				pIBuf += k;
			}
		}
	}
	free(pTImg);
	//求均值
	#pragma omp parallel for
	for (int i = 0; i < Bands; i++) 
	{
		double sum = 0;
		for (int kid = 0; kid < kernel; kid++) sum += meanK[kid][i];
		mean [i] = sum / HW;
	}
	FREE2(meanK,kernel);
	//求协方差
	HW2 = HW - 1;
	double** pCovK = (double**)malloc(kernel * sizeof(double));
	for (int kid = 0; kid < kernel; kid++) pCovK[kid] = covK[kid];  //存放的是地址
	double* pCovData = cov;
	double* p2CovData = NULL;
	for (int i = 0; i < Bands; i++)
	{
		double sum;
		double temp = HW * mean[i];
		for (int j = i; j < Bands; j++)
		{
			sum = 0;
			for (int kid = 0; kid < kernel; kid++) sum += *pCovK[kid]++;  //求和
			*pCovData++ = (sum - temp * mean[j]) / HW2;
		}
		if (i >= Bands - 1) break;
		p2CovData = cov + i + 1;
		for (int j = 0; j <= i; j++)
		{
			*pCovData++ = *p2CovData;
			p2CovData  += Bands;
		}
	}
	free(pCovK);
	FREE2(covK,kernel);
}
template <typename T>   //保存pca数据(非ENVI格式)
void BSQSavePcaDataOMP(HANDLE hReadFile,HANDLE hWriteFile,int* BLUT,ulong HW,ulong Width,ulong Height,int Bands,int reductBand,double* eiv)
{
	ulong readBytes = 0;
	ulong writeBytes = 0;
	ulong BT = Bands * sizeof(T);
	long proSize = SIZE16M;
	if(GetMemoryInfoG() >= 2) proSize = SIZE32M;
	int kernel = GetKCount();
	MALLOC2(T,KernelR,kernel,Bands);
	MALLOC2(float,KernelPcaR,kernel,reductBand);
	long k = proSize / BT; //BT比小于16M
	ulong offsetT = (HW - k) * sizeof(T);
	ulong offsetF = (HW - k) * sizeof(float);
	ulong KT = k * sizeof(T);
	ulong KF = k * sizeof(float);
	ulong BenTOffset = 0;
	ulong BenFOffset = 0;
	T* pTImg = (T*)malloc(k * BT);
	float* pFImg = (float*)malloc(KF * reductBand);
	ulong HW2 = HW / k;
	for (ulong y = 0; y < HW2; y++)
	{
		SetFilePointer(hReadFile ,BenTOffset,NULL,FILE_BEGIN);
		SetFilePointer(hWriteFile,BenFOffset,NULL,FILE_BEGIN);
		T* pTBuf = pTImg;
		for (int i = 0; i < Bands; i++)
		{
			ReadFile(hReadFile,(LPVOID)pTBuf,KT,&readBytes,NULL);
			SetFilePointer(hReadFile ,offsetT,NULL,FILE_CURRENT);
			pTBuf += k;
		}
		#pragma omp parallel for num_threads(kernel)
		for (long ik = 0; ik < k; ik++)
		{
			int kId = omp_get_thread_num();
			T* r = KernelR[kId];
			float* pcaR = KernelPcaR[kId];
			T* pIBuf = pTImg + ik;
			float* pJBuf = pFImg + ik;
			for (int i = 0; i < Bands; i++)
			{
				r[i] = *pIBuf;
				pIBuf += k;
			}
			ExcetPca<T>(r,eiv,BLUT,pcaR,Bands,reductBand);
			for(int i = 0; i < reductBand; i++)
			{
				*pJBuf = pcaR[i];
				pJBuf += k;
			}
		}
		float* pFBuf = pFImg;
		for (int i = 0; i < reductBand; i++)
		{
			WriteFile(hWriteFile,(LPVOID)pFBuf,KF,&writeBytes,NULL);
			SetFilePointer(hWriteFile ,offsetF,NULL,FILE_CURRENT);
			pFBuf += k;
		}
		BenTOffset += KT;
		BenFOffset += KF;
	}
	k = HW - k * HW2;
	if (k != 0)
	{
		SetFilePointer(hReadFile ,BenTOffset,NULL,FILE_BEGIN);
		SetFilePointer(hWriteFile,BenFOffset,NULL,FILE_BEGIN);
		KT = k * sizeof(T);
		KF = k * sizeof(float);
		offsetT = (HW - k) * sizeof(T);
		offsetF = (HW - k) * sizeof(float);
		T* pTBuf = pTImg;
		for (int i = 0; i < Bands; i++)
		{
			ReadFile(hReadFile,(LPVOID)pTBuf,KT,&readBytes,NULL);
			SetFilePointer(hReadFile ,offsetT,NULL,FILE_CURRENT);
			pTBuf += k;
		}
		if (k < kernel) kernel = k;
		#pragma omp parallel for num_threads(kernel)
		for (long ik = 0; ik < k; ik++)
		{
			int kId = omp_get_thread_num();
			T* r = KernelR[kId];
			float* pcaR = KernelPcaR[kId];
			T* pIBuf = pTImg + ik;
			float* pJBuf = pFImg + ik;
			for (int i = 0; i < Bands; i++)
			{
				r[i] = *pIBuf;
				pIBuf += k;
			}
			ExcetPca<T>(r,eiv,BLUT,pcaR,Bands,reductBand);
			for(int i = 0; i < reductBand; i++)
			{
				*pJBuf = pcaR[i];
				pJBuf += k;
			}
		}
		float* pFBuf = pFImg;
		for (int i = 0; i < reductBand; i++)
		{
			WriteFile(hWriteFile,(LPVOID)pFBuf,KF,&writeBytes,NULL);
			SetFilePointer(hWriteFile ,offsetF,NULL,FILE_CURRENT);
			pFBuf += k;
		}
	}
	FREE2(KernelR,kernel);
	FREE2(KernelPcaR,kernel);
	free(pTImg);
	free(pFImg);
}
template <typename T>   //保存pca数据(ENVI格式数据)
void BSQSaveRMPcaDataOMP(HANDLE hReadFile,HANDLE hWriteFile,int* BLUT,ulong HW,ulong Width,ulong Height,int Bands,int reductBand,double* eiv)
{
	ulong readBytes = 0;
	ulong writeBytes = 0;
	ulong RBD = sizeof(double) * reductBand;
	double* mean = (double*)malloc(RBD);
	memset(mean,0,RBD);
	int kernel = GetKCount();
	MALLOC2(T,KernelR,kernel,Bands);
	MALLOC2(float,KernelPcaR,kernel,reductBand);
	MALLOC2(double,meanK,kernel,reductBand);
	ulong BT = Bands * sizeof(T);
	long proSize = SIZE16M;
	if(GetMemoryInfoG() >= 2) proSize = SIZE32M;
	long k = proSize / BT; //BT比小于16M
	ulong offsetT = (HW - k) * sizeof(T);
	ulong offsetF = (HW - k) * sizeof(float);
	ulong KT = k * sizeof(T);
	ulong KF = k * sizeof(float);
	ulong BenTOffset = 0;
	ulong BenFOffset = 0;
	T* pTImg = (T*)malloc(k * BT);
	float* pFImg = (float*)malloc(KF * reductBand);
	ulong HW2 = HW / k;
	for (ulong y = 0; y < HW2; y++)
	{
		SetFilePointer(hReadFile ,BenTOffset,NULL,FILE_BEGIN);
		SetFilePointer(hWriteFile,BenFOffset,NULL,FILE_BEGIN);
		T* pTBuf = pTImg;
		for (int i = 0; i < Bands; i++)
		{
			ReadFile(hReadFile,(LPVOID)pTBuf,KT,&readBytes,NULL);
			SetFilePointer(hReadFile ,offsetT,NULL,FILE_CURRENT);
			pTBuf += k;
		}
		#pragma omp parallel for num_threads(kernel)
		for (long ik = 0; ik < k; ik++)
		{
			int kId = omp_get_thread_num();
			T* r = KernelR[kId];
			float* pcaR = KernelPcaR[kId];
			T* pIBuf = pTImg + ik;
			float* pJBuf = pFImg + ik;
			for (int i = 0; i < Bands; i++)
			{
				r[i] = *pIBuf;
				pIBuf += k;
			}
			ExcetPca<T>(r,eiv,BLUT,pcaR,Bands,reductBand,meanK[kId]);
			for(int i = 0; i < reductBand; i++)
			{
				*pJBuf = pcaR[i];
				pJBuf += k;
			}
		}
		float* pFBuf = pFImg;
		for (int i = 0; i < reductBand; i++)
		{
			WriteFile(hWriteFile,(LPVOID)pFBuf,KF,&writeBytes,NULL);
			SetFilePointer(hWriteFile ,offsetF,NULL,FILE_CURRENT);
			pFBuf += k;
		}
		BenTOffset += KT;
		BenFOffset += KF;
	}
	k = HW - k * HW2;
	if (k != 0)
	{
		SetFilePointer(hReadFile ,BenTOffset,NULL,FILE_BEGIN);
		SetFilePointer(hWriteFile,BenFOffset,NULL,FILE_BEGIN);
		KT = k * sizeof(T);
		KF = k * sizeof(float);
		offsetT = (HW - k) * sizeof(T);
		offsetF = (HW - k) * sizeof(float);
		T* pTBuf = pTImg;
		for (int i = 0; i < Bands; i++)
		{
			ReadFile(hReadFile,(LPVOID)pTBuf,KT,&readBytes,NULL);
			SetFilePointer(hReadFile ,offsetT,NULL,FILE_CURRENT);
			pTBuf += k;
		}
		if (k < kernel) kernel = k;
		#pragma omp parallel for num_threads(kernel)
		for (long ik = 0; ik < k; ik++)
		{
			int kId = omp_get_thread_num();
			T* r = KernelR[kId];
			float* pcaR = KernelPcaR[kId];
			T* pIBuf = pTImg + ik;
			float* pJBuf = pFImg + ik;
			for (int i = 0; i < Bands; i++)
			{
				r[i] = *pIBuf;
				pIBuf += k;
			}
			ExcetPca<T>(r,eiv,BLUT,pcaR,Bands,reductBand,meanK[kId]);
			for(int i = 0; i < reductBand; i++)
			{
				*pJBuf = pcaR[i];
				pJBuf += k;
			}
		}
		float* pFBuf = pFImg;
		for (int i = 0; i < reductBand; i++)
		{
			WriteFile(hWriteFile,(LPVOID)pFBuf,KF,&writeBytes,NULL);
			SetFilePointer(hWriteFile ,offsetF,NULL,FILE_CURRENT);
			pFBuf += k;
		}
	}
	FREE2(KernelR,kernel);
	FREE2(KernelPcaR,kernel);
	free(pTImg);
	#pragma omp parallel for
	for (int i = 0; i < reductBand; i++)
	{
		double sum = 0;
		for (int kid = 0; kid < kernel; kid++) sum += meanK[kid][i];
		mean [i] = sum / HW;
	}
	FREE2(meanK,kernel);
	//去均值
	SetFilePointer(hWriteFile,0,NULL,FILE_BEGIN);
	k = proSize / sizeof(float);
	KF = k * sizeof(float);
	pFImg = (float*)realloc(pFImg,proSize);
	HW2 = HW / k;
	ulong k1  = HW - k * HW2;
	ulong K1F = k1 * sizeof(float);
	for (int i = 0; i < Bands; i++)
	{
		for (ulong x = 0; x < HW2; x++)
		{
			ReadFile(hWriteFile,(LPVOID)pFImg,KF,&readBytes,NULL);
			#pragma omp parallel for num_threads(kernel)
			for (long ik = 0; ik < k; ik++)
			{
				float* pFBuf = pFImg + ik;
				*pFBuf = *pFBuf - mean[i];
			}
			SetFilePointer(hWriteFile ,-KF,NULL,FILE_CURRENT);
			WriteFile(hWriteFile,(LPVOID)pFImg,KF,&writeBytes,NULL);
		}
		if(k1 != 0)
		{
			ReadFile(hWriteFile,(LPVOID)pFImg,K1F,&readBytes,NULL);
			#pragma omp parallel for num_threads(kernel)
			for (long ik = 0; ik < k1; ik++)
			{
				float* pFBuf = pFImg + ik;
				*pFBuf = *pFBuf - mean[i];
			}
			SetFilePointer(hWriteFile ,-K1F,NULL,FILE_CURRENT);
			WriteFile(hWriteFile,(LPVOID)pFImg,K1F,&writeBytes,NULL);
		}
	}
	free(pFImg);
	free(mean);
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值