0

So I found a code on Github that can convert pfm grayscales images to png ones. The problem with this code is that it's not working on colourful images.

Here is an image sample that I wanna convert to a png extension : https://drive.google.com/file/d/16yP987otoCyOX-ail22Aru2AltnSa1hR/view?usp=sharing It's a link cause I can't upload pfm images :)

The link to the original code : https://github.com/MahdiGhiasi/DepthEstimationProject/blob/master/pfm2png/pfm2png_depth.py

from PIL import Image
import numpy as np
import colorsys
import sys
import re
import os
def readPFM(file):
    file = open(file, 'rb')

    color = None
    width = None
    height = None
    scale = None
    endian = None

    header = file.readline().rstrip().decode('utf-8')
    if header == 'PF':
        color = True
    elif header == 'Pf':
        color = False
    else:
        print(header)
        raise Exception('Not a PFM file.')

    dim_match = re.match(r'^(\d+)\s(\d+)\s$', file.readline().decode('utf-8'))
    if dim_match:
        width, height = map(int, dim_match.groups())
    else:
        raise Exception('Malformed PFM header.')

    scale = float(file.readline().rstrip().decode('utf-8'))
    if scale < 0: # little-endian
        endian = '<'
        scale = -scale
    else:
        endian = '>' # big-endian

    data = np.fromfile(file, endian + 'f')
    shape = (height, width, 3) if color else (height, width)

    data = np.reshape(data, shape)
    data = np.flipud(data)
    return data, scale, color

def writePFM(file, image, scale=1):
    
    file = open(file, 'wb')

    color = None

    if image.dtype.name != 'float32':
        raise Exception('Image dtype must be float32.')
      
    image = np.flipud(image)  

    if len(image.shape) == 3 and image.shape[2] == 3: # color image
        color = True
    elif len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1: # greyscale
        color = False
    else:
        raise Exception('Image must have H x W x 3, H x W x 1 or H x W dimensions.')

    file.write('PF\n' if color else 'Pf\n')
    file.write('%d %d\n' % (image.shape[1], image.shape[0]))

    endian = image.dtype.byteorder

    if endian == '<' or endian == '=' and sys.byteorder == 'little':
        scale = -scale

    file.write('%f\n' % scale)

    image.tofile(file)
def save_depth_image(result, image_path):
    
    height = len(result)
    width = len(result[0])

    maxVal = np.max(result)

    #print("width:", width)
    #print("height:", height)

    output = []
    for i in range(height):
        row = []
        for j in range(width):
            h = 240 * result[i][j] / maxVal;
            (r,g,b) = colorsys.hsv_to_rgb(h / 360,1,1)
            #color = (int)(255 * result[j][i] / maxVal)
            row.append([int(r * 255), int(g * 255), int(b * 255), 255])
        output.append(row)

    img = Image.fromarray(np.asarray(output).astype(np.uint8), mode='RGBA')
    
    img.save(image_path, "PNG")
def normalize(data):
    
    maxVal = np.max(data)

    print("maxVal:", maxVal)

    data = data / maxVal
    data = 1 - data
    data *= 90

    return data
file_name = input("pfm file?\n")

data, scale, color = readPFM(file_name)

data = normalize(data)

if color:
    print("Not a depth file")
else:
    save_depth_image(data, 'pfm2png_depth.png')
    os.startfile('pfm2png_depth.png')

TTT
  • 11
  • 1
  • 1
  • 4
  • 2
    Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Alex B May 17 '22 at 08:48

1 Answers1

0

no need to roll code for this:

import cv2
img = cv2.imread("img.pfn", cv2.IMREAD_UNCHANGED) # it's float32 !
img /= 255 # back to [0..255]
cv2.imwrite("img.png", img)
berak
  • 1,226
  • 2
  • 5
  • 7
  • It's not that simple, pfm images are so complicated to deal with & I tried your suggestion but it's not working, did you by any chance tried to convert it using my image https://drive.google.com/file/d/16yP987otoCyOX-ail22Aru2AltnSa1hR/view ? – TTT May 17 '22 at 12:16
  • yep i tried your image. however, i did not look at the result (which is all white !) – berak May 17 '22 at 12:49
  • please see updated answer (cv2.IMREAD_UNCHANGED , scaling) – berak May 17 '22 at 13:00
  • Same, still not working & the fact that you got a white image, it's because the conversion to a png image didn't work properly ! – TTT May 17 '22 at 14:15
  • From what I understand, we have to pass from the code that I put in the section above & also there is a missing piece wish concerned the RGB pfm images ! – TTT May 17 '22 at 14:30
  • If there is someone who knows about "demosaicing" on python and all those stuff, maybe we can then resolve this issue & Thank you to everyone who's jumping into this, really appreciate you all. – TTT May 17 '22 at 14:35