【问题标题】:Image rotation (bi-linear interpolation and nearest neighbor)图像旋转(双线性插值和最近邻)
【发布时间】:2016-06-01 19:48:37
【问题描述】:

我想旋转我的图像。我从文件transform1(应该将图像旋转45度)和transform2(进行投影变换)中获取输入矩阵。这些矩阵用于我必须遵循的逆映射算法。程序可以工作,但将输出作为原始图像而不是旋转它。

void ntransform1 ( char * filename, image * img )
{
    int i,j,x,y,n,m;
    float det=0;
    double** mat = malloc(1000000 * sizeof(double*));

    for ( i = 0; i < 1000000; ++i)
        mat[i] = malloc(4 * sizeof(double));

    FILE *file;
    file=fopen(filename, "r");

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++)
        {
            if (!fscanf(file, "%lf", &mat[i][j])) break;
            // mat[i][j] -= '0';
            // printf("%lf\n",mat[i][j]);
        }
    }
    // printf("%lf\n",mat[1][1]);
    det = (mat[0][0]*mat[1][1]) - (mat[0][1]*mat[1][0])
        - (mat[0][0]*mat[1][2]*mat[2][1])
        + (mat[2][0]*mat[0][1]*mat[1][2])
        + (mat[0][2]*mat[1][0]*mat[2][1])
        - (mat[0][2]*mat[1][1]*mat[2][0]);

    // inverse of matrix is
    mat[0][0] =  (mat[1][1]-(mat[1][2]*mat[2][1])) / det;
    mat[0][1] = -(mat[0][1]-(mat[0][2]*mat[2][1])) / det;
    mat[0][2] = ((mat[0][1]*mat[1][2])-(mat[0][2]*mat[1][1])) / det;
    mat[1][0] = -(mat[1][0]-(mat[1][2]*mat[2][0])) / det;
    mat[1][1] = (mat[0][0]-(mat[0][2]*mat[2][0])) / det;
    mat[1][2] = -((mat[0][0]*mat[1][2])-(mat[0][2]*mat[1][0])) / det;
    mat[2][0] = ((mat[1][0]*mat[2][1])-(mat[1][1]*mat[2][0])) / det;
    mat[2][1] = -((mat[0][0]*mat[2][1])-(mat[0][1]*mat[2][0])) / det;
    mat[2][2] = ((mat[0][0]*mat[0][2])-(mat[0][1]*mat[1][0])) / det;

    for(y=0;y<img->y;y++)
    {
        for(x=0;x<img->x;x++)
        {
            double xnew,ynew;
            // calculating the new rotated pixel value
            xnew = (float)(((x-(img->x)/2))
                 * (mat[0][0]))+((y-(img->y)/2)
                 * (mat[0][1]))+mat[0][2]+(img->x)/2;
            ynew = (float)(((x-(img->x)/2))
                 * (mat[1][0]))+((y-(img->y)/2)
                 * (mat[1][1]))+mat[1][2]+(img->y)/2;
            m = (int)round(xnew);
            n = (int)round(ynew);
            image2[n][m];
        }
    }
}

void bitransform1 ( char * filename, image * img )
{
    int i,j;
    float det=0;
    /*matrix*/

    double** mat = malloc(1000000 * sizeof(double*)); 
    for(i=0;i<1000000;++i)
        mat[i]=malloc(4*sizeof(double));

    FILE *file;
    file=fopen(filename, "r");

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 3; j++) 
        {

            if (!fscanf(file, "%lf", &mat[i][j])) break;
            // mat[i][j] -= '0'; 
            // printf("%lf\n",mat[i][j]); 
        }
    }
    // printf("%lf\n",mat[1][1]);
    det = (mat[0][0]*mat[1][1])-(mat[0][1]*mat[1][0])-(mat[0][0]*mat[1][2]*mat[2][1])+(mat[2][0]*mat[0][1]*mat[1][2])+(mat[0][2]*mat[1][0]*mat[2][1])-(mat[0][2]*mat[1][1]*mat[2][0]);

    // inverse of matrix is
    mat[0][0]=(mat[1][1]-(mat[1][2]*mat[2][1]))/det;
    mat[0][1]=-(mat[0][1]-(mat[0][2]*mat[2][1]))/det;
    mat[0][2]=((mat[0][1]*mat[1][2])-(mat[0][2]*mat[1][1]))/det;
    mat[1][0]=-(mat[1][0]-(mat[1][2]*mat[2][0]))/det;
    mat[1][1]=(mat[0][0]-(mat[0][2]*mat[2][0]))/det;
    mat[1][2]=-((mat[0][0]*mat[1][2])-(mat[0][2]*mat[1][0]))/det;
    mat[2][0]=((mat[1][0]*mat[2][1])-(mat[1][1]*mat[2][0]))/det;
    mat[2][1]=-((mat[0][0]*mat[2][1])-(mat[0][1]*mat[2][0]))/det;
    mat[2][2]=((mat[0][0]*mat[0][2])-(mat[0][1]*mat[1][0]))/det;


