这个问题不是语言特定的,而且是一个数学问题。然而,我将使用一些C ++代码来解释我需要什么,因为我对数学不太热。
以下是图像的组成方式:
ImageMatrix image;
image[0][0][0] = 1;
image[0][1][0] = 2;
image[0][2][0] = 1;
image[1][0][0] = 0;
image[1][1][0] = 0;
image[1][2][0] = 0;
image[2][0][0] = -1;
image[2][1][0] = -2;
image[2][2][0] = -1;
这是我正在尝试创建的函数的原型:
ImageMatrix rotateImage(ImageMatrix image, double angle);
我想只旋转前两个索引(行和列),而不是通道。
答案 0 :(得分:28)
解决这个问题的通常方法是向后做。您可以计算输出图像中每个像素在输入图像中的位置(通过在另一个方向上旋转相同的量 ,而不是计算输入图像中每个像素的最终位置。这样,您可以确保输出图像中的所有像素都具有值。
output = new Image(input.size())
for each pixel in input:
{
p2 = rotate(pixel, -angle);
value = interpolate(input, p2)
output(pixel) = value
}
有不同的插值方法。对于旋转公式,我认为你应该检查https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions
但是为了好看,这里是(点(x,y)角度/弧度的旋转):
newX = cos(angle)*x - sin(angle)*y
newY = sin(angle)*x + cos(angle)*y
答案 1 :(得分:2)
请注意除了旋转矩阵之外还有另一种解决方案,即不会通过锯齿丢失图像信息。 您可以将2D图像旋转分离为skews and scalings,从而保持图像质量。
答案 2 :(得分:2)
要旋转图像,您需要创建3个点:
A----B
|
|
C
并围绕A旋转。要获得新的旋转图像,请执行以下操作:
这可能听起来很复杂,但事实并非如此。请看一下我前面写的这个C#代码: rotoZoomer by me
绘图时,我稍微改变源指针以获得类似橡胶的效果,但是如果禁用它,您将看到代码旋转图像没有问题。当然,在某些角度你会得到一个看起来有点扭曲的图像。源代码包含正在进行的注释,因此您应该能够轻松地获取其背后的数学/逻辑。
如果你更喜欢Java,我也已经制作了一个java版本,大约14年前;) - > http://www.xs4all.nl/~perseus/zoom/zoom.java
答案 3 :(得分:0)
您提供的示例似乎是一些边缘检测内核。因此,如果您想要检测不同角度的边缘,您最好选择一些连续函数(在您的情况下可能是x1的参数化高斯乘以x2),然后根据kigurai提供的公式旋转它。因此,您可以更有效地生成磁盘内核而不会出现锯齿。