当前位置: 首页 > 科技观察

Python硬上C语言,会怎样?

时间:2023-03-13 05:19:03 科技观察

雷达数据可视化是雷达数据处理的最后阶段,通常将二维数组数据转换为扇形图像。此二维阵列中的行数对应于雷达的扫描半径。扫描半径越大,行数越多;数据的列数与雷达的扫描角度有关。扫描角度越大,列数越多。雷达扫描数据示例(扫描半径1km,扫描范围130°)例如上图是雷达二维数据的可视化展示,扫描半径1km,扫描范围130°。下图就是由这个数据转换得到的扇区图像。二维数据转扇形图像的原始数据转扇形图像(顺时针扫描,初始相位155°)的原理很简单,就是将每一列二维数据写入输出图像的对应像素。如果输出图像的扇区弧长多于原始数据的列数,则需要进行插值。下图是将二维数据转换为扇形图像的原理示意图。原始数据有8列,输出图像的弧长为24像素(弧长取决于雷达扫描角度和扫描半径),因此每列数据重复操作。3次,每次旋转角度不同。二维数据转扇形图像原理示意图最近有网友求助,让我帮忙优化一个雷达数据可视化的Python脚本。稍微分析了一下,根据二维数据转扇形图像的基本原理,重新写了一个新的脚本文件给求助的网友。整个代码大约50行。#-*-coding:utf-8-*-importos,timeimportnumpyasnpfromPILimportImagedefoutimg(fn_squ,fn_fan,angle,r0=0,phase=180,cw=True):"""将矩形图像转换成环形fn_squ-输入文件名fn_fan-输出文件名angle-ring角度r0-ring内圆半径,默认r0为0,输出sectorphase-初始相位(原点在输出图像的中心,指向右边的水平线为0°,andthecounterclockwisedirectionisPositive)cw-scanclockwise"""im=np.array(Image.open(fn_squ))#读取图像文件为NumPy数组h,w,d=im.shape#高度、宽度和通道数矩形图像的r1=h+r0#扇区半径k=int(np.ceil(np.radians(angle)*r1/w))#插值系数(自动确定,无需修改)xs=np.ones((2*r1-1,2*r1-1),dtype=np.int32)*-1#列索引数组ys=np.ones((2*r1-1,2*r1-1),dtype=np.int32)*-1#行索引数组rs=np.linspace(r1,r0,h)#半径序列hs=range(h)#行序列ifcw:#顺时针扫描theta=np.radians(np.linspace(phase,阶段-angle,k*w))else:#Scanthetacounterclockwise=np.radians(np.linspace(phase,phase+angle,k*w))foriinrange(k*w):x=np.int32(np.cos(theta[i])*rs)+r1-1y=-np.int32(np.sin(theta[i])*rs)+r1+1xs[(y,x)]=i//kys[(y,x)]=hsim_fan=im[(ys,xs)]#从原始数据中获取扇形图像数据im_fan[np.where(xs==-1)]=(0,0,0,0)#设置空白部分为透明Image.fromarray(im_fan).save(fn_fan)#saveasfileif__name__=='__main__':fn_squ='res/raw_d130_1km.png'fn_fan='res/fan_d130_1km.png't0=time.time()outimg(fn_squ,fn_fan,angle=130,r0=100,phase=155,cw=True)t1=time.time()打印('图像已处理并保存,耗时%d毫秒'%int((t1-t0)*1000))使用上图扫描半径1km,扫描范围130°的雷达二维数据(可以直接下载图片文件作为测试数据),这段代码用了大约1.6秒的时间生成了一个扇形图片发给求助的网友,很快就有反馈:新脚本不行只是正常运行,速度却提升了20倍左右。略显夸张的感谢之后,网友表示对优化没有太大期待,只是想试试;如果优化结果不理想,他们计划用C替换这个脚本;现在好了,我们处理一下速度已经可以满足需求了,不用用C重写了,帮助顺利完成,不过这位网友的话让我有了一个想法:到底快多少它要用C来实现与Python相同的功能?总是听到很多人说Python这么慢,为什么不利用这个问题让Python和C来一场正面较量呢?不如着手去做。几个小时后,我写完了下面的C代码,同样实现了二维数据到扇形图像的转换。其中加载图片文件和保存图片文件借用了GitHub上的一个C/C++图片库。这个叫stb的图片库不为人知。仅贡献者就有188人。近10年不断发展,在圈内也算小有名气。要运行以下代码,请先到stb的GitHub(https://github.com/nothings/stb/)下载stb_image.h和stb_image_write.h这两个头文件。#include#include#include#define_USE_MATH_DEFINES#include#defineSTB_IMAGE_IMPLEMENTATION#include"stb_image.h"#defineSTB_IMAGE_WRITE_IMPLEMENTATION#include"stb_image_write.h"intmain(){LARGE_INTEGERli;LONGLONGstartTime,stopTime,freq;QueryPerformanceFrequency(&li);freq=li.QuadPart;QueryPerformanceCounter(&li);startTime=li.QuadPart;//记录开始时间char*rawFile="D://MyCcode//RadoData2Image//res//raw_d130_1km.png";char*outFile="D://MyCcode//RadoData2Image//res//fan_d130_1km.png";intw_raw=0,h_raw=0,chn=0;unsignedchar*radoData=stbi_load(rawFile,&w_raw,&h_raw,&chn,0);intr0=100,cw=1,r1=h_raw+r0;doubleangle=130.0,phase=155.0;intw_out=2*r1-1,h_out=2*r1-1;intsize_out=w_out*h_out*chn;intk=(int)(ceil((M_PI*angle/180.0)*w_out/w_raw));intarc=k*w_raw;doublestep=angle/(arc-1);char*fanData;fanData=(char*)malloc(size_out);//生成保存转换结果的数组for(inti=0;i