代码更新:

1. 仿真部分代码修改为GPU
2. 删除了原CPU的仿真代码
3. GPU代码部分,由 SimulationSAR 文件,移动到 BaseLibraryCPP 文件中
4. 补充了成像平面的 matlab 代码
Release
陈增辉 2024-11-29 23:32:50 +08:00
parent e56b8f2d98
commit bee90080f2
18 changed files with 1446 additions and 612 deletions

@ -1 +1 @@
Subproject commit 458be41d96524bbdad14aaa0b6184a5de387e7e5
Subproject commit ef94aa388ae2ed85e970ff4f857450a5f28cf0b2

239
README.md
View File

@ -1 +1,238 @@
# RasterProcessTool
# RasterProcessTool
extern "C" void AddCUDA(void* aPtr, void* bptr, void* cptr, long member, LAMPGPUDATETYPE datetype) {
int blockSize = 256; // 每个块的线程数
int numBlocks = (member + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
}
// CUDA 核函数
__global__ void computeDistanceAndEchoID(float* antPx, float* antPy, float* antPz,
float* img_x, float* img_y, float* img_z,
complexfloat* echopluse, complexfloat* imgarr,
long rowcount, long colcount, long prfid,
float Rnear, float fs, float factorj) {
long idx = blockIdx.x * blockDim.x + threadIdx.x;
// 确保线程索引有效
if (idx < rowcount * colcount) {
// 计算距离
float dx = antPx[prfid] - img_x[idx];
float dy = antPy[prfid] - img_y[idx];
float dz = antPz[prfid] - img_z[idx];
float imgR = sqrt(dx * dx + dy * dy + dz * dz);
// 计算 EchoID
long echoID = floor(((imgR - Rnear) * 2 / LIGHTSPEED) * fs);//回波坐标
float Rftj = imgR * factorj; // 校正
//printf("%d:(%f,%f),%f,%f |||||, %f, %f, %f, %f, %f, %f, %f\n", idx, echopluse[echoID].real, Rftj, imgR, fs,
// antPx[prfid], antPy[prfid], antPz[prfid], img_x[idx], img_y[idx], img_z[idx], imgR);
if (echoID < 0 || echoID >= colcount) {
}
else {
complexfloat Rphi{ 0,Rftj };
Rphi = expComplex(Rphi);
imgarr[idx] = addComplex(imgarr[idx], mulComplex(echopluse[echoID], Rphi));
}
}
}
void TBPImageGPUBlock(float* antPx, float* antPy, float* antPz, float* img_x, float* img_y, float* img_z,
std::shared_ptr<std::complex<double>> echoArr, long prfcount, long plusecount,
std::shared_ptr<std::complex<double>> imageArr,
float freq, float fs, float Rnear, float Rfar, float factorj,
long startline, long stepline,
long rowcount, long colcount) {
long pixelcount = rowcount * colcount;
complexfloat* h_echopluse;
complexfloat* h_imgarr;
cudaMallocHost(&h_echopluse, sizeof(float) * 2 * plusecount); // 单个传感器的位置
cudaMallocHost(&h_imgarr, sizeof(float) * 2 * stepline * colcount);
for (long i = 0; i < stepline; i++) {
long rid = startline + i;
for (long j = 0; j < colcount; j++) {
h_imgarr[i * colcount + j].real = imageArr.get()[rid * colcount + j].real();
h_imgarr[i * colcount + j].imag = imageArr.get()[rid * colcount + j].imag();
}
}
std::cout << "h_imgarr init finished!!" << std::endl;
float* h_antPx, * h_antPy, * h_antPz;
cudaMallocHost(&h_antPx, sizeof(float) * prfcount); // 单个传感器的位置
cudaMallocHost(&h_antPy, sizeof(float) * prfcount);
cudaMallocHost(&h_antPz, sizeof(float) * prfcount);
// 初始化
for (long i = 0; i < prfcount; i++) {
h_antPx[i] = antPx[i];
h_antPy[i] = antPy[i];
h_antPz[i] = antPz[i];
}
float* h_img_x, * h_img_y, * h_img_z;
cudaMallocHost(&h_img_x, sizeof(float) * stepline * colcount);
cudaMallocHost(&h_img_y, sizeof(float) * stepline * colcount);
cudaMallocHost(&h_img_z, sizeof(float) * stepline * colcount);
// 初始化
long rid = 0;
for (long i = 0; i < stepline; i++) {
rid = startline + i;
for (long j = 0; j < colcount; j++) {
h_img_x[i * colcount + j] = img_x[rid * colcount + j];
h_img_y[i * colcount + j] = img_y[rid * colcount + j];
h_img_z[i * colcount + j] = img_z[rid * colcount + j];
}
}
std::cout << "h_img_x init finished!!" << std::endl;
// 分配设备内存
float* d_antPx, * d_antPy, * d_antPz, * d_img_x, * d_img_y, * d_img_z;
complexfloat* d_echopluse;
complexfloat* d_imgarr;
cudaMalloc(&d_echopluse, sizeof(float) * 2 * plusecount);
cudaMalloc(&d_imgarr, sizeof(float) * 2 * stepline * colcount);
cudaMalloc(&d_antPx, sizeof(float) * prfcount);
cudaMalloc(&d_antPy, sizeof(float) * prfcount);
cudaMalloc(&d_antPz, sizeof(float) * prfcount);
cudaMalloc(&d_img_x, sizeof(float) * rowcount * colcount);
cudaMalloc(&d_img_y, sizeof(float) * rowcount * colcount);
cudaMalloc(&d_img_z, sizeof(float) * rowcount * colcount);
// 将数据从主机拷贝到设备
cudaMemcpy(d_antPx, h_antPx, sizeof(float) * prfcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_antPx, h_antPx, sizeof(float) * prfcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_antPy, h_antPy, sizeof(float) * prfcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_antPz, h_antPz, sizeof(float) * prfcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_img_x, h_img_x, sizeof(float) * rowcount * colcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_img_y, h_img_y, sizeof(float) * rowcount * colcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_img_z, h_img_z, sizeof(float) * rowcount * colcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_imgarr, h_imgarr, sizeof(float) * 2 * stepline * colcount, cudaMemcpyHostToDevice);
int blockSize = 256; // 每个块的线程数
int numBlocks = (pixelcount + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小
long eid = 0;
std::complex<double> Rphi;
for (long prfid = 0; prfid < prfcount; prfid++) {
for (long i = 0; i < plusecount; i++) {
h_echopluse[i].real = echoArr.get()[prfid * plusecount + i].real();
h_echopluse[i].imag = echoArr.get()[prfid * plusecount + i].imag();
}
cudaMemcpy(d_echopluse, h_echopluse, sizeof(float) * 2 * plusecount, cudaMemcpyHostToDevice);
computeDistanceAndEchoID << < numBlocks, blockSize >> > (d_antPx, d_antPy, d_antPz,
d_img_x, d_img_y, d_img_z,
d_echopluse, d_imgarr,
rowcount, colcount, prfid,
Rnear, fs, factorj);
cudaDeviceSynchronize();// 等待所有设备任务完成
if (prfid % 100 == 0) {
//std::cout << "\rprf " << prfid <<"/"<< prfcount << "\t\t\t";
}
//cudaMemcpy(h_echopluse, d_echopluse, sizeof(float) * 2 * stepline * colcount, cudaMemcpyDeviceToHost);
}
std::cout << std::endl;
// GPU -> CPU
cudaMemcpy(h_imgarr, d_imgarr, sizeof(float) * 2 * stepline * colcount, cudaMemcpyDeviceToHost);
for (long i = 0; i < stepline; i++) {
long rid = startline + i;
for (long j = 0; j < colcount; j++) {
imageArr.get()[rid * colcount + j] = std::complex<double>(h_imgarr[i * colcount + j].real, h_imgarr[i * colcount + j].imag);
}
}
// 清理资源
cudaFree(d_antPx);
cudaFree(d_antPy);
cudaFree(d_antPz);
cudaFree(d_img_x);
cudaFree(d_img_y);
cudaFree(d_img_z);
cudaFree(d_echopluse);
cudaFree(d_imgarr);
cudaFreeHost(h_antPx);
cudaFreeHost(h_antPy);
cudaFreeHost(h_antPz);
cudaFreeHost(h_img_x);
cudaFreeHost(h_img_y);
cudaFreeHost(h_img_z);
cudaFreeHost(h_echopluse);
cudaFreeHost(h_imgarr);
std::cout << "end GPU" << std::endl;
}
void RTPC(float* antx, float* anty, float* antz,
float* demx, float* demy, float* demz,
float* demslopex, float* demslopey, float* demslopez
) {}

View File

@ -179,6 +179,7 @@
<QtMoc Include="SimulationSAR\QToolAbstract.h" />
<QtMoc Include="RegisterToolbox.h" />
<QtMoc Include="SimulationSAR\QSimulationBPImage.h" />
<ClInclude Include="BaseLibraryCPP\GPUTool.cuh" />
<ClInclude Include="SimulationSAR\TBPImageAlgCls.h" />
<QtMoc Include="QSimulationRTPCGUI.h" />
<QtMoc Include="GF3ProcessToolbox\QOrthSlrRaster.h" />
@ -206,8 +207,9 @@
<QtMoc Include="QMergeRasterProcessDialog.h" />
</ItemGroup>
<ItemGroup>
<CudaCompile Include="SimulationSAR\TBPGPU.cu">
<FileType>Document</FileType>
<CudaCompile Include="BaseLibraryCPP\GPUTool.cu">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</ExcludedFromBuild>
</CudaCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -219,6 +219,9 @@
<ClInclude Include="SimulationSAR\TBPImageAlgCls.h">
<Filter>SimulationSAR</Filter>
</ClInclude>
<ClInclude Include="BaseLibraryCPP\GPUTool.cuh">
<Filter>BaseLibraryCPP</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtMoc Include="QMergeRasterProcessDialog.h">
@ -297,8 +300,8 @@
</QtUic>
</ItemGroup>
<ItemGroup>
<CudaCompile Include="SimulationSAR\TBPGPU.cu">
<Filter>SimulationSAR</Filter>
<CudaCompile Include="BaseLibraryCPP\GPUTool.cu">
<Filter>BaseLibraryCPP</Filter>
</CudaCompile>
</ItemGroup>
</Project>

View File

@ -81,8 +81,10 @@ void QSimulationBPImage::onbtnaccepted()
TBPimag.setEchoL0(echoL0ds);
TBPimag.setImageL1(imagL1);
long cpucore_num = std::thread::hardware_concurrency();
TBPimag.setGPU(true);
TBPimag.Process(cpucore_num);
QMessageBox::information(this,u8"成像",u8"成像结束");
}
void QSimulationBPImage::onbtnrejected()

View File

@ -44,6 +44,9 @@
<height>30</height>
</size>
</property>
<property name="text">
<string>D:\Programme\vs2022\RasterMergeTest\TestData\outData\GF3_Simulation.xml</string>
</property>
</widget>
</item>
<item>
@ -92,6 +95,9 @@
<height>30</height>
</size>
</property>
<property name="text">
<string>D:\Programme\vs2022\RasterMergeTest\TestData\outBPImage2\GF3_Simulation</string>
</property>
</widget>
</item>
<item>

File diff suppressed because it is too large Load Diff

View File

@ -613,6 +613,13 @@ ErrorCode AbstractRadiationPattern::getGainLinear(double& theta, double& phi, do
}
double AbstractRadiationPattern::getGainLearThetaPhi(double theta, double phi)
{
double gainvlaue = 0;
this->getGainLinear(theta, phi, gainvlaue);
return gainvlaue;
}
ErrorCode AbstractRadiationPattern::setGain(double& theta, double& phi, double& GainValue)
{
this->GainMap.push_back(RadiationPatternGainPoint{ theta,phi,GainValue });

View File

@ -112,6 +112,7 @@ public:
virtual std::vector<RadiationPatternGainPoint> getGainList();
virtual ErrorCode getGain(double& theta, double& phi, double& GainValue);
virtual ErrorCode getGainLinear(double& theta, double& phi, double& GainValue);
double getGainLearThetaPhi(double theta, double phi);
virtual ErrorCode setGain(double& theta, double& phi, double& GainValue);
virtual ErrorCode RecontructGainMatrix(double threshold=-3);
virtual std::vector<double> getThetas();

View File

@ -226,11 +226,17 @@ void PolyfitSatelliteOribtModel::setAntnnaAxisZ(double X, double Y, double Z)
///
ErrorCode PolyfitSatelliteOribtModel::getAntnnaDirection(SatelliteOribtNode& node)
{
bool flag = false;
double nexttime = node.time + 1e-6;
SatelliteOribtNode node1 = this->getSatelliteOribtNode(nexttime, flag);
// 1. 计算天线指向
Eigen::Vector3d axisZ0 = { -1*node.Px ,-1 * node.Py,-1 * node.Pz}; // z 轴 --波位角为0时天线指向的反方向
Eigen::Vector3d axisX0 = { node.Vx ,node.Vy,node.Vz }; // x 轴 --飞行方向
Eigen::Vector3d axisZ0 = { -1 * node.Px ,-1 * node.Py,-1 * node.Pz }; // z 轴 --波位角为0时天线指向的反方向
Eigen::Vector3d axisX0 = { (node1.Px - node.Px) , (node1.Py - node.Py), (node1.Pz - node.Pz) }; // x 轴 --飞行方向
Eigen::Vector3d axisY0 = axisZ0.cross(axisX0); // y 轴 --右手定则 -- 初始坐标系
double rotateAngle = this->RightLook ? -this->beamAngle : this->beamAngle; // 旋转角度 左逆时针theta , 右(顺时针): -theta
// 1.2. 根据波位角确定卫星绕X轴-飞行轴
@ -240,7 +246,7 @@ ErrorCode PolyfitSatelliteOribtModel::getAntnnaDirection(SatelliteOribtNode& nod
axisX0=rotateMatrixBeam*axisX0;
// 1.3. 根据方位角确定卫星绕Y轴旋转
double azangle = node.AzAngle;
Eigen::Matrix3d rotateMatrixAzAngle = rotationMatrix(axisY0, rotateAngle * d2r); // 旋转矩阵
Eigen::Matrix3d rotateMatrixAzAngle = rotationMatrix(axisY0, azangle * d2r); // 旋转矩阵
axisZ0 = rotateMatrixAzAngle * axisZ0; // 旋转矩阵
axisY0 = rotateMatrixAzAngle * axisY0;
axisX0 = rotateMatrixAzAngle * axisX0;
@ -270,9 +276,13 @@ ErrorCode PolyfitSatelliteOribtModel::getAntnnaDirection(SatelliteOribtNode& nod
ErrorCode PolyfitSatelliteOribtModel::getZeroDopplerAntDirect(SatelliteOribtNode& node)
{
bool flag = false;
double nexttime = node.time + 1e-6;
SatelliteOribtNode node1 = this->getSatelliteOribtNode(nexttime, flag);
// 1. 计算天线指向
Eigen::Vector3d axisZ0 = { -1 * node.Px ,-1 * node.Py,-1 * node.Pz }; // z 轴 --波位角为0时天线指向的反方向
Eigen::Vector3d axisX0 = { node.Vx ,node.Vy,node.Vz }; // x 轴 --飞行方向
Eigen::Vector3d axisX0 = { (node1.Px-node.Px) , (node1.Py - node.Py) , (node1.Pz - node.Pz) }; // x 轴 --飞行方向
Eigen::Vector3d axisY0 = axisZ0.cross(axisX0); // y 轴 --右手定则 -- 初始坐标系
double rotateAngle = this->RightLook ? -this->beamAngle : this->beamAngle; // 旋转角度 左逆时针theta , 右(顺时针): -theta
@ -284,7 +294,7 @@ ErrorCode PolyfitSatelliteOribtModel::getZeroDopplerAntDirect(SatelliteOribtNode
axisX0 = rotateMatrixBeam * axisX0;
// 1.3. 根据方位角确定卫星绕Y轴旋转
double azangle = 0;
Eigen::Matrix3d rotateMatrixAzAngle = rotationMatrix(axisY0, rotateAngle * d2r); // 旋转矩阵
Eigen::Matrix3d rotateMatrixAzAngle = rotationMatrix(axisY0, azangle * d2r); // 旋转矩阵
axisZ0 = rotateMatrixAzAngle * axisZ0; // 旋转矩阵
axisY0 = rotateMatrixAzAngle * axisY0;
axisX0 = rotateMatrixAzAngle * axisX0;

View File

@ -1,190 +0,0 @@
#include <iostream>
#include <memory>
#include <cmath>
#include <complex>
#include <cuda_runtime.h>
#include <cublas_v2.h>
#include <device_launch_parameters.h>
#include "BaseConstVariable.h"
void checkCudaError(cudaError_t err, const char* msg) {
if (err != cudaSuccess) {
std::cerr << "CUDA error: " << msg << " (" << cudaGetErrorString(err) << ")" << std::endl;
exit(EXIT_FAILURE);
}
}
// CUDA 核函数
__global__ void computeDistanceAndEchoID(float* antPx, float* antPy, float* antPz,
float* img_x, float* img_y, float* img_z,
float* imgR, float* imgEchoID,
long rowcount, long colcount, long prfid,
float Rnear, float fs) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
// 确保线程索引有效
if (i < rowcount && j < colcount) {
int idx = i * colcount + j;
// 计算距离
float dx = antPx[prfid] - img_x[idx];
float dy = antPy[prfid] - img_y[idx];
float dz = antPz[prfid] - img_z[idx];
imgR[idx] = sqrt(dx * dx + dy * dy + dz * dz);
// 计算 EchoID
imgEchoID[idx] = (imgR[idx] - Rnear) / (2 * LIGHTSPEED) * fs;
}
}
/// <summary>
/// TBP GPU代码
/// </summary>
/// <param name="antpos_ptr">卫星轨道坐标</param>
/// <param name="echoArr">回波矩阵</param>
/// <param name="img_arr">图像矩阵</param>
void TBPImageGPUAlgBlock(std::shared_ptr<float> antPx, std::shared_ptr<float> antPy, std::shared_ptr<float> antPz, // 天线坐标
std::shared_ptr<float> antVx, std::shared_ptr<float> antVy, std::shared_ptr<float> antVz,
std::shared_ptr<float> img_x, std::shared_ptr<float> img_y, std::shared_ptr<float> img_z, // 图像坐标
std::shared_ptr<std::complex<float>> echoArr,std::shared_ptr<std::complex<float>> img_arr,
float freq, float fs,float Rnear,float Rfar,
long rowcount,long colcount) {
float factorj = freq * 4 * PI / LIGHTSPEED;
std::shared_ptr<float> imgR(new float[rowcount * colcount]);
std::shared_ptr<long> imgEchoID(new long[rowcount * colcount]);
for (long prfid = 0; prfid < rowcount; prfid++) {
for (long i = 0; i < rowcount; i++) {
for (long j = 0; j < colcount; j++) {
imgR.get()[i * colcount + j] = std::sqrt(
std::pow(antPx.get()[prfid]-img_x.get()[i * colcount + j], 2)
+ std::pow(antPy.get()[prfid] - img_y.get()[i * colcount + j], 2)
+ std::pow(antPz.get()[prfid] - img_z.get()[i * colcount + j], 2)
);
imgEchoID.get()[i * colcount + j] = (imgR.get()[i * colcount + j] - Rnear) / 2 / LIGHTSPEED * fs;
}
}
}
// 分配主机内存
float* h_antPx, * h_antPy, * h_antPz, * h_img_x, * h_img_y, * h_img_z;
float* h_imgR, * h_imgEchoID;
cudaMallocHost(&h_antPx, sizeof(float) * 1); // 单个传感器的位置
cudaMallocHost(&h_antPy, sizeof(float) * 1);
cudaMallocHost(&h_antPz, sizeof(float) * 1);
cudaMallocHost(&h_img_x, sizeof(float) * rowcount * colcount);
cudaMallocHost(&h_img_y, sizeof(float) * rowcount * colcount);
cudaMallocHost(&h_img_z, sizeof(float) * rowcount * colcount);
cudaMallocHost(&h_imgR, sizeof(float) * rowcount * colcount);
cudaMallocHost(&h_imgEchoID, sizeof(float) * rowcount * colcount);
// 将数据初始化到主机内存(这里仅为示例,实际数据根据需求加载)
for (long i = 0; i < rowcount * colcount; i++) {
h_img_x[i] = 0.0f;
h_img_y[i] = 0.0f;
h_img_z[i] = 0.0f;
}
h_antPx[0] = 0.0f;
h_antPy[0] = 0.0f;
h_antPz[0] = 0.0f;
// 分配设备内存
float* d_antPx, * d_antPy, * d_antPz, * d_img_x, * d_img_y, * d_img_z;
float* d_imgR, * d_imgEchoID;
cudaMalloc(&d_antPx, sizeof(float) * 1);
cudaMalloc(&d_antPy, sizeof(float) * 1);
cudaMalloc(&d_antPz, sizeof(float) * 1);
cudaMalloc(&d_img_x, sizeof(float) * rowcount * colcount);
cudaMalloc(&d_img_y, sizeof(float) * rowcount * colcount);
cudaMalloc(&d_img_z, sizeof(float) * rowcount * colcount);
cudaMalloc(&d_imgR, sizeof(float) * rowcount * colcount);
cudaMalloc(&d_imgEchoID, sizeof(float) * rowcount * colcount);
// 将数据从主机拷贝到设备
cudaMemcpy(d_antPx, h_antPx, sizeof(float) * 1, cudaMemcpyHostToDevice);
cudaMemcpy(d_antPy, h_antPy, sizeof(float) * 1, cudaMemcpyHostToDevice);
cudaMemcpy(d_antPz, h_antPz, sizeof(float) * 1, cudaMemcpyHostToDevice);
cudaMemcpy(d_img_x, h_img_x, sizeof(float) * rowcount * colcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_img_y, h_img_y, sizeof(float) * rowcount * colcount, cudaMemcpyHostToDevice);
cudaMemcpy(d_img_z, h_img_z, sizeof(float) * rowcount * colcount, cudaMemcpyHostToDevice);
// 设置 CUDA 核函数的网格和块的尺寸
dim3 blockDim(16, 16); // 每个块处理 16x16 的像素点
dim3 gridDim((colcount + blockDim.x - 1) / blockDim.x,
(rowcount + blockDim.y - 1) / blockDim.y);
// 调用 CUDA 核函数
computeDistanceAndEchoID << <gridDim, blockDim >> > (d_antPx, d_antPy, d_antPz,
d_img_x, d_img_y, d_img_z,
d_imgR, d_imgEchoID,
rowcount, colcount, prfid,
RNEAR, LIGHTSPEED, FS);
// 等待所有设备任务完成
cudaDeviceSynchronize();
// 将结果从设备拷贝回主机
cudaMemcpy(h_imgR, d_imgR, sizeof(float) * rowcount * colcount, cudaMemcpyDeviceToHost);
cudaMemcpy(h_imgEchoID, d_imgEchoID, sizeof(float) * rowcount * colcount, cudaMemcpyDeviceToHost);
// 清理资源
cudaFree(d_antPx);
cudaFree(d_antPy);
cudaFree(d_antPz);
cudaFree(d_img_x);
cudaFree(d_img_y);
cudaFree(d_img_z);
cudaFree(d_imgR);
cudaFree(d_imgEchoID);
cudaFreeHost(h_antPx);
cudaFreeHost(h_antPy);
cudaFreeHost(h_antPz);
cudaFreeHost(h_img_x);
cudaFreeHost(h_img_y);
cudaFreeHost(h_img_z);
cudaFreeHost(h_imgR);
cudaFreeHost(h_imgEchoID);
}

View File

@ -6,6 +6,8 @@
#include <cmath>
#include <QProgressDialog>
void TBPImageProcess(QString echofile, QString outImageFolder, QString imagePlanePath,long num_thread)
{
std::shared_ptr<EchoL0Dataset> echoL0ds(new EchoL0Dataset);
@ -63,7 +65,7 @@ std::shared_ptr<SARSimulationImageL1Dataset> TBPImageAlgCls::getImageL0()
ErrorCode TBPImageAlgCls::Process(long num_thread)
{
if (GPURUN) {
return this->ProcessGPU();
}
else {
return this->ProcessCPU(num_thread);
@ -337,36 +339,88 @@ ErrorCode TBPImageAlgCls::ProcessGPU()
pixelZ.get()[i*colCount+ j] = Pz + AntDirectZ * R;
}
}
qDebug()<<"R: " << R;
this->L1ds->saveAntPos(antpos);
antpos.reset();
}
std::shared_ptr<std::complex<float>> imagarr(new std::complex<float>[rowCount * colCount]);
{
std::shared_ptr<std::complex<double>> Rasterarr = this->L1ds->getImageRaster();
for (long i = 0; i < pixelCount; i++) {
imagarr.get()[i] = Rasterarr.get()[i];
}
}
std::shared_ptr<std::complex<float>> echodata(new std::complex<float>[rowCount * colCount]);
{
std::shared_ptr<std::complex<double>> echodataPtr = this->L0ds->getEchoArr();
for (long i = 0; i < PRFCount; i++) {
for (long j = 0; j < PlusePoints; j++) {
echodata.get()[i * PlusePoints + j] = echodataPtr.get()[i * PlusePoints + j];
for (long i = 0; i < rowCount; i++) {
for (long j = 0; j < colCount; j++) {
Rasterarr.get()[i * colCount + j] = Rasterarr.get()[i * colCount + j] * 0.0;
}
}
}
TBPImageGPUAlg(Pxs, Pys, Pzs, // ÌìÏß×ø±ê
Vxs, Vys, Vzs,
pixelX, pixelY, pixelZ, // ͼÏñ×ø±ê
echodata, imagarr, freq,fs,Rnear,Rfar,rowCount,colCount);
TBPImageGPUAlg(Pxs, Pys, Pzs, // 天线坐标
Vxs, Vys, Vzs,
pixelX, pixelY, pixelZ, // 图像坐标
echodataPtr, Rasterarr,
freq, fs, Rnear, Rfar,
rowCount, colCount, this->L1ds);
qDebug() << "image writing:\t" << this->L1ds->getxmlFilePath();
return ErrorCode::SUCCESS;
}
void TBPImageAlgCls::setGPU(bool flag)
{
this->GPURUN = flag;
}
bool TBPImageAlgCls::getGPU( )
{
return this->GPURUN;
}
/// <summary>
/// TBP GPU代码
/// </summary>
/// <param name="antpos_ptr">卫星轨道坐标</param>
/// <param name="echoArr">回波矩阵</param>
/// <param name="img_arr">图像矩阵</param>
void TBPImageGPUAlg(std::shared_ptr<float> antPx, std::shared_ptr<float> antPy, std::shared_ptr<float> antPz, // 天线坐标
std::shared_ptr<float> antVx, std::shared_ptr<float> antVy, std::shared_ptr<float> antVz,
std::shared_ptr<float> img_x, std::shared_ptr<float> img_y, std::shared_ptr<float> img_z, // 图像坐标
std::shared_ptr<std::complex<double>> echoArr, std::shared_ptr<std::complex<double>> img_arr,
float freq, float fs, float Rnear, float Rfar,
long rowcount, long colcount, std::shared_ptr<SARSimulationImageL1Dataset> L1ds) {
float factorj = freq * 4 * PI / LIGHTSPEED;
qDebug() << "factorj:\t" << factorj;
qDebug() << "freq:\t" << freq;
qDebug() << "fs:\t" << fs;
qDebug() << "Rnear:\t" << Rnear;
qDebug() << "Rfar:\t" << Rfar;
qDebug() << "img_x:\t" << img_x.get()[0];
qDebug() << "img_y:\t" << img_y.get()[0];
qDebug() << "img_z:\t" << img_z.get()[0];
long blockline = Memory1MB * 1000 / sizeof(float) / colcount;
blockline = blockline < 10 ? 10 : blockline;
for (long startline = 0; startline < rowcount; startline = startline + blockline) {
long stepline = startline + blockline < rowcount ? blockline : rowcount - startline;
std::cout << startline << " \ " << rowcount << " "<< stepline << " start " << std::endl;
//TBPImageGPUBlock(antPx.get(), antPy.get(), antPz.get(), img_x.get(), img_y.get(), img_z.get(),
// echoArr, rowcount, colcount,
// img_arr,
// freq, fs, Rnear, Rfar, factorj, startline, stepline,
// stepline, colcount);
//std::cout << startline << " \ " << rowcount << " " << stepline << " end " << std::endl;
//L1ds->saveImageRaster(img_arr, 0, rowcount);
}
L1ds->saveImageRaster(img_arr, 0, rowcount);
L1ds->saveToXml();
}

View File

@ -50,12 +50,21 @@ public:
public:
ErrorCode Process(long num_thread);
void setGPU(bool flag);
bool getGPU( );
private:
ErrorCode ProcessCPU(long num_thread);
ErrorCode ProcessGPU();
};
void TBPImageProcess(QString echofile,QString outImageFolder,QString imagePlanePath,long num_thread);
void TBPImageProcess(QString echofile,QString outImageFolder,QString imagePlanePath,long num_thread);
void TBPImageGPUAlg(std::shared_ptr<float> antPx, std::shared_ptr<float> antPy, std::shared_ptr<float> antPz, // ÌìÏß×ø±ê
std::shared_ptr<float> antVx, std::shared_ptr<float> antVy, std::shared_ptr<float> antVz,
std::shared_ptr<float> img_x, std::shared_ptr<float> img_y, std::shared_ptr<float> img_z, // ͼÏñ×ø±ê
std::shared_ptr<std::complex<double>> echoArr, std::shared_ptr<std::complex<double>> img_arr,
float freq, float fs, float Rnear, float Rfar,
long rowcount, long colcount, std::shared_ptr<SARSimulationImageL1Dataset> L1ds);

Binary file not shown.

View File

@ -0,0 +1,21 @@
%% WGS84直角坐标系转经纬度
% 东经正数,西经为负数
% 北纬为正数,南纬为负数
% 输入参数1纬度输入参数2经度输入参数3高度
% 经纬度单位:度;高度单位:米
function [latitude,longitude,height]=XYZ2LLA(x,y,z)
a = 6378137.0;
b = 6356752.31424518;
c = sqrt(((a * a) - (b * b)) / (a * a));
d = sqrt(((a * a) - (b * b)) / (b * b));
p = sqrt((x * x) + (y * y));
q = atan((z * a)/ (p * b));
longitude = atan(y/x);
latitude = atan((z + (d * d) * b * sin(q)^3)/(p - (c * c) * a * cos(q)^3));
N = a / sqrt(1 - ((c * c) * sin(latitude)^2));
height = (p / cos(latitude)) - N;
longitude = longitude * 180.0 / pi+180;
latitude = latitude * 180.0 / pi;
end

View File

@ -0,0 +1,226 @@
% n0= [-1944902.1250000000 4077521.2500000000 4487326.5000000000 ];
% n1= [-1944873.0000000000 4077511.0000000000 4487348.5000000000 ];
% n2= [-1944922.0000000000 4077512.0000000000 4487326.5000000000 ];
% n3= [-1944931.3750000000 4077531.5000000000 4487305.0000000000 ];
% n4= [-1944882.3750000000 4077530.7500000000 4487326.5000000000 ];
%
% n01 = n1 - n0, n02 = n2 - n0, n03 = n3 - n0, n04 = n4 - n0;
%
% VN=(cross(n01, n04) + cross(n04, n03) + cross(n03, n02) + cross(n02, n01)) * 0.25;
% VNorm=VN./norm(VN);
clear,clc,close all
% 打开二进制文件
fileID = fopen('D:\\Programme\\vs2022\\RasterMergeTest\\TestData\\outData\\GF3_Simulation.gpspos.data', 'rb'); % 假设二进制文件名为 'data.bin'
% 定义每个数据字段的数据类型
% 假设每个数据是双精度浮动数8字节
dataType = 'double';
% 读取数据:根据你的数据格式,数据长度为 16 * 8 字节每个元素8字节
% 例如每16个数据项为一组对应prf_id
numFields = 19; % 每组数据的字段数
PRFnumRecords = 15382; % 假设有100个记录你可以根据实际情况修改
% 读取所有记录的数据
rawData = fread(fileID, numFields * PRFnumRecords, dataType);
% 关闭文件
fclose(fileID);
% 解析数据为结构体数组
data = struct();
AntDirecX=zeros(PRFnumRecords,1);
AntDirecY=zeros(PRFnumRecords,1);
AntDirecZ=zeros(PRFnumRecords,1);
Px=zeros(PRFnumRecords,1);
Py=zeros(PRFnumRecords,1);
Pz=zeros(PRFnumRecords,1);
Vx=zeros(PRFnumRecords,1);
Vy=zeros(PRFnumRecords,1);
Vz=zeros(PRFnumRecords,1);
% 假设你的数据在 rawData 中按顺序排列
% 例如,解析 prf_id = 0, 1, 2...的相关数据
for prf_id = 0:PRFnumRecords-1
idx = prf_id * numFields + 1;
data(prf_id+1).prf_time = rawData(idx); % prf_time + imageStarttime
Px(prf_id+1) = rawData(idx+1); % sateOirbtNode.Px
Py(prf_id+1) = rawData(idx+2); % sateOirbtNode.Py
Pz(prf_id+1) = rawData(idx+3); % sateOirbtNode.Pz
Vx(prf_id+1) = rawData(idx+4); % sateOirbtNode.Vx
Vy(prf_id+1) = rawData(idx+5); % sateOirbtNode.Vy
Vz(prf_id+1) = rawData(idx+6); % sateOirbtNode.Vz
AntDirecX(prf_id+1) = rawData(idx+7); % sateOirbtNode.AntDirecX
AntDirecY(prf_id+1) = rawData(idx+8); % sateOirbtNode.AntDirecY
AntDirecZ(prf_id+1) = rawData(idx+9); % sateOirbtNode.AntDirecZ
data(prf_id+1).AVx = rawData(idx+10); % sateOirbtNode.AVx
data(prf_id+1).AVy = rawData(idx+11); % sateOirbtNode.AVy
data(prf_id+1).AVz = rawData(idx+12); % sateOirbtNode.AVz
data(prf_id+1).lon = rawData(idx+13); % outP.lon
data(prf_id+1).lat = rawData(idx+14); % outP.lat
data(prf_id+1).ati = rawData(idx+15); % outP.ati
end
% 查看解析后的数据
disp(data);
fileID = fopen('D:\\Programme\\vs2022\\RasterMergeTest\\TestData\\outData\\tmp\\ImageX.dat', 'rb'); % 假设二进制文件名为 'data.bin'
dataType = 'float';
numFields = 5400; % 每组数据的字段数
numRecords = 5400; % 假设有100个记录你可以根据实际情况修改
demX = fread(fileID, numFields * numRecords, dataType);
demX=reshape(demX,[numRecords,numRecords]);
fclose(fileID);
fileID = fopen('D:\\Programme\\vs2022\\RasterMergeTest\\TestData\\outData\\tmp\\ImageY.dat', 'rb'); % 假设二进制文件名为 'data.bin'
dataType = 'float';
numFields = 5400; % 每组数据的字段数
numRecords = 5400; % 假设有100个记录你可以根据实际情况修改
demY = fread(fileID, numFields * numRecords, dataType);
demY=reshape(demY,[numRecords,numRecords]);
fclose(fileID);
fileID = fopen('D:\\Programme\\vs2022\\RasterMergeTest\\TestData\\outData\\tmp\\ImageZ.dat', 'rb'); % 假设二进制文件名为 'data.bin'
dataType = 'float';
numFields = 5400; % 每组数据的字段数
numRecords = 5400; % 假设有100个记录你可以根据实际情况修改
demZ = fread(fileID, numFields * numRecords, dataType);
demZ=reshape(demZ,[numRecords,numRecords]);
fclose(fileID);
%% 绘制成像平面
Rn=884053;
Rf=942069;
data_ant_norm=(AntDirecX.^2+AntDirecY.^2+AntDirecZ.^2).^0.5;
AntDirecX=AntDirecX./data_ant_norm;
AntDirecY=AntDirecY./data_ant_norm;
AntDirecZ=AntDirecZ./data_ant_norm;
Rlist=linspace(Rn,Rf,300);
ImageX=zeros(PRFnumRecords,300);
ImageY=zeros(PRFnumRecords,300);
ImageZ=zeros(PRFnumRecords,300);
for i=1:PRFnumRecords
ImageX(i,:)=Px(i,:) + Rlist.*AntDirecX(i,:);
ImageY(i,:)=Py(i,:) + Rlist.*AntDirecY(i,:);
ImageZ(i,:)=Pz(i,:) + Rlist.*AntDirecZ(i,:);
end
B=[AntDirecX(1,1),AntDirecY(1,1),AntDirecZ(1,1)];
A=[Px(1,1)-Px(2,1),Py(1,1)-Py(2,1),Pz(1,1)-Pz(2,1)] ;
V=[Vx(1,1),Vy(1,1),Vz(1,1)];
% 计算点积
dotProduct = dot(A,B);
% 计算模长
normA = norm(A);
normB = norm(B);
% 计算夹角的余弦值
cosTheta = acos(dotProduct / (normA * normB));
cosTheta*180/pi
tp=[-2023401.250000,4104205.500000,4428297.000000];
TP=Px.*0;
for i=1:PRFnumRecords
TP(i,:)=sqrt((Px(i,:) -tp(1)).^2+(Py(i,:) -tp(2)).^2+(Pz(i,:) -tp(3)).^2);
end
figure,
plot(TP )
PR=(Px.^2+Py.^2+Pz.^2).^0.5;
ImageR=(ImageX.^2+ImageY.^2+ImageZ.^2).^0.5;
figure,
plot(ImageR(:,1)),hold on
plot(ImageR(:,end)),hold on
plot(PR),hold on
legend(["Rn","Rf","Rs"])
a=[Px-mean(demX,"all"),Py-mean(demY,"all"),Pz-mean(demZ,"all")];
a=(a(:,1).^2+a(:,2).^2+a(:,3).^2).^0.5;
figure,
surfl(ImageX,ImageY,ImageZ),shading flat,hold on
scatter3(mean(demX,"all"),mean(demY,"all"),mean(demZ,"all"),'red','filled'),shading flat,hold on
plot3(Px,Py,Pz,'red')
xlabel("X")
ylabel("Y")
zlabel("Z")
view([-90.6000010944003 90]);
dl=sqrt((Px(1)-Px(end)).^2+(Py(1)-Py(end)).^2+(Pz(1)-Pz(end)).^2);
R=7;
ImageR=((Px(10000,1)-R-Px).^2+(Py(10000,1)-R-Py).^2+(Pz(10000,1)-R-Pz).^2).^0.5;
figure,
plot(ImageR)
P=zeros(100*100,3);
pp=1;
for i=1:100
for j=1:100
[latitude,longitude,height]=XYZ2LLA(ImageX(i,j),ImageY(i,j),ImageZ(i,j));
P(pp,:)=[latitude,longitude,height];
pp=pp+1;
end
end
% %% 计算
%
%
% Tx=-2001212.875000;
% Ty=4082207.000000;
% Tz=4471714.500000;
% R=((demX-Px(1)).^2+(demY-Py(1)).^2+(demZ-Pz(1)).^2).^0.5;
% figure,
% plot(R)
%
% imgX=ImageX(3000,150);
% imgY=ImageY(3000,150);
% imgZ=ImageZ(3000,150);
% R1= sqrt((ImageX(1,1)-Px(:,1)).^2+(ImageY(1,1)-Py(:,1)).^2+(ImageZ(1,1)-Pz(:,1)).^2);
% figure,
% plot(R1)
%
%
%
% Timgx=abs(ImageX-Tx);
% Timgy=abs(ImageY-Ty);
% Timgz=abs(ImageZ-Tz);
%
% [latitude,longitude,height]=XYZ2LLA(ImageX(3000,150),ImageY(3000,150),ImageZ(3000,150))
%
%
%

265
script/datasetCreate.ipynb Normal file

File diff suppressed because one or more lines are too long

141
script/gdalClipRaster.ipynb Normal file
View File

@ -0,0 +1,141 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"id": "7d84d0c7-8625-432c-acd7-89bdb0e66a43",
"metadata": {},
"outputs": [],
"source": [
"from osgeo import gdal\n",
"import os\n",
"\n",
"def crop_raster(input_raster_path, output_raster_path, bounds):\n",
" \"\"\"\n",
" 使用 GDAL 裁剪栅格影像到指定的四至范围。\n",
"\n",
" :param input_raster_path: 输入栅格影像路径\n",
" :param output_raster_path: 输出裁剪后影像的路径\n",
" :param bounds: 裁剪范围,格式为 (minx, miny, maxx, maxy)\n",
" \"\"\"\n",
" minx, miny, maxx, maxy = bounds\n",
"\n",
" # 打开输入影像\n",
" dataset = gdal.Open(input_raster_path)\n",
" if dataset is None:\n",
" print(f\"无法打开输入影像: {input_raster_path}\")\n",
" return\n",
"\n",
" # 获取影像的投影和变换信息\n",
" geo_transform = dataset.GetGeoTransform()\n",
" projection = dataset.GetProjection()\n",
"\n",
" # 计算裁剪区域在影像中的像素坐标\n",
" ulx = int((minx - geo_transform[0]) / geo_transform[1]) # 左上角 x\n",
" uly = int((maxy - geo_transform[3]) / geo_transform[5]) # 左上角 y\n",
" lrx = int((maxx - geo_transform[0]) / geo_transform[1]) # 右下角 x\n",
" lry = int((miny - geo_transform[3]) / geo_transform[5]) # 右下角 y\n",
"\n",
" # 检查像素坐标是否在影像范围内\n",
" if ulx < 0 or uly < 0 or lrx > dataset.RasterXSize or lry > dataset.RasterYSize:\n",
" print(\"裁剪范围超出影像范围!\")\n",
" return\n",
"\n",
" # 创建输出影像\n",
" driver = gdal.GetDriverByName('GTiff')\n",
" out_dataset = driver.Create(output_raster_path, lrx - ulx, lry - uly, dataset.RasterCount, gdal.GDT_Float32)\n",
"\n",
" # 设置输出影像的投影和变换信息\n",
" out_geo_transform = (minx, geo_transform[1], geo_transform[2], maxy, geo_transform[4], geo_transform[5])\n",
" out_dataset.SetGeoTransform(out_geo_transform)\n",
" out_dataset.SetProjection(projection)\n",
"\n",
" # 将裁剪后的数据写入输出影像\n",
" for i in range(1, dataset.RasterCount + 1):\n",
" band = dataset.GetRasterBand(i)\n",
" data = band.ReadAsArray(ulx, uly, lrx - ulx, lry - uly)\n",
" out_dataset.GetRasterBand(i).WriteArray(data)\n",
"\n",
" # 清理\n",
" out_dataset.FlushCache()\n",
" del out_dataset\n",
" del dataset\n",
"\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "3ac1f4a3-38f8-4c50-8bad-36852fcb18f6",
"metadata": {},
"outputs": [],
"source": [
"# 输入栅格影像路径\n",
"input_raster = \"115E39N_COP30.tif\"\n",
"\n",
"# 输出裁剪后影像的路径\n",
"output_raster = \"115E39N_COP30_clip.tif\"\n",
"\n",
"\n",
"# 定义裁剪范围 (minx, miny, maxx, maxy)\n",
"bounds =(115.5,43.5,117.0,45.0) # 示例范围\n",
"\n",
"# 裁剪影像\n",
"crop_raster(input_raster, output_raster, bounds)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "65dcf0f1-55e7-4dfa-8988-412ca0e6c41a",
"metadata": {},
"outputs": [],
"source": [
"(xmin, ymin, xmax, ymax)=(115.5,43.5,117.0,45.0)\n",
"# 定义裁剪范围 (minx, miny, maxx, maxy)\n",
"bounds = (xmin, ymin, xmax, ymax) # 例如 (100000, 200000, 110000, 210000)\n",
"# 裁剪影像\n",
"clip_raster(input_raster, output_raster, bounds)\n",
"print(f\"影像已裁剪并保存到: {output_raster}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ea8bcfa3-7612-477d-bf0b-b4e3537fcf33",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "407416e7-729d-4d7e-ae09-318cdfce7739",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.19"
}
},
"nbformat": 4,
"nbformat_minor": 5
}