augraphy icon indicating copy to clipboard operation
augraphy copied to clipboard

Add new augmentation - Leaky Ink Effect

Open kwcckw opened this issue 3 years ago • 18 comments

I came across several images with effect looks like ink is leaking into the paper, and usually the effect is at the borders or edges of paper. Probably we can add this effect too?

Example: img_301 img_137174

A more severe ink leaking example: img_136996

Please suggest a better name for this augmentation too.

kwcckw avatar Aug 25 '21 08:08 kwcckw

This effect appears all the time, especially in scans of faxes of old documents.

I think this can probably be a part of BadPhotoCopy, but we can start by developing it separately. For now, we could use BadFax for the name, to fit BadPhotoCopy.

In all of these images, we can see a white border around the text inside the large dark regions. We can probably do something like the following to replicate this effect:

  1. randomly select a region to add this effect to,
  2. use the Sobel filter to get edges in this region (A),
  3. add noise around the edges in this region to "enlarge" the edge mask (B),
  4. subtract the edge mask from the region, removing the text
  5. apply very heavy noise in the region
  6. add the negative of (B) back to the region, creating a white area around the text,
  7. add (A) back to the image, printing black text over the white region from part 6

proofconstruction avatar Aug 26 '21 14:08 proofconstruction

Right, this should be feasible with current badphotocopy augmentation. Probably we just need to adjust the code a bit to produce a different noise pattern.

kwcckw avatar Aug 27 '21 00:08 kwcckw

Can we produce a copy of this with BadPhotoCopy and/or the upcoming Faxify?

proofconstruction avatar Sep 09 '21 14:09 proofconstruction

Can we produce a copy of this with BadPhotoCopy and/or the upcoming Faxify?

Not with Faxify, but it is possible with Badphotocopy, I will work on a different hash type in BadPhotoCopy to produce this effect after my next update on the Faxify.

kwcckw avatar Sep 10 '21 01:09 kwcckw

Does the new Faxify update allow this kind of effect?

proofconstruction avatar Sep 26 '21 11:09 proofconstruction

Does the new Faxify update allow this kind of effect?

Nope, faxify is creating something like monochrome (black & white) and halftone. We have something similar but not exactly with badphotocopy (hash type = 1). For example:

image

We are still not able to create a consistent wavy pattern yet, so is this really needed? If yes i will look further on how to reproduce it.

kwcckw avatar Sep 26 '21 12:09 kwcckw

I think we could use the following algorithm to reproduce this effect with the wave pattern:

  1. randomly choose 2 edges of the page (must be different edges), edge1 and edge2
  2. randomly choose a point on each of the edges, let's call them p_start and p_end
  3. randomly pick a number n, maybe in the interval (3,7) to start
  4. randomly pick n points in the image, p1, p2, ..., pn
  5. use the Chaikin algorithm to create a contour connecting p_start, p1, ..., pn, p_end
  6. randomly pick one side of this contour
  7. use the contour, edge1, and edge2 as the boundary of a region of the page
  8. get the mask corresponding to this region, with all transparent pixels in the other part of the mask
  9. apply BadPhotoCopy to this mask
  10. layer the mask back onto the original document

proofconstruction avatar Oct 01 '21 12:10 proofconstruction

Good idea, i think we can try this out.

kwcckw avatar Oct 02 '21 01:10 kwcckw

Good idea, i think we can try this out.

I tried but looks like i'm getting a straight line with chaikin and smooth, is there any example of chaikin usage? Anyway, right now i'm trying to use a sine wave curve to reproduce a similar effect, i will push again when it is done.

kwcckw avatar Oct 03 '21 12:10 kwcckw

...looks like i'm getting a straight line with chaikin and smooth, is there any example of chaikin usage?

The Strikethrough augmentation uses chaikin via the call to smooth.

This may be oversimplifying it, but I think the idea is first to create a sequence of random points across the page in such a way that they could be connected and smoothed. The smoothed line would connect any one side of the page to any of the 4 sides (including the starting side).

Then, complete the creation of an enclosing shape using from 1 to 5 straight lines, depending on which direction was chosen and the location of the start/stop points. The straight lines will either join to a corner or the start/stop points.

The enclosing shape would then serve as the mask for partially applying the bad copy effect.

image

jboarman avatar Oct 03 '21 18:10 jboarman

^ This is exactly what I meant

proofconstruction avatar Oct 04 '21 04:10 proofconstruction

I tried with this approach, the output looks jagged, it wouldn't look natural in way:

