1像素线条模糊不清的原因

http://www.jb51.net/html5/70312.html

 

 

上次我们讲到,canvas有时候会出现1像素的线条模糊不清且好像更宽的情况,如下图:

这样的线条显然不是我们想要的。
这篇文章的目的就是弄清楚里面的原理,以及解决它。
大家都知道屏幕上最小的显示尺寸就是1像素,虽然小于1像素的东西可能显示不出来,但计算机可不管,他会试着画一下。
其实像素终究来说也是一个单位,假如我们把画布放大到足够大,足以看清楚每个像素,会是什么情况呢?大概是这个样子:


每个像素都有起止范围,如图所示,他们的范围从左起,跨过1像素,到右止。
如果我们画1像素线条的时候,遵循像素的起止范围,那么我们肯定能得到一个很标准的细线。如下:


但遗憾的是canvas的线条画法不一样,上一篇文章我们已经说了,canvas的每条线都有一条无限细的“中线”,线条的宽度是从中线向两侧延伸的。如果我们还是从第2个像素点画一条线,那么线条的中线就会靠齐到第2个像素的起点,然后我们开始画了,问题也就来了:Canvas 的线条以中线向两侧延伸,而不是向某一边延伸(比如这里,如果只是往右侧延伸,那么我们的问题就不再是问题了),延伸过后我们的线条实际上是这样的:


此时又有个问题:计算机不允许出现小于1px的图形,所以他做了一个折中的事:把这两个像素都绘制了。
所以,如此一来,本来1px的线条,就成了看起来2px宽的线条。
失败的原因找到了:Canvas中的line把中线与像素的起点对齐了,而不是像素的中间点。
那么我们怎么解决这个蛋疼的问题?也许有人已经想到了:既然是因为两个的起点不一样,那我们就把他们的起点变得一样吧!
我们让线条的中线和像素的中间点对齐就行了!
像素的中间点很好找,比如第2像素的中间点,依据图上的解释就是1.5像素的位置,那么x像素的中间点就是(x-0.5)px。


当然,在不很严谨的场合,你使用x+0.5也是可以的。
现在我们在canvas上试试我们的研究结果。

复制代码
代码如下:

ctx.moveTo(100.5,100.5);
ctx.lineTo(200.5,100.5);
ctx.lineTo(200.5,200.5);
ctx.lineTo(100.5,200.5);
ctx.lineTo(100.5,100.5);
ctx.closePath();
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(255,0,0,0.5)';
ctx.stroke();


 


看起来对了吧?
不过貌似这样一来我们画线的时候就非常纠结,难道每次都去加这个让人郁闷的0.5?当然不是,因为我们大部分时间都是用变量保存值的,就不用给每个值加0.5 了
而且,对于lineWidth>1 的线,我们也不用管它:因为只有线条宽1px的时候,这个问题才最明显。

### Matlab 中运动模糊图像的去模糊处理 #### 原理概述 图像模糊通常由多种因素引起,其中一种常见的原因是相机或物体的相对运动造成的运动模糊。为了恢复清晰的图像,可以采用盲去卷积算法来实现图像去模糊[^1]。 #### 运动模糊方向检测 对于运动模糊图像,首先需要确定模糊的方向和长度。这一步可以通过手动测量或者自动分析完成。例如,在某些情况下,可以借助 MATLAB 自带的绘图工具绘制线条并计算角度。具体而言,通过选取特定区域中的几何形状(如三角形),能够估算出模糊方向的角度[^2]。 #### 实现步骤说明 以下是基于 MATLAB 的典型运动模糊去除流程: 1. **加载输入图片** 使用 `imread` 函数读取待处理的模糊图像。 2. **定义 PSF (Point Spread Function)** 对于已知的运动模糊参数(比如方向和距离),可以直接构建对应的点扩散函数(PSF),它描述了成像系统的退化过程。如果这些参数未知,则需先估计它们再创建合适的 PSF 模型。 3. **应用逆滤波/维纳滤波器或其他高级方法** - 维纳滤波是一种常用的技术用于减少噪声影响的同时尽可能还原原始信号;而 Richardson-Lucy 算法则属于迭代优化类别的解决方案之一,在实际效果上往往表现更佳但计算成本较高。 - 下面展示了一个简单的例子程序片段展示了如何运用 deconvwnr() 来执行维纳反褶积操作: ```matlab % 加载测试图像 I = imread('motion_blurred_image.jpg'); imshow(I); title('Motion Blurred Image'); % 创建一个模拟的PSF表示水平向右移动9像素的情况 LEN = 9; % 长度单位数代表位移量级大小 THETA = 0; % 方向角设为零意味着完全沿X轴正向平移 PSF = fspecial('motion', LEN, THETA); % 执行Wiener Deconvolution with default noise-to-signal ratio estimation. J = deconvwnr(I, PSF); figure, imshow(J), title('Restored Image using Wiener Filter') ``` 上述代码段中调用了内置函数fspecial生成指定类型的二维滤镜模板作为PSF输入给deconvwnr做进一步运算得到初步复原后的结果图像 J[]. 注意这里仅提供了一种基础方案示意目的并非详尽列举所有可能情形下的最佳实践方式因为不同场景下适用的具体算法可能会有所差异取决于目标需求精度等因素考量。 --- #### 注意事项 尽管理论模型提供了强大的工具帮助我们理解并解决这类问题,但在真实世界的应用当中仍然存在诸多挑战需要注意规避潜在风险: - 如果错误地选择了不匹配实际情况的PSF形式将会导致严重的伪影现象; - 当信噪比较低时简单依靠频域变换难以取得满意成效因此考虑引入更多约束条件改进传统方法成为研究热点领域内的活跃课题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值