Here we’re assuming equi-angular projection, and once we figure out pixel/arcmin for our image we can apply the standard deviation from the paper as pixel radius (-r) to pfilt. Lorentian with FHWM=11 roughly mapped to standard deviation of 5.7 for gaussian. We(Greg) also added two additional blur at larger radius and weighted them at end to have a better fit to the lorentian (I guess?)
In Radiance, the actual blurring is done in pfilt. Here I have the equivalent Python script, maybe you can try the it on windows: python blur.py test.hdr out.hdr
import argparse
import math
import os
import subprocess as sp
import sys
import tempfile
def pgblur(radii, inp):
reduc = math.floor(radii / 1.8)
if reduc <= 1:
return sp.run(["pfilt", "-1", "-r", str(radii), inp], check=True, stdout=sp.PIPE).stdout
filt = radii / reduc
dims = sp.run(['getinfo', '-d'], input=inp.encode()).stdout.split()
pfilt1 = sp.run(['pfilt', '-1', '-x', f"/{reduc}", '-y', f"/{reduc}", inp], check=True, stdout=sp.PIPE)
pfilt2 = sp.run(['pfilt', '-1', '-r', str(filt), '-x', dims[3], '-y', dims[1]], input=pfilt1.stdout, check=True, stdout=sp.PIPE)
return pfilt2.stdout
def humanblur(inp):
"""Simulate Lorentzian function with FWHM=11"""
header = sp.run(['getinfo', inp], check=True, stdout=sp.PIPE).stdout
view_line = [l for l in header.decode().splitlines() if l.strip().startswith('VIEW=')][0]
parser = argparse.ArgumentParser()
parser.add_argument('-vh', type=float)
args, _ = parser.parse_known_args(view_line.split())
vhoriz = args.vh
out = sp.run(['getinfo', '-d', inp], check=True, stdout=sp.PIPE).stdout.decode().split()
rhoriz = int(out[4])
pparcmin = rhoriz / (60 * vhoriz)
rad = 5.7 * pparcmin, 22.6 * pparcmin, 42.4 * pparcmin
if rad[1] >= 10 or rad[1] < 1:
raise ValueError("Input image is too small")
if rad[0] >= 10 or rad[0] < 1:
with tempfile.TemporaryDirectory() as td:
blur1 = os.path.join(td, "blur1")
blur2 = os.path.join(td, "blur2")
with open(blur1, 'wb') as tmp:
tmp.write(pgblur(rad[1], inp))
with open(blur2, 'wb') as tmp2:
tmp2.write(pgblur(rad[2], inp))
proc = sp.run(['pcomb', '-s', '.85', '-o', inp, '-s', '.11', '-o', blur1, '-s', '.04', '-o', blur2],
check=True, stdout=sp.PIPE)
return proc.stdout
else:
with tempfile.TemporaryDirectory() as td:
blur1 = os.path.join(td, "blur1")
blur2 = os.path.join(td, "blur2")
with open(blur1, 'wb') as tmp:
tmp.write(pgblur(rad[1], inp))
with open(blur2, 'wb') as tmp2:
tmp2.write(pgblur(rad[2], inp))
blur0 = pgblur(rad[0], inp)
proc = sp.run(['pcomb', '-s', '.85', '-o', '-', '-s', '.11', '-o', blur1, '-s', '.04', '-o', blur2],
check=True, input=blur0, stdout=sp.PIPE)
return proc.stdout
if __name__ == "__main__":
with open(sys.argv[2], 'wb') as out:
out.write(humanblur(sys.argv[1]))