[置顶] 【计算机图形学】【加权区域采样】用加权区域采样的方法绘制反走样直线
2018-03-29 12:03
1006 查看
用加权区域采样的方法绘制反走样直线
我们在光栅图形显示器上绘制非水平、非垂直的直线或多边形边界时,会呈现锯齿状外观。这是因为直线和多边形的边界是连续的,而光栅则是由离散的点组成。在光栅显示设备上表现直线、多边形等,必须在离散位置采样。由于采样不充分重建后造成的信息失真,就叫走样;用于减少或消除这种效果的技术,就称为反走样。在光栅图形显示器上绘制非水平且非垂直的直线或多边形边界时,或多或少会呈现锯齿状或台阶状外观。这是因为直线、多边形、色彩边界等是连续的,而光栅则是由离散的点组成,在光栅显示设备上表现直线、多边形等,必须在离散位置采样。由于采样不充分重建后造成的信息失真,就叫走样(aliasing)。走样直线效果图:可以清晰的看到图中直线的锯齿状,并不是很笔直的直线。因此我们需要对直线进行反走样来消除锯齿达到美观的目的。基本上反走样方法可分为两类。第一类是提高分辨率 即增加采样点(提高采样频率)。另一类反走样是把像素作为一个有限区域,对区域采样来调整像素的亮度,以光顺边界来减小锯齿现象。在这里我们采用第二种方法,基于bresenham算法采用加权区域采样的方法进行反走样算法设计。
1.关于bresenham算法的简介
Bresenham 画 线 算 法 是 非 常 流 行 的 直 线 光 栅 化 生成算法。该算法具有效率高、易于硬件实现等优点。但光栅化后的直线(段)和理想的直线不同,它是有单像 素宽度的。这就使得光栅化后的直线 (水平,垂直线除外 )有 锯 齿 ,即 所 谓 的“走 样”。2.加权区域采样方法简介:
其基本思想是 ,当直线经过某像素时 ,该像素的亮度值是在直线 与像素所交 区域上对滤波函数进行积分所得到的积分值。由于求积分的运算量很大,所以可以通过选取有代表性的直线组成采样数组以减少运算量,但各像素权值的取值的准确性很难保证。本文给出了一种基于加权区域采样算法的离散化算法。加权平均的子像素划分方 法 ,并基于该技术对 Breseifla am 画 线 算 法 进 行 了 改 进 ,与传统的离散化反走样算法相比,实现效果完全相同但效率更优。3.1 像素的均匀分割
将一个像素在水平与垂直方向上均匀分割为n个 子 像 素 ,则 每 个 子 像 素 的 面 积 为 1/n 。 再 计 算 每 个子 像 素 对 原 像 素 灰 度 的 贡 献 值 ,并 保 存 在 一 张 表 (称为加权表)中。一般来说,离像素中心越近的子像素其贡献值 就大(这 和滤波 函数的特点相吻合 )。在实际应用中 ,经 常 将 一 个 像 素 划 分 为 9 个 子 像 素 ,其 加 权 表 可 取为{w1,w2,w3}. {1,2,1}{w4,w5,w6} = {2,4,2}
{w7,w8,w9}. {1,2,1}
3.2子像素中心与矩形区域位置关系的判断
因 为 一 个 像 素 宽 度 的 直 线 段 实 际 上 可 以 看 作 是 一 个宽度为 1的矩形 区域 .当直线与某一个像素相交时,关键问题是如何求得该像素的哪些子像素的中心落在矩形区域中。
设 理 想 直 线 段 的 两 个 端 点 为 Pl(X0,Y0) 和P2(X1,Y1)。则其一般方程为 k=(y1-y0)/(x1-x0);
其 中 (y-y0)/(x-x0)=k=(y1-y0)/(x1-x0); 因此,直线方程可以写为:y-(x-x0)*(y1-y0)/(x1-x0)-y0=0;
两条平行线的直线方程为:
上边界:y-(x-x0)*(y1-y0)/(x1-x0)-y0-0.5*sqrt(k*k+1)=0;
下边界:y-(x-x0)*(y1-y0)/(x1-x0)-y0+0.5*sqrt(k*k+1)=0;
由于我们把直线看作宽度为1像素的线,因此这条直线在x=某个值时最多与像素有2个相交(假设直线斜率的绝对值在0-1之间)
而且最多有三种相交情况:
1.直线穿过该像素点(x,y)和该像素点上一个像素点(x,y+1);
2.直线只穿过该像素点;
3.直线穿过该像素点(x,y)和该像素点下一个像素点(x,y-1);
因此针对上述三种相交情况:
我们可以通过以下方法判断这三个像素点的权值
1.判断像素点(x,y+1)时,这时判断(x,y+1)像素的权值只需要判断该点的9个像素分点在上边界下方的权值累加;
2.判断像素点(x,y)时,这时判断(x,y)像素的权值需要判断该点的9个像素分点在上边界下方同时在下边界的上方的权值累加;
3.判断像素点(x,y-1)时,这时判断(x,y-1)像素的权值只需要判断该点的9个像素分点在下边界的上方的权值累加;
通过以上的计算我们便可以得到响应的3个像素点的权值,我们便可以为这3个像素点亮度设置相应的值。反走样效果图:
本文的代码全部使用java语言实现,如需相应的代码,可以在评论区中留言。
相关文章推荐
- 计算机图形学(三)_图元的属性_16_ 反走样_4_直线短的区域取样
- 计算机图形学—判断点在直线上的方法
- 计算机图形学——绘制直线
- 计算机图形学—判断点在直线上的方法(转)
- 计算机图形学作业 - 运用PyOpenGL使用区域填充的递归算法(种子填充)绘制“明”字
- 计算机图形学-实验1-掌握开发环境配置方法和基本图元绘制函数
- 计算机图形学考试-绘制一条任意线型和线宽的直线。
- 计算机图形学-基于OpenGL的绘制直线及图形变换练习
- 计算机图形学-基于OpenGL的直线扫描程序
- 计算机图形学 学习笔记(三):多边形的区域填充算法,反走样算法
- 计算机图形学——生成直线的DDA算法
- 计算机图形学——光栅图形学直线算法简介
- 计算机图形学——直线的三种扫描转换算法
- 计算机图形学--多边形扫瞄转换与区域填充实现
- 图形学中的贴图采样、走样与反走样等
- 计算机图形学——绘制钻石图案
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)
- 计算机图形学之--直线生成算法(一)
- php绘制一条直线的方法
- 在区域内绘制宽字符串多行自动换行的c语言实现方法