algorithmimage-processingphotoshop

How is the photoshop Crosshatch filter implemented?


Photoshop has a lot of cool artistic filters, and I'd love to understand the underlying algorithms.
One algorithm that's particularly interesting is Crosshatch filter.
Is there any source for technical descriptions of the Photoshop filters? Alternatively, do you have any thoughts about how this particular filter might be implemented? enter image description here

enter image description here


Solution

  • You can do something like a Photoshop crosshatch with a 2D convolution with OpenCV in Python:

    #!/usr/bin/env python3
    
    import cv2 as cv
    import numpy as np
    
    # Load image
    im = cv.imread('bird.png')
    
    # Define +/- 45 degree kernel, change length to taste
    len=11
    kern = np.eye(len, dtype=np.float32)
    kern = np.maximum(kern, kern[:,::-1]) / ( 2 * len)
    print(kern)
    
    # Apply 2D convolution to image
    res = cv.filter2D(im, -1, kern)
    
    # Save result
    cv.imwrite('result.png', res)
    

    enter image description here


    If I change the length of the convolution kernel to 6, you can see its shape and content better. It is basically the sum of two diagonal matrices:

    [[0.08333334 0.         0.         0.         0.         0.08333334]
     [0.         0.08333334 0.         0.         0.08333334 0.        ]
     [0.         0.         0.08333334 0.08333334 0.         0.        ]
     [0.         0.         0.08333334 0.08333334 0.         0.        ]
     [0.         0.08333334 0.         0.         0.08333334 0.        ]
     [0.08333334 0.         0.         0.         0.         0.08333334]]
    

    If, instead of opening your image, I just create a 400x400 black image and place a single white dot at the centre, then do the convolution, you will see what it does:

    #!/usr/bin/env python3
    
    import cv2 as cv
    import numpy as np
    
    # Create square black image with a single white pixel in the middle
    im = np.zeros((400,400), dtype=np.uint8)
    im[200,200] = 255
    
    # Define +/- 45 degree kernel, change length to taste
    len=24
    kern = np.eye(len, dtype=np.float32)
    kern = np.maximum(kern, kern[:,::-1]) / ( 2 * len)
    print(kern)
    
    # Apply 2D convolution to image
    res = cv.filter2D(im, -1, kern)
    
    # Save result
    cv.imwrite('result.png', res)
    

    enter image description here