0

我正在尝试将一些代码从 IDL 移植到 C,但我发现自己不得不复制 ROT 函数。目标是将 1024x1024 的无符号短裤阵列旋转一个角度(以度为单位)。就本项目而言,角度非常小,小于 1 度。该函数使用双线性插值。

我尝试了一种向后的方法。对于输出数组中的每个像素,我进行了反向旋转以确定它属于输入数组中的哪个坐标,然后使用插值来确定该值是什么。如果输入网格倾斜,我不确定如何进行双线性插值;我见过的每个例子都假设它是正交的。

对于轮换,我提到了这一点:

x' = x * cos(a) + y * sin(a)
y' = y * cos(a) - x * sin(a)

来自:C/C++ 中的图像缩放和旋转

对于插值,我提到了这个:http ://en.wikipedia.org/wiki/Bilinear_interpolation

无论如何,这是我的代码:

#define DTOR 0.0174532925

void rotatearray(unsigned short int *inarray, unsigned short int *outarray, int xsize,
                 int ysize, double angle)
{
  //allocate temparray, set to 0                                                        
  unsigned short int *temparray;
  temparray = calloc(xsize*ysize, sizeof(unsigned short int));

  int xf, yf;
  int xi1, xi2, yi1, yi2;
  double xi, yi;
  double x, y;
  double minusangle = (360 - angle)*DTOR;
  unsigned short int v11, v12, v21, v22;

  int goodpixels=0;
  int badpixels=0;

  for(yf=0;yf<ysize;yf++)
    {
      for(xf=0;xf<xsize;xf++)
        {
          //what point in the input grid would map to this output pixel?                
          //(inverse of rotation)                                                       
          xi = (xf+0.5)*cos(minusangle) + (yf+0.5)*sin(minusangle);
          yi = (yf+0.5)*cos(minusangle) - (xf+0.5)*sin(minusangle);

          //Is it within bounds?                                                        
          if ((xi>(0+0.5))&&(xi<xsize-0.5)&&
              (yi>(0+0.5))&&(yi<ysize-0.5))
            {
              //what are the indices of the bounding input pixels?                  
              xi1 = (int)(xi - 0.5);                          
              xi2 = (int)(xi + 0.5);                        
              yi1 = (int)(yi - 0.5);
              yi2 = (int)(yi + 0.5);

              //What position is (x,y) in the bound unit square?
              x = xi - xi1;           
              y = yi - yi1;

              //what are the values of the bounding input pixels?                  
              v11 = inarray[yi1*xsize + xi1];//What are the values of                   
              v12 = inarray[yi2*xsize + xi1];//the bounding input pixels?               
              v21 = inarray[yi1*xsize + xi2];
              v22 = inarray[yi2*xsize + xi2];

              //Do bilinear interpolation                                               
              temparray[yf*xsize + xf] = (unsigned short int)
                (v11*(1-x)*(1-y) + v21*x*(1-y) + v12*(1-x)*y + v22*x*y);
              goodpixels++;
            }
          else{temparray[yf*xsize + xf]=0; badpixels++;}
        }
    }

  //copy to outarray                                                                    
  for(yf=0;yf<ysize;yf++)
    {
      for(xf=0;xf<xsize;xf++)
        {
          outarray[yf*xsize + xf] = temparray[yf*xsize+xf];
        }
    }

  free(temparray);
  return;
}

我通过打印几十个数字来测试它,并将其与 IDL 代码的相同 ind 进行比较,结果完全不一样。我不确定我可以提供哪些更多信息,因为我目前无法生成阵列的工作图像。您在我的实施中看到任何错误吗?我的算法背后的推理是否合理?

编辑:这是从输入数组中选择的一些数字;它们在 C 和 IDL 程序中是相同的。打印的是 x 索引,然后是 y 索引,然后是该点的值。

   0       0      24.0000
 256       0      17.0000
 512       0      23.0000
 768       0      21.0000
1023       0      0.00000
   0     256      19.0000
 256     256      459.000
 512     256      379.000
 768     256      191.000
1023     256      0.00000
   0     512      447.000
 256     512      388.000
 512     512      231.000
 768     512      231.000
1023     512      0.00000
   0     768      286.000
 256     768      378.000
 512     768      249.000
 768     768      205.000
1023     768      0.00000
   0    1023      6.00000
 256    1023      10.0000
 512    1023      11.0000
 768    1023      12.0000
1023    1023      0.00000

这是 IDL 程序在旋转后输出的内容:

   0       0      31.0000
 256       0      20.4179
 512       0      20.3183
 768       0      20.0000
1023       0      0.00000
   0     256      63.0000
 256     256      457.689
 512     256      392.406
 768     256      354.140
1023     256      0.00000
   0     512      511.116
 256     512      402.241
 512     512      230.939
 768     512      240.861
1023     512      0.00000
   0     768      296.826
 256     768      377.217
 512     768      218.039
 768     768      277.194
1023     768      0.00000
   0    1023      14.0000
 256    1023      8.00000
 512    1023      9.34906
 768    1023      23.7820
1023    1023      0.00000

这是使用我的函数旋转后的数据:

[0,0]: 0
[256,0]: 44
[512,0]: 276
[768,0]: 299
[1023,0]: 0
[0,256]: 0
[256,256]: 461
[512,256]: 439
[768,256]: 253
[1023,256]: 0
[0,512]: 0
[256,512]: 377
[512,512]: 262
[768,512]: 379
[1023,512]: 0
[0,768]: 0
[256,768]: 340
[512,768]: 340
[768,768]: 198
[1023,768]: 18
[0,1023]: 0
[256,1023]: 0
[512,1023]: 0
[768,1023]: 0
[1023,1023]: 0

我没有看到这里出现的立即有用的模式来指示正在发生的事情,这就是我最初没有包含它的原因。

编辑 编辑 编辑:我相信我的脑海里突然发现了这个问题!我注意到 0,0 像素似乎从未改变,而 1023,1023 像素变化最大。当然,这意味着算法被设计为围绕原点旋转,而我假设我试图模仿的函数被设计为围绕图像的中心旋转。答案仍然不一样,但更接近了。我所做的只是改变线路

      xi = (xf+0.5)*cos(minusangle) + (yf+0.5)*sin(minusangle);
      yi = (yf+0.5)*cos(minusangle) - (xf+0.5)*sin(minusangle);

      xi = (xf-512+0.5)*cos(minusangle) + (yf-512+0.5)*sin(minusangle) + 512;
      yi = (yf-512+0.5)*cos(minusangle) + (xf-512+0.5)*sin(minusangle) + 512;
4

0 回答 0