GithubHelp home page GithubHelp logo

mdouchement / hdr Goto Github PK

View Code? Open in Web Editor NEW
37.0 4.0 4.0 221 KB

HDR is a library that handles RAW image format written with Golang

License: MIT License

Go 100.00%
hdr-image hdr golang golang-library tone-mapping tmo raw reinhard drago icam

hdr's Introduction

HDR - High Dynamic Range

GoDoc Go Report Card License

HDR is a library that handles RAW image format written with Golang. Here some rendering examples.

It aims to provide tools to read HDR files and convert it to a LDR (Low Dynamic Range, aka PNG/JPEG/etc.) in an image.Image object.

Documentations:

Supported codecs (file formats)

  • Radiance RGBE/XYZE
  • PFM, Portable FloatMap file format
  • TIFF using mdouchement/tiff
  • CRAD, homemade HDR file format

Supported tone mapping operators

Read this documentation to find what TMO use.

Read this documentation to understand what is a TMO.

  • Linear
  • Logarithmic
  • Drago '03 - Adaptive logarithmic mapping for displaying high contrast scenes
  • Durand - Fast bilateral filtering for the display of high-dynamic-range images
  • Reinhard '05 - Photographic tone reproduction for digital images
    • Playing with parameters could provide better rendering
  • Custom Reinhard '05
    • Rendering looks like a JPEG photo taken with a smartphone
  • iCAM06 - A refined image appearance model for HDR image rendering

Usage

go get github.com/mdouchement/hdr
package main

import (
	"fmt"
	"image"
	"image/png"
	"os"
	"runtime"
	"time"

	"github.com/mdouchement/hdr"
	_ "github.com/mdouchement/hdr/codec/rgbe"
	"github.com/mdouchement/hdr/tmo"
)

// Samples:
//
// http://www.anyhere.com/gward/hdrenc/pages/originals.html
// http://resources.mpi-inf.mpg.de/tmo/logmap/ (High Contrast Scenes)

var (
	// input = "/Users/mdouchement/tmp/hdr/memorial_o876.hdr"
	// input = "/Users/mdouchement/tmp/hdr/MtTamWest_o281.hdr"
	// input = "/Users/mdouchement/tmp/hdr/rend02_oC95.hdr"
	// input = "/Users/mdouchement/tmp/hdr/Tree_oAC1.hdr"
	input  = "/Users/mdouchement/tmp/hdr/Apartment_float_o15C.hdr"
	output = "/Users/mdouchement/tmp/hdr/output.png"
)

func main() {
	fmt.Printf("Using %d CPUs\n", runtime.NumCPU())

	fi, err := os.Open(input)
	check(err)
	defer fi.Close()

	start := time.Now()

	m, fname, err := image.Decode(fi)
	check(err)

	fmt.Printf("Read image (%s) took %v\n", fname, time.Since(start))

	if hdrm, ok := m.(hdr.Image); ok {
		startTMO := time.Now()

		// t := tmo.NewLinear(hdrm)
		// t := tmo.NewLogarithmic(hdrm)
		// t := tmo.NewDefaultDrago03(hdrm)
		// t := tmo.NewDefaultDurand(hdrm)
		// t := tmo.NewDefaultCustomReinhard05(hdrm)
		t := tmo.NewDefaultReinhard05(hdrm)
		// t := tmo.NewDefaultICam06(hdrm)
		m = t.Perform()

		fmt.Println("Apply TMO took", time.Since(startTMO))
	}

	fo, err := os.Create(output)
	check(err)

	png.Encode(fo, m)

	fmt.Println("Total", time.Since(start))
}

func check(err error) {
	if err != nil {
		panic(err)
	}
}

HDR Tools

https://github.com/mdouchement/hdrtool

License

MIT

Implementing a TMO

A TMO must implement tmo.ToneMappingOperator:

type ToneMappingOperator interface {
	// Perform runs the TMO mapping.
	Perform() image.Image
}

Implementing an image codec

  • Reader
// DecodeConfig returns the color model and dimensions of a PFM image without
// decoding the entire image.
func DecodeConfig(r io.Reader) (image.Config, error) {
  // ...
  return m, err
}

