面对不同的渲染算法,比如:PT、BDPT、PM、SPPM、Original MLT、PSSMLT、MMLT等等,对比不同渲染算法效果的常用方式是:相同时间下,渲染图片的质量(或者,渲染相同质量图片所需的时间)。

这里涉及到一个关键问题:怎么评估渲染图片的质量?
一般是,计算渲染图片和参考图片(标准图片)的MSE(均方误差)。

参考图片的选择要特别注意!!!
参考图片的选择要特别注意!!!
参考图片的选择要特别注意!!!
(小编正是在因为选错了参考图片然后被折磨得死去活来之后,才决定写这篇博文的)

举例说明。
假设我们要用MMLT渲染这么一个场景:
https://benedikt-bitterli.me/resources/

小编下载这个场景模型的原因是:其提供了参考图片(如果是本地自己用path tracing渲染一张参考图片的话,至少得好几十个小时吧)
具体怎么用PBRT-V3渲染这个场景,不是本篇文章的内容。此处默认已经完成渲染得到了一张渲染图片。
现在,是要根据渲染图片和参考图片的MSE判断渲染图片的质量。

下载的场景模型文件夹中包含两张参考图片,分别是:
TungstenRender.exr
TungstenRender.png
在不调节场景的几何参数时,对应的参考图片应该是来自TungstenRender.exr。

小编用的MSE程序是基于网络上找的一段python代码改的。
python貌似不能直接读取.exr文件,另外考虑到这个场景的描述文件中设置的渲染图片输出格式为.png,所以,我们将.exr格式的参考图片转换为.png格式。
Mac中的Preview软件是可以读取.exr格式的,而且可以直接将其转换为.png格式。但是,不要这么做,不要这么做,不要这么做!!!!!
这样操作得到的png参考图片和PBRT-V3产生的渲染图片是“不匹配”的,所以会导致MSE计算错误。

小编转换参考图片的具体步骤如下(敲黑板,划重点):
1,shift+cmd+4在屏幕上截一张640x360的图(考虑到:参考图片是1280x720分辨率,另外“截图”刚好是png格式),然后用Preview打开截图;
2,用Preview打开原.exr格式的参考图片,然后复制参考图片(ctrl+a,ctrl+c);
3,将1280x720参考图片粘贴到640x360的“截图”上(参考图片会自动缩小,然后调整位置使得参考图片刚好填在“截图”上)
4,Tools–>Adjust Size,将Resolution后面的数字由144改成72(此时“截图”图片即为1280x720分辨率png格式的参考图片了)

得到正确的参考图片之后,就可用如下代码计算MSE了。
(再次声明这段程序是基于网路上的python代码改的,原出处找不到了,抱歉)

import cv2def clmap(v, k, upBound):  # mul and clampval = v * kif val > upBound:return upBoundelse:return val#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_13_0_1280,720_m100_985s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_9_0_1280,720_670_9_7510s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_5_0_1280,720_750_9_7807s.png'  #
inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_11_0_1280,720_800_9_7744s.png'  ##inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_13_1_1280,720_m60_901s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_13_1_1280,720_m70_1191s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_5_1_1280,720_500_9_7898s_zlb3.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_9_1_1280,720_310_9_6843s_again,depth+2.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_9_2_1280,720_270_9_6645s_again,depth+2.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_9_2_1280,720_350_9_8416s_again,depth+2.png'  #
inImage_2 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/living-room/living-room_17_18_1_reference.png'  ##inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,0_1280,720_m100_1446s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,0_1280,720_m140_2179s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,0_1280,720_m280_3805s.png'  ##inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,1_1280,720_m50_1176s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,1_1280,720_m55_1290s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,1_1280,720_m60_1410s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,1_1280,720_m65_1520s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,1_1280,720_m70_1597s.png'  #
#inImage_1 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-10_again,1_1280,720_m100_2321s.png'  #
#inImage_2 = '/Users/libingzeng/CG/pbrt-v3/buildX/Debug/bathroom2/bathroom2-9_reference.png'  #dif_img = 'dif_' + inImage_1img_1 = cv2.imread(inImage_1)  # read as color image
img_2 = cv2.imread(inImage_2)dif = img_1.copy()
show_dif = dif.copy()  # dif image for show onlywidth = img_1.shape[0]  # get width
height = img_1.shape[1]  # get height
sum = 0for i in range(width):for j in range(height):# dif[i, j] = [128,0,0]      # b g r# print img_1[i,j]-img_2[i,j]#diff0 = float(img_1[i, j][0]) - float(img_2[i, j][0])#diff1 = float(img_1[i, j][1]) - float(img_2[i, j][1])#diff2 = float(img_1[i, j][2]) - float(img_2[i, j][2])#diff = (abs(diff0) + abs(diff1) + abs(diff2)) / 3.0y1 = img_1[i, j][2] * 0.212671 + img_1[i, j][1] * 0.715160 + img_1[i, j][0] * 0.072169y2 = img_2[i, j][2] * 0.212671 + img_2[i, j][1] * 0.715160 + img_2[i, j][0] * 0.072169diff = y1 - y2diff0 = diffsum = sum + diff ** 2if diff0 < 0:show_dif[i, j] = [0, clmap(abs(diff0), 10, 255), 0]elif diff0 > 0:show_dif[i, j] = [0, 0, clmap(abs(diff0), 10, 255)]else:show_dif[i, j] = [0]dif[i, j] = abs(diff0)mse = sum / (width * height)
print 'MSE: ', mseprint dif_img
print 'different data:'
print 'max : ', dif.max()
print 'min : ', dif.min()
print 'mean : ', dif.mean()cv2.imwrite(dif_img, show_dif)cv2.imshow('_dif', show_dif)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考图片:

