Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Example of a simple conversion #1

Open
bryab opened this issue Apr 22, 2020 · 7 comments
Open

Question: Example of a simple conversion #1

bryab opened this issue Apr 22, 2020 · 7 comments

Comments

@bryab
Copy link

bryab commented Apr 22, 2020

Hi, I'd like to use your library to convert some images from one colorspace to another. Most of this is a bit over my head. Would you mind providing an example of a simpler conversion?

I'd like to, for example, take an RGB pixel, defined by 3 float16 values, and convert it from "P3_D65", without transfer function (linear), to "sRGB" colorspace, with the sRGB gamma.

Thank you!

@anderslanglands
Copy link
Owner

Hi there! First thing you'll need to do is get your RGB pixel as an RGBf32, then:

let pix_p3: RGBf32 = px_f16.into();
let mtx = transform::rgb_to_rgb_matrix(&model_f32::DCI_P3_D65, &model_f32::sRGB);
let pix_srgb_linear = mtx * pix_p3;
let pix_srgb = model_f32::sRGB.encode(pix_srgb_linear);

That should work. I'm typing this from memory as I'm unable to use my dev machine right now. Let me know how you get on!

@kubo-von
Copy link

Heya! Chiming in because I'm after something something similar.

I've used the code above and it works for me with modifications.

let aces_cg: RGBf32 = RGBf32::new(sampled[0],sampled[1],sampled[2]); let mtx = transform::rgb_to_rgb_matrix(&color_space_rgb::model_f32::ACES_CG, &color_space_rgb::model_f32::SRGB); let srgb_linear = mtx * aces_cg; let srgb = color_space_rgb::model_f32::SRGB.encode(srgb_linear);

I'm trying to take output from a renderer in acesCG and display it as a srgb image in renderview. It works but I'd like to also get that nice nice highlight sofclip that DCCs have when using aces_cg in renderview, I guess there's some transfer function I'm missing ?

Thanks a lot!

PS: I've had some trouble with colorspace-rs printing few lines for every converted pixel which slowed the process a lot. I commented lines 122, 123, 136 and 141-143 in chromatic_adaptation.rs, rebuild and it was fine.

@anderslanglands
Copy link
Owner

Hi! thanks for that. Yes there's some print statements here and there I'm using while developing that I should get rid of.

To your question - yes, what you're after requires implementing the RRT, which I haven't done yet since in my main use case I'll be putting images through Nuke and can do whatever grading looks I want there. Shouldn't be too hard to add though I'll add it to the list.

@kubo-von
Copy link

kubo-von commented May 1, 2020

Ah right!
Awesome ! will try to hack together some "filmic" curve until then. Thanks for the answers!
Cheers

@kubo-von
Copy link

kubo-von commented May 2, 2020

Hi Anders!
I'd like to hijack this thread one more time for another question.
I'm trying to implement spectral sampling for my toy renderer. So I'd like to have a way to get RGB color from single wavelenght. I've tried to implement it based on your hero sampling example, but as there's lot of going on there and I'm new both to colorimetry and rust, I'm probably missing something again.
Here's a code evaluated for each pixel, that i was hoping would give me the full spectral rainbow

    let xf_xyz_to_srgb: colorspace::math::Matrix33::<f64> = transform::xyz_to_rgb_matrix(color_space_rgb::model_f64::SRGB.white, &color_space_rgb::model_f64::ACES_CG);
    let x_bar =  interpolation::InterpolatorSprague::<f64>::new(&cmf::CIE_1931_2_DEGREE.x_bar);
    let y_bar =  interpolation::InterpolatorSprague::<f64>::new(&cmf::CIE_1931_2_DEGREE.y_bar);
    let z_bar =  interpolation::InterpolatorSprague::<f64>::new(&cmf::CIE_1931_2_DEGREE.z_bar);

    let gradient: f64 = (i as f64/1280.0)*380.0+350.0; //i is horizontal pixel number in my 1280x720 window
    let sample_xyz = xyz::XYZf64::new(
        x_bar.evaluate(gradient),
        y_bar.evaluate(gradient),
        z_bar.evaluate(gradient),
    );

    //xyz to AcesCG RGB
    let rgb = transform::xyz_to_rgb(&xf_xyz_to_srgb,sample_xyz);

But I get something like this:
Screenshot from 2020-05-02 21-06-17
Any idea where I might be going wrong about this?

Thanks!

EDIT: After digging a bit more into this a reading some more about Manuka, I've tried to create 3 SPDs for R,G,B based on Arri Alexa spectral response data I found online, and use them to generate the RGB color directly and it seems to work surprisingly well! Not sure yet what primaries the data I'm getting have, or how to properly deal with intensity though.

@anderslanglands
Copy link
Owner

Hi there! Sorry for the late reply. I haven't had a chance to look at this yet. In principle what you're doing doesn't look immediately wrong but there's probably some normalization or out-of-gamut-type thing going on.

@kubo-von
Copy link

Hey! No worries, I figured a way around yesterday: I grabbed XYZ CMF data from here:
http://cvrl.ioo.ucl.ac.uk/cmfs.htm, created SPDs fro x,y and z based on that and use them to get the XYZ coordinates, then fed it into xyz::XYZf64::new, seems to works well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants