python - 与 Photoshop 相比,OpenCV Warpaffine 的质量较低

标签 python c++ image opencv image-processing

我想使用 OpenCV 的 cv2.warpAffine 函数从 CelebA 图像(1024x1024 大小)转换和对齐检测到的人脸(320x240 大小),但转换后图像的质量明显低于我使用时的质量尝试在 Photoshop 中手动对齐:(左图由 Photoshop 变换,右图由 OpenCV 变换)

Left Image Is Transformed By Photoshop & Right Image Is Transformed in OpenCV

我使用了 OpenCV 的所有插值技术,但它们的质量都无法与 Photoshop 相媲美。

我使用的代码是:

warped = cv2.warpAffine(image, TRANSFORM_MATRIX, (240, 320), flags=cv2.INTER_AREA)

可能是什么问题导致转换后的图像质量如此之低?

这是一个Link如果需要,可以转换为原始 1024x1024 图像。

最佳答案

问题及一般解决方案

您正在对信号进行下采样。<​​/p>

方法始终相同:

  • 低通滤波器去除高频成分
  • 重新采样/抽取

不该做什么

如果您进行低通处理,就会出现混叠。你注意到了这一点。混叠意味着采样步骤可能完全错过一些高频分量(边缘/角/点/...),从而产生那些奇怪的伪影。正确重新采样的图像不会完全丢失如此高频的特征。

如果您在重采样之后进行低通,它不会解决问题,只会隐藏它。损害已经造成。

如果您对一些强烈对比的线条的规则网格进行下采样,您可以让自己相信这两个方面。尝试交替使用黑白单像素线以获得最佳效果。

实现

PIL 等库在重采样之前隐式执行低通处理。

OpenCV 没有(一般来说)。即使使用 Lanczos 插值(在 OpenCV 中),您也无法跳过低通,因为 OpenCV 的 Lanczos 具有固定系数。

OpenCV 具有INTER_AREA,这是一种线性插值,但它另外对所有像素进行求和。在角样本之间的区域(而不是仅对这四个角进行采样)。这可以省去额外的低通步骤。

这是cv.resize(im, (240, 240), interpolation=cv.INTER_AREA)的结果:

resize

这是 cv.warpAffine(im, M[:2], (240, 240), interpolation=cv.INTER_AREA)M = np.eye(3) 的结果* 0.25(等效缩放):

warpAffine

看来warpAffine无法执行INTER_AREA。这对你来说很糟糕:/

如果您需要使用 OpenCV 进行下采样,并且它是2的幂,您可以使用pyrDown。这会进行低通和抽取……因子为两倍。重复应用会给你更高的力量。

如果您需要任意下采样,并且出于某种原因不喜欢 INTER_AREA,则必须对输入应用 GaussianBlur。西格玛需要与比例因子成(反)比例。高斯滤波器的西格玛和所得截止频率之间存在某种关系。如果您不想任意选择一个值,您将需要进行更多调查。查看pyrDown的内核,以及它最匹配的高斯西格玛。对于比例因子 0.5 来说,这可能是一个不错的值,其他因素应该成(反)比例。

对于简单的缩小,一个高斯模糊就可以了。对于仿射扭曲和更高的变换,您需要应用低通,以尊重所查找的每个像素的不同比例,因为它们在源图像中的“支持”不再是正方形,甚至可能不是矩形,而是任意四边形!

我没有说什么?

这适用于向下采样。如果您向上采样,请不要低通。

关于python - 与 Photoshop 相比,OpenCV Warpaffine 的质量较低,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69972016/

相关文章:

python - 将位作为位写入文件

python - 使用 Sklearn 计算 ROC 曲线下的面积?

python - 错误: Classification metrics can't handle a mix of multiclass-multioutput and multilabel-indicator targets

c++ - 在 Linux 上优化 WebKit 中的动画性能

c++ - Excel 自动化。如何复制多个单元格?

c++ - 从 DLL 导出静态库符号

css - 背景图片不显示 CSS

python - 如何从Deno运行Python脚本?

html - 水平显示无序列表

javascript - JQuery 中有什么方法可以更改图像的一部分吗?