渲染图片:

输出结果

从前面程序中可以看到,可视化的是第0通道(blue)的差异。
注意:
1,程序中默认通道次序是blue、green、red(和常见的rgb次序不一样)
2,一般求三个通道的MSE的方式是:分别求每个通道的MSE,然后平均。小编的求法是:对单像素点的三个通道的差异的绝对值求平均值,然后对这个平均值平方求和,最后再平均

渲染图片和参考图片的第0通道的差异图:
(绿色:差异<0;红色:差异>0;黑色:差异=0)

[PBRT-V3]怎么对比不同渲染算法的效果相关推荐

  1. 高糊视频秒变4K!Facebook发布低分辨率视频实时渲染算法,网友:是好东西,但是玩不起...

    贾浩楠 发自 凹非寺 量子位 报道 | 公众号 QbitAI 还记得那个引来巨大争议,最后把LeCun逼退推特的低分辨率图像还原算法PULSE吗? PULSE是针对低分辨率图像进行还原的,而就在PUL ...

  2. CV:人工智能之计算机视觉方向的简介(CV发展史+常用数据集+CV职位)、传统方法对比CNN类算法、计算机视觉十大应用(知识导图+经典案例)之详细攻略

    CV:人工智能之计算机视觉方向的简介(CV发展史+常用数据集+CV职位).传统方法对比CNN类算法.计算机视觉十大应用(知识导图+经典案例)之详细攻略 目录 计算机视觉的简介 1.计算机视觉的研究方向 ...

  3. MLT-type渲染算法review(笔记)

    本文是个人对当前的一些MLT-type渲染算法思路及其之间关系的简单理解.

  4. Q140:PBRT-V3,各种渲染算法(Integrator,积分器)汇总

    PBRT-V3中各种渲染算法(Integrator)汇总截图如下: 各种渲染算法(Integrator)之前的博文链接: WhittedIntegrator: Q111:PBRT-V3系统概述中的5. ...

  5. ICCV 2021 Oral | Paint Transformer - 基于笔触预测的快速油画渲染算法

    这篇专栏主要介绍我们团队(百度视觉技术部视频理解与编辑组)发表于ICCV 2021上的Oral工作:"Paint Transformer: Feed Forward Neural Paint ...

  6. 聊聊引擎底层如何实现Bloom渲染算法

    Bloom渲染是游戏中常用的,在Unity和UE4中也有Bloom渲染算法如果我们自己实现Bloom渲染算法,该如何实现呢?网上关于Bloom的实现算法讲述的也比较多,但是我们本篇实现的Bloom渲染 ...

  7. 聊聊引擎底层如何实现BRDF渲染算法

    BRDF作为比较流行的渲染算法,但凡成熟的引擎的都有此功能,我们自己写引擎也不例外,我在编写引擎时也会参考网上的一些资料,这也是学习的过程,先介绍BRDF,它是双向反射分布函数,说白了它是对于物体表面 ...

  8. Fog Volume渲染算法实现

    由于项目需求,需要实现Fog Volume的效果,查阅了网上资料没有找到相关算法介绍,Unity虽然提供了插件但是效果不是项目想要的,只能自己去写,为了便于日后查阅,写篇博客记录下来,在介绍Fog V ...

  9. javafx treeview菜单千层渲染算法

    目录 通过接口自动构建TreeView树形菜单 sql建表,预装数据 查询结果集 main函数渲染结果 核心算法源码 总结 通过接口自动构建TreeView树形菜单 进行javafx开发时候,渲染树形 ...

最新文章

  1. 如何强制“ git pull”覆盖本地文件?
  2. LeetCode Construct Binary Tree from Preorder and Inorder Traversal(构造二叉树)
  3. 爬虫简单入门:第一个简单爬虫
  4. html控件的id和name属性有什么不同
  5. 大数据之-Hadoop3.x_MapReduce_序列化案例FlowReducer---大数据之hadoop3.x工作笔记0099
  6. 用python画图代码-常用激活函数的python画图代码
  7. APP 代码提交GitHub: 提交、合并与冲突解决 (终端操作语法)
  8. 小米笔记本适合计算机专业吗,真Pro还是假专业?细说小米新笔记本电脑五宗罪...
  9. 菜鸟教程python爬虫小说_Python 爬虫介绍 | 菜鸟教程
  10. 云桥网络 unity学习素材整理合集包 可自行获取
  11. android 投屏代码,android投屏技术:控制设备源码分析
  12. 蓝桥杯 ADV-222 7-2求arccos值 java
  13. 项目的组织结构(职能型、项目型和矩阵型)
  14. Druid加载(load data)HDFS文件数据
  15. 微服务-API网关-熔断降级
  16. 谈一谈|在win10家庭版上用虚拟机安装docker
  17. win10系统激活不了?只因你忽略了这些细节!
  18. 如何删除数组中的一个元素
  19. php 上传 413,PHP CURL上传文件出现413 Request Entity Too Large
  20. 定风波·南海归赠王定国侍人寓娘

热门文章

  1. 浅析如何掌握了解SQL Server的锁机制
  2. 一个网络传输框架——zeroMQ 调研笔记
  3. Linux系统管理_附加控制权限-Redhat Enterprise 5
  4. Leetcode 931.下降路径最小和
  5. 关于使用skimage.measure.shannon_entropy计算图像信息熵的问题
  6. tensorflow实现对彩色图像的均值滤波
  7. latex中设置标题左对齐
  8. pc-H5 适配方案
  9. Day9--Python--函数入门
  10. react 生命周期函数