// Decode reads a HDR image from r and returns an image.Image.
func Decode(r io.Reader) (img image.Image, err error) {
  // ...
  return
}

func init() {
  // Register the format in the official lib.
  // https://golang.org/pkg/image/#RegisterFormat
  image.RegisterFormat("format-name", "magic-code", Decode, DecodeConfig)
}
  • Writer
// Encode writes the Image m to w in PFM format.
func Encode(w io.Writer, m hdr.Image) error {
  return nil
}

Contributing

All PRs are welcome. If you implement a TMO or an image codec in a dedicated repository, please tell me in order to link it in this readme.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

As possible, run the following commands to format and lint the code:

# Format
find . -name '*.go' -not -path './vendor*' -exec gofmt -s -w {} \;

# Lint
golangci-lint run -c .golangci.yml

hdr's People

Contributors

mdouchement avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

hdr's Issues

implementation of the fattal02 TMO

Hi, mdouchement !

Couldn't find a better way to contact you via github, apologies for raising this as an issue.

Many thanks for the hdr library ! It's been very useful for a hobby project of mine, exposure stacking eclipse photos.

Before I found your library, I implemented the fattal02 TMO in Golang. It depends on the fftw3 C library. (To be more honest, I just ported the C implementation from the pfstmo project :) Code here: https://github.com/abworrall/eclipse-hdr/blob/master/pkg/fattal02/fattal02.go

After finding your hdr library, I revised it to implement your API, and also inherit the TMOs you'd already implemented - so thanks again :)

  • Adam

[iCAM06] White adaptation with Bilateral filter is as good and faster

        // Chromatic adaptation (White adaptation) - Section 2.3
-       t.white = filter.FastGaussian(t.normalized, (t.minDim() / 2))
+       // t.white = filter.FastGaussian(t.normalized, (t.minDim() / 2))
+       wh := filter.NewYFastBilateralAuto(t.normalized)
+       wh.SigmaSpace = float64(t.minDim() / 2)
+       wh.Perform()
+       t.white = wh.HDRResultImage()

[iCAM06] Smart percentile function

In the normalize step, the percentile slice could be replaced by a smart function .
The percentile slice uses a large amount of memory for only 2 values are needed (minRGB && maxRGB).

[iCAM06] Bad White Adaptation due to StackBlur

In the paper the white adaptation is provided by a low-pass Gaussian blur.
For performance the StackBlur is used but it have some effects side in the image rendering.

hdr/tmo/icam06.go

Lines 133 to 139 in 08312e9

// FIXME StackBlur seems to have some side effects here (halo effect and red-ish image)
// l2, m2, s2, _ := hdr.NewLMSCAT02w(t.white).HDRAt(x, y).HDRPixel()
// la := 0.2 * m2
// Use generic White adaptation values
l2, m2, s2 := 1.0, 1.0, 1.0
la := 1.0

S := math.Abs(Yw) // Luminance of each pixel in the chromatic adapted image - FIXME Should be Yca according to the paper

Named package (aka no `util` package)

Replace util package with more dedicated packages.
Move also generic functions defined in filterand tmo to these new packages (e.g. filter/filter.go#clamp(...)).

Decoding reads more bytes than necessary?

Hello and thanks for your work,

I wanted to encode several HDR images into one buffer or file but then rgbe.Decode seems to read more bytes than it should and I can't figure why after reviewing your code.

Encoding and decoding once works fine though.

This, for instance, will throw an error:

rgbe.Encode(buf, img)
rgbe.Encode(buf, img)
img, e := rgbe.Decode(buf)
img, e = rgbe.Decode(buf)

More verbose:

// Encode twice the HDR image and check how many bytes were written
rgbe.Encode(buf, img)
rgbe.Encode(buf, img)
writtenBytes := buf.Len()

// No problem, the first img is fine
img, e := rgbe.Decode(buf)

// More bytes read than written though
fmt.Printf("Bytes read: %v; Bytes written: %v", writtenBytes - buf.Len(), writtenBytes)

// And this returns an invalid format error because we begin to read too far in the buffer
img, e = rgbe.Decode(buf)
if e != nil {
    log.Fatal(e)
}

Any idea why?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.