Question: I want to read pfm format images in python. I tried with imageio.read but it is throwing an error. Can I have any suggestion, please?

`img = imageio.imread('image.pfm')`

Answer: 
The following Python 3 implementation will decode .pfm files.

Download the example [memorial.pfm](http://www.pauldebevec.com/Research/HDR/memorial.pfm) from [Paul Devebec's page](http://www.pauldebevec.com/Research/HDR/PFM/).

```
from pathlib import Path
import numpy as np
import struct

def read_pfm(filename):
    with Path(filename).open('rb') as pfm_file:

        line1, line2, line3 = (pfm_file.readline().decode('latin-1').strip() for _ in range(3))
        assert line1 in ('PF', 'Pf')

        channels = 3 if "PF" in line1 else 1
        width, height = (int(s) for s in line2.split())
        scale_endianess = float(line3)
        bigendian = scale_endianess > 0
        scale = abs(scale_endianess)

        buffer = pfm_file.read()
        samples = width * height * channels
        assert len(buffer) == samples * 4

        fmt = f'{"<>"[bigendian]}{samples}f'
        decoded = struct.unpack(fmt, buffer)
        shape = (height, width, 3) if channels == 3 else (height, width)
        return np.flipud(np.reshape(decoded, shape)) * scale

import matplotlib.pyplot as plt
image = read_pfm('memorial.pfm')
plt.imshow(image)
plt.show()

```
I am not at all familiar with Python, but here are a few suggestions on reading a `PFM` (**Portable Float Map**) file.

---

**Option 1**

The **ImageIO** documentation [here](http://imageio.readthedocs.io/en/latest/format_pfm-fi.html#pfm-fi) suggests there is a **FreeImage** reader you can download and use.

---

**Option 2**

I pieced together a simple reader myself below that seems to work fine on a few sample images I found around the 'net and generated with **ImageMagick**. It may contain inefficiencies or bad practices because I do not speak Python.

```
#!/usr/local/bin/python3
import sys
import re
from struct import *

# Enable/disable debug output
debug = True

with open("image.pfm","rb") as f:
    # Line 1: PF=>RGB (3 channels), Pf=>Greyscale (1 channel)
    type=f.readline().decode('latin-1')
    if "PF" in type:
        channels=3
    elif "Pf" in type:
        channels=1
    else:
        print("ERROR: Not a valid PFM file",file=sys.stderr)
        sys.exit(1)
    if(debug):
        print("DEBUG: channels={0}".format(channels))

    # Line 2: width height
    line=f.readline().decode('latin-1')
    width,height=re.findall('\d+',line)
    width=int(width)
    height=int(height)
    if(debug):
        print("DEBUG: width={0}, height={1}".format(width,height))

    # Line 3: +ve number means big endian, negative means little endian
    line=f.readline().decode('latin-1')
    BigEndian=True
    if "-" in line:
        BigEndian=False
    if(debug):
        print("DEBUG: BigEndian={0}".format(BigEndian))

    # Slurp all binary data
    samples = width*height*channels;
    buffer  = f.read(samples*4)

    # Unpack floats with appropriate endianness
    if BigEndian:
        fmt=">"
    else:
        fmt="<"
    fmt= fmt + str(samples) + "f"
    img = unpack(fmt,buffer)

```

---

**Option 3**

If you cannot read your `PFM` files in Python, you could convert them at the command line using **ImageMagick** to another format, such as TIFF, that can store floating point samples. **ImageMagick** is installed on most Linux distros and is available for macOS and Windows:

```
magick input.pfm output.tif

```