Channel Shuffle

Hi,

This is now in Testing > Prawnsushi > Channel Shuffle
Or: fx_chanshuff Split_Width=>0,Angle=>0,Axis=0|1,Sorting=0-25,Ordering=0|1
First image: gmic run 'sp teddy fx_chanshuff 2,60,0,16,0'




It just splits channels, splits them up in N parts and then appends everything in Shuffle or Sorting mode. With an optional rotation. :person_shrugging:
I have a question though : how can I do random width splits without getting the deadly “this image cannot be split into N parts” message? :scream:
I want the splits to be irregular in size…
Edit: oh but then how will I reconstruct the channels after shuffling uneven splits ? :face_with_raised_eyebrow:

These questions have been answered now ( see below) , thanks!

3 Likes

Please share your code, so that we can figure it out.

Without knowing what is involved: there ought to be conditionals that create pathways where the error does not emerge or at least a fallback to safe parameters. The reconstruction part may be trickier. I guess finding a way to fill the empty portions so it matches up…?

Will add it later I’m on my phone. It’s nothing to write home about though.

What maybe I could do is:

  • Split channels with a different split size for each
  • Shuffle without mixing them together so that I can :
  • Append (x) them back as 3 images ( R,G,B ) with same image dimensions
  • Split them again and shuffle the whole parts
  • Append (x) again
  • Append c

Or clone and split everything and them use a random selection to split again. Use j to paste splits on the original R,G,B channels until filled?

This basically happens when the number of parts N you specify is strictly higher than the size along the dimension of the split:

11 s x,5 # -> OK
11 s x,11 # -> OK
11 s x,12 # -> Not OK

Yes, I’ve noticed that when writing other filters (I think I even put a note about that on one of them). But I wanted to split unevenly, randomly, in one go. For example, if I split an image in 4 parts i could get such results as: 51px,17px,478px,{whatever is left} . I tried repeating splits but I always end up with not OK buddy.
Maybe i should just use +crop instead?

Yes, something like this maybe:

foo :
  sp lena

  # Random split along the x-axis in N parts.
  N=8
  l. { {$N+1},1,1,1,>u+j(-1) n. 0,{-2,w} round. repeat $N { +z[0] {1,[i[$>],i[$>+1]-1]} } rm[0,1] }

EDIT Problem with this code is that if N is high (i.e. N = width of the image), the resulting image has more columns that the original image. It requires a bit more work.

EDIT2 This is safer:

  # Random split along the x-axis in N parts.
  N=10
  +l. {
    {$N+1},1,1,1,>u+j(-1) n. 0,{-2,w} round. discard. repeat h-1 { +z[0] {1,[i[$>],i[$>+1]-1]} } rm[0,1]
  }

but it does not ensure you get exactly N parts in your split.

1 Like

Oh thanks, I’ll try to inject this in the script. I don’t think i could’ve come up with something like this :open_mouth: Now I’ll try to understand it!
The number of splits is not important, as long as width (or height) is randomized.

Transformed your code into a small command in my gmic file.
In the end I couldn’t make head or tail of what to modify to split on the Y axis with your code (append y wouldn’t look right) so for now i’ve done it the lazy way and just added a rotation before and after :

fx_rnd_split:
  # By David Tschumperlé
  foreach {
    N=$1
    l. {
     if $2 rotate 90,0,0 fi
     {$N+1},1,1,1,>u+j(-1) n. 0,{-2,w} round. discard. repeat h-1 { +z[0] {1,[i[$>],i[$>+1]-1]} } rm[0,1]
     if $2 rotate -90,0,0 fi
    }
  }


Alpha is fun too.

1 Like

Split along the Y-axis :

  {$N+1},1,1,1,>u+j(-1) n. 0,{-2,h} round. discard. repeat h-1 { +rows[0] {1,[i[$>],i[$>+1]-1]} } rm[0,1]
1 Like

Ah, you make it look so obvious ! I tried all the combinations of h and w i could think of… But didn’t think to use rows instead of crop … I thought it just could do it. Thanks!

Well yes, sorry I used z (a.k.a. crop) in my first code, but using columns would have been better. crop with only two arguments is equivalent to columns actually, and z is definitely shorter to write :slight_smile:

I think there is always room for more aliases :slight_smile: and rotate probably needs one :wink: