华科_图形学笔记_0402_图形思维的起点_朴素的软光栅(二)_03

计算机图形学_华中科技大学_中国大学MOOC(慕课)


4.5_巧妙的区域填充

提纲

区域的定义: 指已经表示成点阵形式的填充图形,它是像素集合

一个点P的4-邻接点指的是它上下左右四个相邻的接点

一个点P的8-邻接点指的是它上下左右,左上,左下,右上,右下八个相邻的接点

填充是指从区域内的一个点开始,这个点叫种子点,由内向外将填充色扩展到整个区域内的过程

对于一个4连通边界表示区域,我们需要从区域内的一点出发,通过访问已知的4-邻接点,在不越出的前提下,遍历区域内的所有像素

8连通区域我们需要通过访问区域内的8邻接点,来遍历整个区域,这样的算法叫做边界填充算法

对于内点表示的区域,也是同样的道理,这时对应的算法叫做泛填充算法

种子填充算法

种子的定义:边界表示区域内的任意一点或者内点表示区域的任意一点

我们从种子点出发,通过邻接点寻找区域内的其它点

绘图板中的油漆桶

油漆桶点击的位置就是一个种子点

算法就从种子点(x,y)开始,检测相邻位置是否是填充颜色,如果不是就用填充色着色,并且检测它的相邻位置,这个过程延续,一直延续到检测完区域边界颜色范围内的所有像素为止

使用栈的结构来实现4连通边界填充算法

针对内点表示区域

它的输入是种子点的坐标,填充色和内部点的颜色,算法从指定的种子开始,用所希望的填充颜色赋给所有当前为给定内部颜色的像素点

类似的也是用先进后出的栈结构来实现泛填充算法,我们只需要将边界填充算法中的判断某个像素点不是边界色且未被制成多边形色改为某个像素点是内部给定的颜色,而且未被制成新的填充色即可

首选,仍然是像素种子入栈

将检查出栈像素的4邻接点改为8邻接点

8连通算法是不能填充4连通的边界表示区域的

由于在泛填充算法中不是内点颜色的像素是不会被入栈的,所以这个点没有机会被入栈,所以就不会被填色,所以也就不会被填入到区域的外部

通过沿扫描线填充水平像素段,用它代替处理四邻/八邻接点,也就是说仅仅需要将每个水平像素段的起始位置放进展,而不是要讲所有当前位置未被处理的邻接点放进站,于是就可以构造出沿扫描线填充水平像素段的4连通边界填充算法的步骤


4.6_属性-改变图元的模样

提纲 

图元的外观是由其属性来控制

对于区域来说,它的轮廓线作为线段也可以有不同属性

区域的内部还有不同的属性,比如可以用不同的颜色或者图案去填充

属性的实现,首先看颜色

线型

像素模板由0和1组成

在不同的方向生成不等长的画线

需要根据线的斜率来调整实心段和中间空白段的像素说明,从而让不同的方向生成等长的画线

这个时候应该刷子的方向

假设直线的斜率绝对值小于1的时候,刷子可以于X轴垂直,这时候叫做垂直线刷子

而当直线的斜率绝对值大于1的时候,就需要把这个刷子转换一个方向,变成与X轴平行的方向,这时候叫做水平线刷子

通常需要添加"线帽"来调整线端的形状,已给出更好的外观

需要通过在线段的端点进行额外的处理,来生成光滑连接   的粗折线

方刷子

它通过把边长为指定的线宽的正方形的中心沿着直线做平行移动来获得具有线宽的线条,显然方刷子是不用转换线条的

有时需要用一个图案进行填充

也可以指定一个特殊的纹理图案,每次要计算这个点对应到纹理图案的颜色值,再进行输出,最后这个输出效果就是进行纹理贴图的效果


4.7_必不可少的反走样

提纲

这条直线实际上是有比较明显的阶梯状或者是锯齿感。

除此之外,还会发生在图形中包含相对微小的物体的时候,这些物体,在静态图形中容易被丢弃或者是忽略,而在动画序列中,时隐时现,产生闪烁。比如这个细小的句型。由于光栅系统中表示图形的最小单位为像素。因此。光栅化的结果,就是这幅图。图形中比像素更窄的细节丢失了,我们就看不到这个句型。在下面的这个动画序列中举行,从左向右移动。当它覆盖了某些像素中心的时候,它就会显示出来。当他没有覆盖像素中心的时候,就不被显示,这样当这个矩形从左到右平缓连续运动的时候,显示出的效果却是不连续的,而是会产生闪烁现象。

因为光栅化的本质是将连续量离散化。

那么是由于直线或多边形边界的数学表示其实是连续的,但是,在光栅图形显示器中,像素却是有面积的,并不是数学中的面积为零的点。比如,数学意义上的直线上的点,是无穷小的,两个紧挨着的点之间的距离,也是无穷小的。而在点阵单元中,每个像素点是有面积的。而任意两个点之间的距离也不可能是无穷小。这样一来,走样就不可避免。因此,我们把这种用离散量表示连续量引起的失真叫做走样。同时,应该认识到走样是光栅化的必然产物。

那么为了提高图形的显示质量,需要减少或消除走样现象。那么用于减少或消除这种效果的技术就称为反走样。进行反走样的一种简单的方法是以较高的分辨率来显示对象。比如这里假设把显示分辨率在X和Y方向分别提高一倍,那么由于每个锯齿在X方向和Y方向都只有原来低分辨率时的一半,所以效果看起来肯定会好一些。但是这种改进,是以四倍的存储器代价和扫描转换时间来获得的。并且一定是会受到硬件条件的限制。另外,即使用当前的技术能达到任意的分辨率,这个方法也不可能够消除锯齿的现象。

