2015-03-06 3 views
1

У меня возникли трудности с реализацией билинейной интерполяции повернутого изображения. Изображение представлено в виде двойников в 2D-матрице. Ниже приведен код, который я использовал. Изображение правильно поворачивается на нужный угол, однако интерполяция, по-видимому, не устраняет «зубчатость» выходного изображения по желанию.Вращение 2D-матрицы с билинейной интерполяцией

Может ли кто-нибудь идентифицировать проблему с моим кодом?

// DimX & DimY are dimensions of input Image (Which has padded space for rotation) 
// radian = angle as rad (2*PI*{angle in deg})/360) 
// COGPosX & COGPosY are the Centre of Gravity pos for the Input Matrix 
// SliceMatrix is the un-rotated input Matrix 

// double cosine,sine,f1,f2,fval,p1,p2,p3,p4,rotX,rotY,xfloor,yfloor; 
// double *sliceMatrix, *rotationMatrixInter; 
// int x,y,dimX,dimY,COGPosX,COGPosY,rotatedX,rotatedY; 

cosine = (double)cos(radian); 
sine = (double)sin(radian); 

for(y=0;y<dimY;y++) 
{ 
    for(x=0;x<dimX;x++) 
    { 
     // Calculate rotated Matrix positions 
     rotatedX=(double)((x-COGPosX)*cosine)-((y-COGPosY)*sine)+COGPosX; 
     rotatedY=(double)((x-COGPosX)*sine)+((y-COGPosY)*cosine)+COGPosY; 

     rotX = (int)floor(rotatedX); 
     rotY = (int)floor(rotatedY); 

     xfloor = floor(rotatedX); 
     yfloor = floor(rotatedY); 

     if(rotX >=0 && rotY < dimX-1 && rotY >=0 && rotY < dimY-1) 
     { 
      // BLI Calculation 
      p1 = sliceMatrix[rotX+(dimX*rotY)];   // 0,0 
      p2 = sliceMatrix[rotX+(dimX*(rotY+1))];  // 0,1 
      p3 = sliceMatrix[(rotX+1)+(dimX*rotY)];  // 1,0 
      p4 = sliceMatrix[(rotX+1)+(dimX*(rotY+1))]; // 1,1 

      f1 = p1 + (p3-p1)*(rotatedX-xfloor); 
      f2 = p2 + (p4-p2)*(rotatedX-xfloor); 
      fval = f1 + (f2-f1)*(rotatedY-yfloor); 

      rotationMatrixInter[x+(dimX*y)]= fval; 
     }  
    } 
} 
+0

Каковы типы 'p1',' p2', 'p3',' p4'? – Codor

+0

Теперь я отредактирую код, чтобы включить объявления для фрагмента –

ответ

1

По-видимому, вы действительно не интерполируете, как ожидалось. rotatedX и rotatedY имеют тип int; если вы бросить их в два раза, они остаются целые значения и знаменатели

((double)(rotatedX+1.0)-(double)rotatedX)) 
((double)(rotatedX+1.0)-(double)rotatedX)) 

отменяют, чтобы быть 1.0, что означает, что никакой реальной интерполяции по желанию не происходит, но f1 и f2 реально получить назначенную p3 и p4 соответственно. Переменные rotatedX и rotatedY должны быть типа double. После поворота их нужно будет округлить вниз и вверх (или просто округлить вниз и добавить один), чтобы получить четыре позиции для выборки данных изображения, и разница в округленных значениях будет определять интерполяцию. Это можно сделать следующим образом, где floor предполагается округлить.

double xfloor = floor(rotatedX); 
double yfloor = floor(rotatedY); 

f1 = p1 + (p3-p1)*(rotatedX-xfloor); 
f2 = p2 + (p4-p2)*(rotatedX-xfloor); 
fval = f1 + (f2-f1)*(rotatedY-yfloor); 
+0

Измененный код, как в вашем ответе, но я получаю тот же результат –

+0

Простое изменение типа не решает проблему; знаменатели также должны быть изменены; Я обновлю ответ. – Codor

+0

Обновлен мой код, выведенное изображение теперь искажено –

Смежные вопросы