After dis- and reassembling my E4 to clean my dusty sensor, the visual and thermal images were shifted against each other, making MSX useless for me. This problem is now solved and here comes a short howto, in case someone else faces the same challenge.
Warning: It involves messing with the calibration file unique to your cam, so 1) know what you're doing and 2) have a backup!
Taucher posted some registers which can be modified by rset:
https://www.eevblog.com/forum/testgear/flir-e4-thermal-imaging-camera-teardown/msg327178/#msg327178This way you could realign your MSX image by adjusting xpanVal and ypanVal, unfortunately I was not able to make it persistent. But since the parallax error depends on the distance to the object to be imaged, it wouldn't have helped anyway.
For a given userDistance
z the shift
d ((x,y)panVal = floor(
d)) between visual and thermal image is calculated by
d(z) = c1 + c0/z (1)
with
c0 and
c1 being constant values that are factory calibrated into your cam.
d,
c0 and
c1 are 2-dimensional (x,y), units are [px] for
d and
c1, [m] for
z and [px*m] for
c0. The coordinate system starts with (0,0) in the upper left corner,
d is the shift of the visual image relative to the thermal image (see below for example).
The constants
c0 and
c1 are provided by \FlashFS\system\calib.rsc, here are mine:
...
.calib.visual.fusion.leExFOL7.C0X double -0
.calib.visual.fusion.leExFOL7.C0Y double 8.1835451
.calib.visual.fusion.leExFOL7.C1X double -8.0483421
.calib.visual.fusion.leExFOL7.C1Y double -2.2975248
...
There are more parameters important for MSX (zoom, rotation, ...), but I didn't need to touch them. So I'm only covering horizontal and vertical shift here.
You have at least two options to calculate new constants for your calibration file:
1) You could set these four parameters to zero, copy the resulting file with a new CRC32 back to the cam, overwriting the original one (keep a backup!) and reboot the E4. To recalculate new values for
c0 and
c1 you need to get at least two MSX images A and B with some distance between them, determine
dA(
zA) as well as
dB(
zB) and solve the system of linear equations to:
c0 = (dA - dB)/(1/zA - 1/zB) (2)
c1 = (dA*zA - dB*zB)/(zA - zB) (3)
Hint for the sign of
d: if your visual image appears 5px to the top and 3px to the left of your thermal image, then
d = (-3px, -5px).
Note that you don't need to configure
z in the cams settings for this, with
c0=
c1=(0,0) while measuring, (x,y)panVal will be 0 for all
z as well.
2) I found it easier to use rset to modify xpanVal and ypanVal (see Tauchers post) on my connected E4, until my MSX images looked the way I wanted. You may want to temporarily disable auto calibration while doing this or wait for the cam to settle.
I started with a very distant object, in my case it was a street light about 50m away, a building front with windows will also work. Now you already have
c1, because
c1 =
d for large
z. Then you need a second image of a nearby object, it should be small and centered in your image to minimize error. I used my doors peep hole at about 25cm away and adjusted (x,y)panVal and the distance to get a proper fit. Now you can use equation (1) to get
c0.
My new calibration file obtained by 2) worked great, at least indoors, distant objects were still off by 3px. Reason: the configurable userDistance in the cams settings ends with ">3" (cam uses
z=3m then), which makes it impossible to reach
c1 for infinity. I decided to overcorrect my parameters and used my obtained
c1 as if it were
dA at
zA=3m and calculated new constants with (2) and (3). Now I have perfect MSX even for great distances, while indoors my actual
z slightly differs from the configured userDistance. However, I think it would be a better solution to have additional menue entries for greater distances (e.g. ">10").
Another thing worth mentioning: The cam doesn't round() the result for (x,y)panVal, it just chops off everything following the decimal point. So if your
dy results to 5.99px at
z=3m you'll end up with a 5px shift being used. You may want to adjust the constants to avoid this and could use rls .image.fusion to see the actual values the cam is using.
Some additional information about MSX can be found in patent EP2634747:
https://data.epo.org/publication-server/rest/v1.0/publication-dates/20130904/patents/EP2634747NWA1/document.pdf