The code to reproduce it:

    img = np.zeros((800,800),dtype='uint8')
    
    point_x = [0, 100, 200, 250, 450, 500]
    point_y = [100, 450, 50, 300, 50, 300]
    
    for i in (range(len(point_x)-1)):
        
        point1 = [point_x[i], point_y[i]]
        point2 = [point_x[i+1], point_y[i+1]]
        points = chaikin([point1,point2])
        smooth_points = smooth(points,5) 
        for x,y in smooth_points:  
            img[int(y),int(x)] = 255
    
    plt.figure()
    plt.scatter(point_x, point_y)
    plt.imshow(img)

The output: image

To smooth it, i tried with some curve fitting:

The code to reproduce it:

    img = np.zeros((800,800),dtype='uint8')
    ysize, xsize = img.shape[:2]
    
    point_x = [0, 100, 200, 250, 450, 500]
    point_y = [100, 450, 50, 300, 50, 300]
    
    for i in (range(len(point_x)-3)):
        
        all_x = [point_x[i], point_x[i+1], point_x[i+2], point_x[i+3]]
        all_y = [point_y[i], point_y[i+1], point_y[i+2], point_y[i+3]]
        xnew = np.linspace(min(all_x), max(all_x), 500).astype('int')
        tck = splrep(all_x, all_y)
        ynew = splev(xnew, tck)
        
        for x,y in zip(xnew, ynew):   
            img[min(int(y),ysize-1),min(int(x),xsize-1)] = 255
    
    plt.figure()
    plt.scatter(point_x, point_y)
    plt.imshow(img)

The output: image

We can further mask the overlapped area: image

So i think we need an additional curve fitting process to create a more natural effect.

kwcckw avatar Oct 04 '21 09:10 kwcckw

Ok, so there is a logical error here while applying the chaikins algorithm. By writing the smooth function inside the for i in (range(len(point_x)-3)): you are basically smoothing each pair of points independently (which is a line). However, the algorithm needs a list of more than 2 points to generate a smoothing effect.

Correct way would be

   img = np.zeros((800, 800), dtype='uint8')

    point_x = [0, 100, 200, 250, 450, 500]
    point_y = [100, 450, 50, 300, 50, 300]
    points=[]
    for i in (range(len(point_x) )):
        p = [point_x[i], point_y[i]]
        points.append(p)
    print(points)
    smooth_points = smooth(points, 10)
    for x, y in smooth_points:
        img[int(y), int(x)] = 255

    plt.figure()
    # plt.scatter(point_x, point_y)
    plt.imshow(img,cmap="gray")
    plt.show()

Figure_1

shaheryar1 avatar Oct 04 '21 17:10 shaheryar1

Ok, so there is a logical error here while applying the chaikins algorithm. By writing the smooth function inside the for i in (range(len(point_x)-3)): you are basically smoothing each pair of points independently (which is a line). However, the algorithm needs a list of more than 2 points to generate a smoothing effect.

Ah, thanks, this should be suitable to generate the wave pattern and replace the current curve fitting workflow in Badphotocopy. We may either mask the top or bottom part of wave too:

image

Also it would be nice if we can at least include some comments or notes in those functions, so that the other user know the correct way to use it too.

kwcckw avatar Oct 05 '21 00:10 kwcckw

This looks great, but I think we still want the curve to end at one of the edges so it looks more natural.

I also agree that we always need more comments, and we should have a markdown file in the docs folder for every augmentation.

proofconstruction avatar Oct 05 '21 08:10 proofconstruction

Also it would be nice if we can at least include some comments or notes in those functions, so that the other user know the correct way to use it too.

Sure, I will do this in my next PR.

shaheryar1 avatar Oct 05 '21 12:10 shaheryar1

These can now be reproduced with BadPhotoCopy, right?

proofconstruction avatar Oct 22 '21 12:10 proofconstruction

These can now be reproduced with BadPhotoCopy, right?

Not exactly, we can reproduce a similar effect, but those noise look sparser (lighter). I will include another update to adjust the noise density later.

kwcckw avatar Oct 22 '21 13:10 kwcckw

@kwcckw I believe we have reproduced this effect in one of the archetypes; however, I don't know that we have generalized the generation of this effect in a parameterized and natural way within the library. Can you confirm the current state of this feature implementation?

jboarman avatar Mar 11 '23 23:03 jboarman

@kwcckw I believe we have reproduced this effect in one of the archetypes; however, I don't know that we have generalized the generation of this effect in a parameterized and natural way within the library. Can you confirm the current state of this feature implementation?

This is now in BadPhotoCopy, by enabling wave_pattern, we should see this effect.

image

kwcckw avatar Mar 12 '23 00:03 kwcckw