int y,x,m,n;
double xfrac,yfrac,gray_new;

for(y=0;y<img->y;y++)
{
    for(x=0;x<img->x;x++)
    {

        double xnew,ynew;
// caclulating the new rotated pixel value
  xnew=(((x-(img->x)/2))*(mat[0][0]))+((y-(img->y)/2)*(mat[0][1]))+mat[0][2]+(img->x)/2;
  ynew=(((x-(img->x)/2))*(mat[1][0]))+((y-(img->y)/2)*(mat[1][1]))+mat[1][2]+(img->y)/2;
  m=(int)floor(xnew);
  n=(int)floor(ynew);
  xfrac=xnew-m;
  yfrac=ynew-n;

// calculating the 4 neighbors of the pixel
if (m >= 0 && m+1 < img->x && n >= 0 && n+1 < img->y)
 {
    gray_new = (1.0 - yfrac)*(1.0 - xfrac)*image1[n][m] + (1.0-xfrac)*(yfrac) *image1[n][m+1] + (1.0-yfrac)*( xfrac)*image1[n+1][m] + xfrac*yfrac *image1[n+1][m+1];

    image2[y][x] = (unsigned char)gray_new;
      } 
else if (m+1 == img->x && n >= 0 && n < img->y || n+1 == img->y && m >= 0 && m <img->x)
 {
    //image2[y][x] = image1[n][m];
      }
 else
 {
    image2[y][x] = 255;
      }
}
    }
    fclose(file);
}     

【问题讨论】:

  • 我很确定全大写对您的情况没有帮助。你应该添加一个实际的问题;目前,这只是“我想做图像旋转,这是我的代码”。它不工作吗?什么不起作用?它应该怎么做?它做了什么?
  • 它确实有效,但在输出中它只是给出原始图像!对于 transform1.txt 它应该将输入图像旋转 45 度,对于 transform2.txt 它应该进行投影变换,但它会将输出作为输入图像本身
  • 将其添加到问题中 - 你可以edit它。
  • 我开始格式化你的代码,这真是一团糟,但我变得太累了。真是一团糟,难怪你不知道它在做什么。

标签: c image image-processing


【解决方案1】:

你没有对你的目标图像image2做任何事情。基本上,代码应该是这样的:

for (y = 0; y < img->y; y++) {
    for (x = 0; x < img->x; x++) {
        int X = (x - img->x / 2) * c - (y - img->y / 2) * s + img2->x / 2;
        int Y = (x - img->x / 2) * s - (y - img->y / 2) * c + img2->y / 2;

        if (X >= 0 && X < img2->x && Y >= 0 && Y <=img2->y) {
            img2->data[y][x] = img->data[Y][X];
        }
    }
}

其中xy是目标图像的像素坐标img2XY是源图像img的像素坐标。

您的代码有很多特点:

  • 您分配了一个 1000000 × 4 双精度的两级向量,以保存一个 3×3 的旋转矩阵。为什么还要使用 3d 旋转矩阵? (我认为第三列是平移向量。)
  • image 和`image2 是什么?它们是全局数组吗?像素值不应该是图像结构的一部分吗?
  • 您的代码将受益于模块化:编写一个函数来读取矩阵;另一个函数来反转它等等。目前,您有很多重复的代码。

【讨论】:

  • 是的 image1 是一个用于获取输入图像的数组,而 image2 是用于获取输出图像...我必须使用双线性插值,所以我必须获取 4 个相邻像素,而你没有在这种情况下拍摄
  • 此声明:image2[n][m];不做任何事情。您必须以某种方式分配给image2。不过,您可以在第二个函数中执行此操作。您是否尝试过调试并发现计算出的坐标是什么?
猜你喜欢
  • 2020-05-20
  • 2016-06-06
  • 2019-11-07
  • 2019-09-22
  • 2010-12-21
  • 2012-04-24
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多