绘制旋转的正弦图像

时间:2011-03-07 19:21:19

标签: c# image math graphics

我正在使用2D傅里叶变换,我有一个方法可以输出以下结果: Original Image

代码如下所示:

    private Bitmap PaintSin(int s, int n)
    {
        Data = new int[Width, Height];
        Bitmap buffer = new Bitmap(Width, Height);

        double inner = (2 * Math.PI * s) / n;
        BitmapData originalData = buffer.LockBits(
           new Rectangle(0, 0, buffer.Width, buffer.Height),
           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

        for (int i = 0; i < buffer.Width; i++)
        {
            for (int j = 0; j < buffer.Height; j++)
            {
                double val;
                int c = 0;

                if (j == 0)
                {
                    val = Math.Sin(inner * i);
                    val += 1;
                    val *= 128;
                    val = val > 255 ? 255 : val;
                    c = (int)val;

                    Color col = Color.FromArgb(c, c, c);
                    SetPixel(originalData, i, j, col);
                }
                else
                    SetPixel(originalData, i, j, GetColor(originalData, i, 0));

                Data[i, j] = c;
            }
        }
        buffer.UnlockBits(originalData);

        return buffer;
    }

现在,我正在考虑一个接受角度的公式,并将图像放在实线所在角度的位置。

例如,如果我输入45度,结果将是:

Rotated image

感谢您的帮助!

如果需要,这是SetPixel代码:

    private unsafe void SetPixel(BitmapData originalData, int x, int y, Color color)
    {
        //set the number of bytes per pixel
        int pixelSize = 3;

        //get the data from the original image
        byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);

        //set the new image's pixel to the grayscale version
        oRow[x * pixelSize] = color.B; //B
        oRow[x * pixelSize + 1] = color.G; //G
        oRow[x * pixelSize + 2] = color.R; //R
    }

2 个答案:

答案 0 :(得分:2)

这应该可以通过使用旋转坐标系。 ij的转换如下:

x = i * cos(angle) - j * sin(angle);
y = j * cos(angle) + i * sin(angle);

注意:我不确定这里的度数/弧度,所以调整angle以使它适合cos和sin需要的单位。此外,您可能必须根据所需的旋转方向否定角度。

事实上,您只需要x来取代您对i的使用。我们将预先计算sin(angle)cos(angle),因为这些是我们在内部循环中不需要的非常省略的操作。另外,您的优化被删除,因为我们不能只绘制一行并重复它:

    [...]
    // double angle = ...
    double cos_angle = cos(angle);
    double sin_angle = sin(angle);
    for (int i = 0; i < buffer.Width; i++)
    {
        for (int j = 0; j < buffer.Height; j++)
        {
            double val;
            double x;
            int c = 0;

            x = i * cos_angle - j * sin_angle;
            val = Math.Sin(inner * x);
            val += 1;
            val *= 128;
            val = val > 255 ? 255 : val;
            c = (int)val;

            Color col = Color.FromArgb(c, c, c);
            SetPixel(originalData, i, j, col);

            Data[i, j] = c;
        }
    }

答案 1 :(得分:0)

您可以编写一个简单的函数rotate(x,y,angle)并在SetPixel中使用其结果。你可以google旋转矩阵。 使用angle = 0的调用应该产生默认输出。