解析hdr图像文件的python实现

如题

import cv2
import numpy as np
def rgbe2float(rgbe):
    res = np.zeros((rgbe.shape[0],rgbe.shape[1],3))
    p = rgbe[:,:,3]>0
    m = 2.0**(rgbe[:,:,3][p]-136.0)
    res[:,:,0][p] = rgbe[:,:,0][p] * m 
    res[:,:,1][p] = rgbe[:,:,1][p] * m 
    res[:,:,2][p] = rgbe[:,:,2][p] * m
    return res
    
    
def readHdr(fileName = 'belgium.hdr'):
    fileinfo = {}
    with open(fileName, 'rb') as fd:
        tline = fd.readline().strip()
        if len(tline)<3 or tline[:2] != '#?':
            print 'invalid header'
            return
        fileinfo['identifier'] = tline[2:]

        tline = fd.readline().strip()
        while tline:
            n = tline.find('=')
            if n>0:
                fileinfo[tline[:n].strip()] = tline[n+1:].strip()
            tline = fd.readline().strip()

        tline = fd.readline().strip().split(' ')
        fileinfo['Ysign'] = tline[0][0]
        fileinfo['height'] = int(tline[1])
        fileinfo['Xsign'] = tline[2][0]
        fileinfo['width'] = int(tline[3])

        data = [ord(d) for d in fd.read()]
        height, width = fileinfo['height'], fileinfo['width']
        if width<8 or width>32767:
            data.resize((height, width, 4))
            return rgbe2float(data)

        img = np.zeros((height, width, 4))
        dp = 0
        for h in range(height):
            if data[dp] !=2 or data[dp+1]!=2:
                print 'this file is not run length encoded'
                print data[dp:dp+4]
                return
            if data[dp+2]*256+ data[dp+3] != width:
                print 'wrong scanline width'
                return
            dp += 4
            for i in range(4):
                ptr = 0
                while(ptr < width):
                    if data[dp]>128:
                        count = data[dp]-128
                        if count==0 or count>width-ptr:
                            print 'bad scanline data'
                        img[h, ptr:ptr+count,i] = data[dp+1]
                        ptr += count
                        dp += 2
                    else:
                        count = data[dp]
                        dp += 1
                        if count==0 or count>width-ptr:
                            print 'bad scanline data'
                        img[h, ptr:ptr+count,i] = data[dp: dp+count]
                        ptr += count
                        dp +=count
        return rgbe2float(img)
if __name__ == '__main__':
    m = readHdr()
    m1,m2 = m.max(), m.min()
    img = (m-m2)/(m1-m2)
    m1 = m[:,:,0].copy();  m[:,:,0] = m[:,:,2]; m[:,:,2]=m1
    cv2.imwrite('tmp.jpg', img*255)

  

posted @ 2016-12-03 14:20  zmshy2128  阅读(3215)  评论(0编辑  收藏  举报