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

my python implementation #2

Closed
iperov opened this issue Nov 12, 2019 · 9 comments
Closed

my python implementation #2

iperov opened this issue Nov 12, 2019 · 9 comments

Comments

@iperov
Copy link

iperov commented Nov 12, 2019

RGB:
2019-11-12_07-51-00

LAB , processing whole lab, but transferring only AB:
2019-11-12_08-04-10

import numpy as np
from numpy import linalg as npla
import cv2
def CTSOT(src,trg, steps=10, batch_size=5, reg_sigmaXY=16.0, reg_sigmaV=5.0):
    """
    Color Transform via Sliced Optimal Transfer, ported by @iperov

    src         - any float range any channel image
    dst         - any float range any channel image, same shape as src
    steps       - number of solver steps
    batch_size  - solver batch size
    reg_sigmaXY - apply regularization and sigmaXY of filter, otherwise set to 0.0
    reg_sigmaV  - sigmaV of filter
    
    return value - clip it manually
    """
    if not np.issubdtype(src.dtype, np.floating):
        raise ValueError("src value must be float")
    if not np.issubdtype(trg.dtype, np.floating):
        raise ValueError("trg value must be float")

    if len(src.shape) != 3:
        raise ValueError("src shape must have rank 3 (h,w,c)")
    
    if src.shape != trg.shape:
        raise ValueError("src and trg shapes must be equal")    

    src_dtype = src.dtype        
    h,w,c = src.shape
    new_src = src.copy()

    for step in range (steps):
        advect = np.zeros ( (h*w,c), dtype=src_dtype )
        for batch in range (batch_size):
            dir = np.random.normal(size=c).astype(src_dtype)
            dir /= npla.norm(dir)

            projsource = np.sum( new_src*dir, axis=-1).reshape ((h*w))
            projtarget = np.sum( trg*dir, axis=-1).reshape ((h*w))

            idSource = np.argsort (projsource)
            idTarget = np.argsort (projtarget)

            a = projtarget[idTarget]-projsource[idSource]
            for i_c in range(c):
                advect[idSource,i_c] += a * dir[i_c]
        new_src += advect.reshape( (h,w,c) ) / batch_size

    if reg_sigmaXY != 0.0:
        src_diff = new_src-src
        new_src = src + cv2.bilateralFilter (src_diff, 0, reg_sigmaV, reg_sigmaXY )
    return new_src
@dcoeurjo
Copy link
Owner

Great, thanks for sharing the code!
Would you kind to create a PR so that this python version would be available in the repo ?
(You’d need to set proper license / copyright information)

@dcoeurjo
Copy link
Owner

Ping @iperov , can I reuse your code ?

@iperov
Copy link
Author

iperov commented Nov 21, 2019

of course you can.
Do what you want.

@dcoeurjo
Copy link
Owner

Would you have an affiliation ? I can also simply use your GitHub login..

@iperov
Copy link
Author

iperov commented Nov 21, 2019

why? just commit the code.

@dcoeurjo
Copy link
Owner

To credit the author

@iperov
Copy link
Author

iperov commented Nov 21, 2019

I don't need it :)
enough "thanks to @iperov" :D

@dcoeurjo
Copy link
Owner

😊👍

@dcoeurjo
Copy link
Owner

done, thx

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

2 participants