可是受这种思想的启发,我们可以构思这样的反走样方法,如果我们在高于显示分辨率的较高分辨率下取点。然后,对几个像素的属性进行平均,得到较低分辨率下的像素属性,是否会打到一定的反走样效果呢?

那么这种技术_就称为过取样或者是后滤波。这个技术实际上是把显示器看成是比实际更细的网格来增加取样率。而后,根据这种更细的网格,使用取样点来确定每个屏幕像素点合适的亮度等级。

而反走样的另一种方法,就是根据图形对象在每个像素点上的覆盖率来确定像素点的亮度。   这种计算覆盖率的反走样技术,称为区域取样或者是前滤波。

过去样方式的一个简单实现,就是用较高的分辨率进行计算,比如在X和Y方向上都把分辨率提高一倍。那么每个像素,就可以对应这样的四个子像素了。 然后扫描转换就求得个子像素的颜色亮度。之后,再对四个像素的颜色亮度进行平均,就可以得到较低分辨率下的像素的颜色亮度了。由于像素中可以供选择的子像素的个数是四。所以像素的亮度级别,就是五级,其实也就是从零到四。

那么这里编号为一和七的像素的亮度级别?是一,编号为2345和六的像素亮度级别,就是二。

 这样的一种方法,使得锯齿感强的地方亮度低一点,从而减弱我们看到的锯齿感。

在office中有时候就可以看到这样的处理,同样斜率的直线,Office中一般比Windows的绘图板中绘制的直线显得要平滑一些,就是因为它在软件中进行了相应的反走样处理。

可是这种方法有一个缺陷,就是相邻的像素之间不互相影响,这样一来,就容易产生色泽不均匀的问题。因此,人们又提出了一种过取样的方法

假设这个显示器的分辨率为M乘以N,其中呢M等于四,N等于三,所以,首先就把显示的窗口划分成了2M加一乘以2N加一个子像素,然后通过扫描转换求得各子像素的颜色值,在对位于像素中心及四周的九个子像素的颜色进行平均。最后就可以得到显示像素的颜色亮度了。相邻点的这个像素模板之间是有重复的子像素的,所以这样一来,相邻像素间就可以互相影响了。这样的话就可以比较好的避免色泽不均匀的问题

那么考虑到接近于像素区域中心的子像素,再决定像素的颜色亮度值中应该发挥更重要的作用。那么这种过取样的方法还经常采用加权平均的方法来计算。比如这里的三个模板都是中心像素的。全职更高,上下左右的四支儿,四个角上的子像素,他的全职更低。实践证明,这种方案对于改进图形的质量有更好的效果。

那么另一种反走样的思想?就是区域取样。

那么在扫描转换的算法中,都是假定像素是数学上的一个点,但实际上像素并不是一个点,而是一个有限区域。

所以屏幕上所画的直线不是数学意义上的没有宽度的理想线段,而是一个宽度至少为一个像素单位的线条。比如这里一条直线实际上就是一个矩形。那么在这个含义下绘制这个直线段,所有与其相交的像素都可以采用适当的亮度来进行显示。

具体通过将每个像素的亮度设置成与线条部分重叠的区域的面积成正比,就可以完成对直线的区域取样。也就是说,如果一个像素与线条的部分重叠,根据重叠区域面积的大小来选择不同的亮度,充电面积大,这个像素,就更亮一些。重叠面积小,这个像素就更暗一些。这种方法,就会产生模糊的边界,以此来减轻锯齿的效应。

在这个方法中,起关键作用的就是计算直线段与像素相交区域的面积。那么如何来计算这个面积?一般可以根据直线的斜率K和直线的精确起点位置来算出。如果已知直线的精确起点,就可以得到图中的D这个值。大家看看利用D和直线的斜率K,就可以得到重叠区域的面积。比如这个三角形面积就是1/2的D乘以D除以K。

类似的,也可以算出右边这幅图中的重叠区域,这是一个梯形,我们也可以算出这个梯形的面积。

为了简化计算?也可以利用一种求相交区域的近似面积的离散计算方法。

这时候,需要把屏幕像素分割成N个更小的子像素,然后计算中心落在直线段内子像素的个数M。那么这时候,N分之M就是线段与像素相交区域面积的近似值了。可是这样一来,就又变成之前的过取样方法。

再来分析一下这种简单取样方法的特点。

第一个,是直线段对一个像素亮度的贡献,与两者的重叠区域的面积是成正比的。

第二个,相同面积的重叠区域对像素的贡献是相同的。可是,与这个重叠区域落在像素内的位置无关。

我们会发现,在重叠面积相同的时候,直线段的中心距离这个像素点的距离是不同的,比如这两幅图。我们会认为,当距离近的时候,其实对这个像素点的影响应该更大

其实,从取样理论的角度,刚才的区域取样的方法相当于使用了这里的立方体滤波。

如果改为圆锥和高斯滤波,以这里的圆锥滤波器为例过滤函数是一个圆锥,圆锥的底面圆中心在当前像素的中心。底圆的半径为一个像素单位,锥高为1,当值线条经过这个像素的时候,这个像素的灰度值是在两者重叠区域上对滤波器进行积分的一个积分的值。相当于,使用过直线条的两边缘且垂直于像素区域的一对平面切割这个圆锥所得到的三维物体的一个体积。

这样一来,大家就会发现了,即便重叠的面积是一样大的。那么你靠近中心切割的和远离中心切割的。得到的体积是不一样的,于是,我们就会给靠近直线中心的像素点分配更高的亮度值。

另外一个就是刚才这样一种方法中,相邻两个像素的滤波器是相交的,所以,直线条经过这个相交区域的时候,对这两个像素都会分配适当的亮度值,这有利于缩小直线条相邻像素的一个亮度差。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值