Lawdy. We've hardly messed with Cosine and Sine. Let's make corkscrews.
gmic -srand 78124 \ street.png \ '(1^0)' \ -resize[-1] [-2],[-2],[-1],[-1],1 \ 5,5,1,2,'2*u-1' \ -resize[-1] [-3],[-3],[-1],[-1],5 \ -orientation[-1] \ -eigen2tensor[-2,-1] \ -repeat 3 \ -smooth[-2] [-1],50 \ -done \ -rm[-1] |
|
At first glance, it may not be clear how we went about setting EigenOne, EigenTwo, Cosine and Sine.
In effect, we specified 25 random directions on a 5 by 5 grid. On resizing, we interpolated these samples over the much larger dimensions of the input image, using a cubic interpolation scheme. We got it by setting -resize’s interpolation parameter to '5'. This filled the Cosine and Sine images with smoothly varying values for each pixel, these nestled among the original 25 explicit samples. The curves manifested by -smooth are Bézier-like, which, like the interpolation used here, are grounded on cubic polynomials. Run this pipeline with other -resize interpolation schemes and see what happens! |
gmic \ -srand 78124 \ street.png \ '(1^0)' \ -resize[-1] [-2],[-2],[-1],[-1],1 \ msk.png \ -normalize[-1] 0,1 \ -mul[-2,-1] \ 5,5,1,2,'2*u-1' \ -resize[-1] [-3],[-3],[-1],[-1],5 \ -orientation[-1] \ -eigen2tensor[-2,-1] \ -repeat 3 \ -smooth[-2] [-1],50 \ -done \ -rm[-1] |
|
Despite utter chaos, some people Just Know How To Keep On Shopping. We introduce a mask (msk.png) cut to the outline of the woman in the foreground. Nothing complicated. The woman is zero bits, everything else is 255. It sets a region in the EigenOne to zero. Concomitantly, EigenTwo is entirely zero, so the region occupied by our shopper has both EigenOne and EigenTwo set to zero, and she is not blurred at all. So, generally, when both eigenvalues are zero blurring turns off. And, more generally, we may vary the overall degree of blurring by varying EigenOne and EigenTwo. To the extent they differ, directional blurring take place. |
Yea, yea, yea. We hear some of you out there telling us that all we had to do was select/float the woman off of a pristine copy and paste her onto the swirly stuff. Sure. No argument. Six of one. Half a dozen of the other. Either way, we're still cutting masks, and that's the time pig. Moreover, we're demonstrating principles here, and the principle here is: blurring is going to be no more than the larger of EigenOne or EigenTwo. Both zero. No Blur. That's the takeaway!
Instead of total chaos, we can just have streamers of chaos.
gmic -srand 78924 street.png '(1^0)' -resize[-1] [-2],[-2],[-1],[-1],1 --luminance[0] -apply_curve[-1] 0.4,0,0,63,64,127,255,191,64,255,0 -normalize[-1] 0,1 -mul[-2,-1] 5,5,1,2,'2*u-1' -resize[-1] [-3],[-3],[-1],[-1],5 -orientation[-1] -eigen2tensor[-2,-1] -repeat 3 -smooth[-2] [-1],50 -done -rm[-1] |
|
The deal here is we took the luminance of the input image and then made a gray scale mask where the midtones map to white, but shadows and highlights map to black, the digerati's classic posterization curve. The tool for this is -apply_curve, G'MIC's equivalent to GIMP's curve tool. We used this mask as a multiplier against EigenOne. EigenTwo is constant zero, so we are dealing with skinny blurring ellipses throughout. This gives rise to the hairlike swirl. The effect is something like a selective blur, with the highlights and shadows holding structure while midtones form swirling banners. |
We've been referencing the anisotropic smoothing bits for pages and pages without introducing them to you. That's because we live in Brooklyn, Noo Yawk and Why Do You Wanna Know?
OK. Got the Attitude out of the way. Here are the Anisotropic Smoothing Bits:
At the data container level, diffusion and structure tensor fields look exactly the same. The conversion from structure to diffusion tensor fields entail redirecting and rescaling vectors, but one tensor field could easily be swapped for the other and -smooth wouldn't care – it would just give you funny results and take a very long time to do it.
Along the way, there are two useful utilities.
Eigenvalues and Eigenvectors | Tensors for the Tonsorially Challenged |