65.9K
CodeProject 正在变化。 阅读更多。
Home

生成条带图像

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (9投票s)

2009年2月19日

CPOL

3分钟阅读

viewsIcon

29257

downloadIcon

254

本文介绍了如何在 C# 中生成包含任意角度的马赫带的图像。

img1.png img2.png

img3.png

引言

图像来自各种来源。大多数数字图像来自数码相机,这些相机通常捕捉日常生活中遇到的场景。然而,出于学习目的,我们需要生成合成图像。合成图像构成了不常自然发现的理想模式。包含带状的图像是这种模式的一个例子。这些带状显示了灰度值的渐变,被称为马赫带。马赫带通常水平或垂直显示,并显示出有趣的视觉错觉。在本文中,我们介绍了一个程序,该程序可以以用户指定的任意角度生成马赫带(灰度)。输入参数是要生成的图像的宽度和高度,以及步数和带状的方向角度。

必要的数学知识

下图显示了图像的几何形状

Rotation_Matrix.jpg - Click to enlarge image

希望以与水平方向成 theta 角的等间距带状排列,如上图所示。为此,我们需要计算要等分的最大距离;观察上图,可以看出这个距离是 AE。这是所有条带垂直的线。使用简单的三角函数,可以证明这个距离是

RotationFormulaFinal.png

当角度变为 90 度时,不能使用此公式,但可以轻松计算出等效距离。

AE 的距离被分成等间距的间隔,并且每个这样的间隔都被分配一个灰度值,这些灰度值以相等的间隔从 0 增加到 255,具体取决于用户指定的步数。

现在,考虑图像中的一个通用像素 (x, y),需要为该像素分配一个灰度值。如果我们将 (x, y) 转换为以 theta 角定向的新坐标系 (x', y'),则很容易分配此灰度值,如上图所示。两个坐标系之间的变换方程是 

RotationMatrixFinal.png

有了这个,确定灰度值就变得很简单了。

Using the Code

程序的输入是 widthheightnumStepstheta。生成图像的步骤是

  1. 创建一个包含灰度值的数组(该数组的维度为 numSteps)。
  2. 计算距离 AE,并计算步长 - 也就是一个带的 width。当然,需要处理角度变为 90 度或负数的特殊情况。这部分代码如下所示。
  3. 形成位图 - 这涉及到计算位图中每个像素的灰度值。函数 getGrayValue() 计算灰度值。该函数的代码列表如下
//Step 2 Computation of Distance AE
double thetaRadians = 3.1415927 * theta / 180;
double thetaRad = thetaRadians;
double diagLength;
if (theta < 0)
    thetaRad = -thetaRadians;
if ((theta == 90) || (theta == -90))
{
    diagLength = width;
}
else
{
    double diagLength1 = height / Math.Cos(thetaRad);
    double val = (width - height * Math.Tan(thetaRad));
    double diagLength2 = val * Math.Sin(thetaRad);
    diagLength = Math.Abs(diagLength1 + diagLength2);
}

double stepSize = diagLength / (1.0 * numSteps);
 // Function to return the gray value corresponding to a x, y pixel position in the image
static int getGrayValue(int x, int y, int width, int height, int numSteps, 
            double thetaRadians, double diagLength, double stepSize)
{
    // Convert the coordinates to the new coordinate system
    double yPrime = -x * Math.Sin(thetaRadians) + y * Math.Cos(thetaRadians);
    double yTopRight = -width * Math.Sin(thetaRadians);
    double yTopLeft = 0.0;

    double dVal;
    if (thetaRadians >= 0)
        dVal = (yPrime - yTopRight) / stepSize;
    else
        dVal = (yPrime - yTopLeft) / stepSize;

    int iVal = Convert.ToInt32(Math.Floor(dVal));
    if (iVal > numSteps - 1) iVal = numSteps - 1;
    if (iVal < 0) iVal = 0;

    // Find out the gray value corresponding to this pixel
    int iGray = Convert.ToInt32(grayValues[iVal]);
    return iGray;
}  

这是一个在 Visual Studio 2008 和 C# 上开发的命令行应用程序。此应用程序的用法是

MakeSteps <filename.png> <width> <height> <numSteps> <thetaDegrees>

该程序生成一个 PNG 文件作为输出。

结论

上面解释了用于在图像中生成任意方向的灰度带的 C# 程序。从该应用程序获得的示例图像显示在本页顶部。可以看到,当步数很大时,我们得到一个具有平滑渐变的图像。该程序的设计灵感来自于 Nick Efford 的《数字图像处理》一书。 此代码可以进一步增强以包含抗锯齿。

致谢

作者要感谢 S Mahesh Reddy 和 Harsha T 为准备本文和相关的编码所做的所有努力。

历史

  • 2009 年 2 月 19 日:最初发布
© . All rights reserved.