生成条带图像






4.50/5 (9投票s)
本文介绍了如何在 C# 中生成包含任意角度的马赫带的图像。


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

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

当角度变为 90 度时,不能使用此公式,但可以轻松计算出等效距离。
AE 的距离被分成等间距的间隔,并且每个这样的间隔都被分配一个灰度值,这些灰度值以相等的间隔从 0 增加到 255,具体取决于用户指定的步数。
现在,考虑图像中的一个通用像素 (x, y),需要为该像素分配一个灰度值。如果我们将 (x, y) 转换为以 theta 角定向的新坐标系 (x', y'),则很容易分配此灰度值,如上图所示。两个坐标系之间的变换方程是

有了这个,确定灰度值就变得很简单了。
Using the Code
程序的输入是 width
、height
、numSteps
和 theta
。生成图像的步骤是
- 创建一个包含灰度值的数组(该数组的维度为
numSteps
)。 - 计算距离 AE,并计算步长 - 也就是一个带的
width
。当然,需要处理角度变为 90 度或负数的特殊情况。这部分代码如下所示。 - 形成位图 - 这涉及到计算位图中每个像素的灰度值。函数
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 日:最初发布