IDL 运算时间比较

程序的效率问题,在大数据或复杂运算的时候是不能忽略的。但在IDL程序的编写方式上,不能按照常规的循环for依次处理方式写,简单归纳下,提高效率的运行的写法注意下面两种方式。

1、 尽量避免或少用循环

2、 多用where和Histogram;

3、total 函数应用

说起来很容易,但实际写的时候一定要多斟酌斟酌。

举例1:对2000*2000的数组中大于100的值进行累加。

程序运行输出:

结果明显显示出:利用total函数运算时间要明显快的多

;≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌

;;;=====================================
;;对一个图像中的特定值,若存在,则以该像素为中心,特定半径
;;内的元素统一修改为某值
;;以IDL自带的图像为例,将数据值等于142的赋为0
;;计算两点之间的距离

;计算两个点的距离

function CalDistance, point1, point2

  compile_opt idl2    ;

  ReturnSQRT((point1[0]-point2[0])^2+(point1[1]-point2[1])^2)

end

;≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌

;搜索当前坐标周围Distance内的下标,注意输入x和y方向的坐标范围xRange和yRange

function calIdxInDistance, curLoc, distance;,xRange,yRange

  ;初始化临时下标

  suitLoc = [0,0]

  ;循环一次,计算矩形范围内的符合要求下标

  for xLoc = curLoc[0]-distance, curLoc[0]+distance do begin

    for yLoc = curLoc[1]-distance, curLoc[1]+distance  do begin

      if calDistance(curLoc, [xLoc,yLoc]) LE distance then suitLoc = [[suitLoc],[xLoc,yLoc]]

    endfor

  end  

  return, suitLoc[*,1:(N_Elements(suitLoc)/2-1)]

end

;≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌≌

;测试即调用主函数

pro test_process

  ;原数据

  file = FILEPATH('rbcells.jpg', $

    SUBDIRECTORY = ['examples', 'data'])

  READ_JPEG, file, data

  ;

  if size(data,/n_dimensions) ne 2 then return

  dims = size(data,/dimension)

  startTime  = systime(1)

  ;当值等于142时,半径5内的元素赋值为0

  eqValue = 142

  repValue = 0

  ;符合要求的坐标

  suitIdx = calIdxInDistance([0,0],5)

  ;新数据

  nData = data

  idxs = where(data eq eqValue,count)

  for curIdx =0,count-1 do begin 

    nSuit = suitIdx

    ;转换为二维坐标

    suitLoc = ARRAY_INDICES(data, idxs[curIdx])

    nSuit[0,*]= nSuit[0,*]+suitLoc[0]

    nSuit[1,*]= nSuit[1,*]+suitLoc[1]

    ;下标要在数组自身范围内

    nSuit[0,*] = dims[0] < nSuit[0,*] > 0

    nSuit[1,*] = dims[1] < nSuit[1,*] > 0

    ;符合要求的位置赋值

    nData[nSuit[0,*],nSuit[1,*]] = repValue

  endfor

  ;输出花费时间

  print,systime(1) - startTime

  ;常规的循环写法

  ns = dims[0]

  nl = dims[1]

  new = data

  new1 = data

  startTime = systime(1)

  for i=0,ns-1 do begin

    for j=0,nl-1 do begin

      if new[i,j] eq eqValue then begin

        for m=0,ns-1 do begin

          for n=0,nl-1 do begin

            if (m-i*1L)^2+(n-j*1L)^2 le 25 then new1[m,n]=0

          endfor

        endfor

      endif

    endfor

  endfor

  print,'common time:',systime(1) - startTime

  window,1,xSize = dims[0]*2,ySize = dims[1]

  tvscl,Data,0

  tvscl,ndata,1

  window,2,xSize = dims[0]*2,ySize = dims[1]

  tvscl,new,0

  tvscl,new1,1

end

程序运行输出:

图像输出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值