为什么我的图像旋转算法不起作用?

Nic*_*ton 5 math image image-processing

尝试 1 和 2:

注意:删除了减少问题大小的首次尝试。请参阅社区 wiki 了解之前的尝试。

尝试3:

根据 fuzzy-waffle 的示例,我已经实现了以下内容,但它似乎无法正常工作。有什么想法我可能做错了什么吗?

ImageMatrix ImageMatrix::GetRotatedCopy(VDouble angle)
{
    // Copy the specifications of the original.
    ImageMatrix &source = *this;
    ImageMatrix &target = CreateEmptyCopy();

    double centerX = ((double)(source.GetColumnCount()-1)) / 2;
    double centerY = ((double)(source.GetRowCount()-1)) / 2;

    // Remember: row = y, column = x
    for (VUInt32 y = 0; y < source.GetRowCount(); y++)
    {
        for (VUInt32 x = 0; x < source.GetColumnCount(); x++)
        {
            double dx = ((double)x) - centerX;
            double dy = ((double)y) - centerY;

            double newX = cos(angle) * dx - sin(angle) * dy + centerX;
            double newY = cos(angle) * dy + sin(angle) * dx + centerY;

            int ix = (int)round(newX);
            int iy = (int)round(newY);

            target[x][y][0] = source[ix][iy][0];
        }
    }

    return target;
}
Run Code Online (Sandbox Code Playgroud)

有了这个原型矩阵...

1 2 1 
0 0 0 
-1 -2 -1 
Run Code Online (Sandbox Code Playgroud)

...prototype.GetRotatedCopy(0)(这是正确的)...

1 2 1 
0 0 0 
-1 -2 -1 
Run Code Online (Sandbox Code Playgroud)

...原型.GetRotatedCopy(90)(不正确)...

-2 0 0 
-2 0 2 
0 0 2 
Run Code Online (Sandbox Code Playgroud)

...prototype.GetRotatedCopy(180)(不正确 - 但有点逻辑?)...

0 -1 -2 
1 0 -1 
2 1 0 
Run Code Online (Sandbox Code Playgroud)

...prototype.GetRotatedCopy(270)(不正确 - 为什么这与 0 旋转相同?)...

1 2 1 
0 0 0 
-1 -2 -1 
Run Code Online (Sandbox Code Playgroud)

解决方案:

正如 Mark Ransom 所指出的,我应该使用弧度,而不是度数;我已将我的代码调整如下:

ImageMatrix ImageMatrix::GetRotatedCopy(VDouble degrees)
{
    // Copy the specifications of the original.
    ImageMatrix &source = *this;
    ImageMatrix &target = CreateEmptyCopy();
    
    // Convert degree measurement to radians.
    double angle = degrees / 57.3;
    
    // ... rest of code as in attempt #3 ...
Run Code Online (Sandbox Code Playgroud)

感谢大家的帮助!

1 2 1 
0 0 0 
-1 -2 -1 

1 2 1 
0 0 0 
-1 -2 -1 

-1 0 1 
-2 0 2 
-1 0 1 

-1 -2 -1 
0 0 0 
1 2 1 

1 0 -1 
2 0 -2 
1 0 -1 
Run Code Online (Sandbox Code Playgroud)

fuz*_*fle 3

这是我编写的一个完整的例子:我认为除其他外,您可能没有使用弧度(我们都应该使用和喜爱)。我将新坐标保留为双打,这似乎使它不那么挑剔。请注意,我没有进行我应该进行的边界检查,但我很懒。

如果您需要更快的旋转,您始终可以像本一样使用剪切。

#include <math.h>
#include <stdio.h>

#define SIZEX 3
#define SIZEY 3

int source[SIZEX][SIZEY] = {
  { 1, 0, 0 },
  { 0, 1, 0 },
  { 0, 0, 1 }
};

int target[SIZEX][SIZEY];

int main () {
  double angle = M_PI/2.0;

  memset(target,0,sizeof(int)*SIZEX*SIZEY);

  double centerX = ((double)(SIZEX-1))/2.0;
  double centerY = ((double)(SIZEY-1))/2.0;

  for (int y = 0; y < SIZEY; y++) {
    for (int x = 0; x < SIZEX; x++) {
        double dx = ((double)x)-centerX;
        double dy = ((double)y)-centerY;
        double newX = cos(angle)*dx-sin(angle)*dy+centerX;
        double newY = cos(angle)*dy+sin(angle)*dx+centerY;

        int ix = (int) round(newX);
        int iy = (int) round(newY);
        target[x][y] = source[ix][iy];
    }
  }

  for (int i=0;i<SIZEY;i++) {
    for (int j=0;j<SIZEX;j++) {
      printf("%d ", target[j][i]);
    }
    printf("\n");
  } 
}
Run Code Online (Sandbox Code Playgroud)