13 Replies - 1000 Views - Last Post: 27 January 2018 - 05:40 AM Rate Topic: -----

#1 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Anti-Alias on image with python

Posted 19 October 2017 - 10:30 AM

Hi I am new to python
and I need help with this problem
I have 100 different 2D images, these images are black and white image (i give one sample image, see below)
and I need to give anti-aliasing on every image. especially I need to add anti-aliasing/gradient gray pixel on the edge of the object.
May you give me some clue, how to do this in python step by step? from import the object to give anti-alias
Thank you

Posted Image

Is This A Good Question/Topic? 0
  • +

Replies To: Anti-Alias on image with python

#2 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 19 October 2017 - 10:59 AM

You need to be able to determine if a point is inside, outside or on the edge.
For a ball this is simple, as the perimeter is defined by simple mathematics.
The edge points are those that need anti-aliasing.

For a random object (like the one showed) how do you determine this? Are the objects described by mathematics?

If size-reduction is allowed, you can use the technique described in my other tutorial: http://www.dreaminco...-anti-aliasing/
Was This Post Helpful? 1
  • +
  • -

#3 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Re: Anti-Alias on image with python

Posted 19 October 2017 - 11:07 AM

View PostDK3250, on 19 October 2017 - 10:59 AM, said:

You need to be able to determine if a point is inside, outside or on the edge.
For a ball, this is simple, as the perimeter is defined by simple mathematics.
The edge points are those that need anti-aliasing.

For a random object (like the one showed) how do you determine this? Are the objects described by mathematics?

If size-reduction is allowed, you can use the technique described in my other tutorial: http://www.dreaminco...-anti-aliasing/


Hey thanks for replying me, I generate the image from 3D STL file, and i have a program that slice the 3D object to 2D layer
this is related to DLP 3D printing, by applying anti-alias, your printed object will be more smooth.
Unfortunately, I cannot reduce the size, it must be 1:1
and yeah random image make this problem more complicated
Was This Post Helpful? 0
  • +
  • -

#4 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 19 October 2017 - 02:48 PM

View Postnoles123, on 19 October 2017 - 07:07 PM, said:

(...) and yeah random image make this problem more complicated

You need to be able to provide exact instructions of how to solve a problem. Otherwise there is no chance of writing a code for the job.

It is not clear (at least not to me) how the generic anti-aliasing should work on the sample figure.

So, it is not a matter of complication, rather of insufficient specification of the task.

I you can specify what you want the code to do, then there is a chance that the code can be made; otherwise not.
The idea here on DIC is that you show an attempt to solve the task i.e. show some code and then ask about errors, problems, etc.
Was This Post Helpful? 0
  • +
  • -

#5 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Re: Anti-Alias on image with python

Posted 20 November 2017 - 06:55 AM

View PostDK3250, on 19 October 2017 - 02:48 PM, said:

View Postnoles123, on 19 October 2017 - 07:07 PM, said:

(...) and yeah random image make this problem more complicated

You need to be able to provide exact instructions of how to solve a problem. Otherwise there is no chance of writing a code for the job.

It is not clear (at least not to me) how the generic anti-aliasing should work on the sample figure.

So, it is not a matter of complication, rather of insufficient specification of the task.

I you can specify what you want the code to do, then there is a chance that the code can be made; otherwise not.
The idea here on DIC is that you show an attempt to solve the task i.e. show some code and then ask about errors, problems, etc.


Hey i have modified some code from your source,
import pygame, sys, math, random
pygame.init()
window = pygame.display.set_mode((768,480))
pygame.display.set_caption("Window")
# DECLARATIONS

X = 768
Y = 480

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
MONO = (255, 255, 255)

size = 400

surf = pygame.image.load('test.png').convert_alpha()

gameLoop=True
while gameLoop:
for event in pygame.event.get():

gameLoop = False

window.fill(BLACK)
window.blit(surf, (0,0))
pygame.display.flip()



def resize(surf, size):
"""
Anti-aliasing by average of color code in four pixels
with subsequent use of the average in a smaller surface
"""
new_surf = pygame.surface.Surface((768//1,480//1))

for j in range(0, 480, 2):
for i in range(0, 768, 2):
r1, g1, b1, a1 = surf.get_at((i, j))
r2, g2, b2, a2 = surf.get_at((i+1, j))
r3, g3, b3, a3 = surf.get_at((i, j+1))
r4, g4, b4, a4 = surf.get_at((i+1, j+1))

r = (r1 + r2 + r3 + r4) / 4
g = (g1 + g2 + g3 + g4) / 4
b = (b1 + b2 + b3 + b4) / 4

new_surf.set_at((i//2, j//2), (r, g, b, 255))

new_size = size // 2
return new_surf, new_size


# MAIN CODE

#surf = draw_figure()
#make_gradient(magenta_1)
surf, size = resize(surf, size)
surf, size = resize(surf, size)

window.blit(surf, (0, 0))
pygame.display.flip()



I have some question:
1. I want to know what is the meaning of size = 400? because what I imagine if it is a picture of the image, it must be X * Y pixels.
2. so my final goal is to make the picture with anti-alias and it has 768*480 resolution. but I saw your code it must resize the image smaller. So my question how to achieve this resolution(768*480) with AA?
my condition now, my image source is 768*480, but I can make it larger. what I think now of the solution is:
1. make a larger source image, and resize it with your code until I get resolution 768*480 pixels
or
2. I resize(larger) the output image from your code to 768*480

what is your recommendation? thanks a lot
i also attach my source image
Was This Post Helpful? 0
  • +
  • -

#6 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 20 November 2017 - 07:25 AM

The size = 400 is just an example used for a square window.
You are absolutely right, in general it must be X * Y.

You should definitely go for option 1, make a larger image (768*2, 480*2) or even (768*4, 480*4) and then re-size down once or twice.

Option 2 will lead to imperfections upon final re-size back to original size. (768, 480) >> Anti-alias >> (384, 240) >> re-size >> (768, 480).
Maybe it is possible to re-size in a 'smart' way not leading to severe imperfections, but option 1 is better.

No image was attached.
Was This Post Helpful? 0
  • +
  • -

#7 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Re: Anti-Alias on image with python

Posted 20 November 2017 - 11:11 PM

View PostDK3250, on 20 November 2017 - 07:25 AM, said:

The size = 400 is just an example used for a square window.
You are absolutely right, in general it must be X * Y.

You should definitely go for option 1, make a larger image (768*2, 480*2) or even (768*4, 480*4) and then re-size down once or twice.

Option 2 will lead to imperfections upon final re-size back to original size. (768, 480) >> Anti-alias >> (384, 240) >> re-size >> (768, 480).
Maybe it is possible to re-size in a 'smart' way not leading to severe imperfections, but option 1 is better.

No image was attached.


sorry for the previous reply, no pic, and no code template, I am still not used to posting in this forum.
hey, I have tried your suggestion, I enlarge the image 2x and 4x larger with paint.
and the result yeah I got a larger image, especially 4x larger image, I can get the result that the resolution I want (768,480)

but the problem is when I observe the result, it lost a lot of grey pixel(AA) at the 2x larger image, furthermore, at the 4x larger image it has no gray-pixel or AA.. so if I make the image larger solve one of my problems but at the other side, it makes another problem that is essential in this case, do you have any suggestion?

and the second problem it takes really a long time, around 1 minute for 1 picture,
I think in my case, the picture only black and white,
I want to change the algorithm loop RGB function to grayscale. How to change this code?

r1, g1, b1, a1 = surf.get_at((i, j))
44
            r2, g2, b2, a2 = surf.get_at((i+1, j))
45
            r3, g3, b3, a3 = surf.get_at((i, j+1))
46
            r4, g4, b4, a4 = surf.get_at((i+1, j+1))
47
 
48
            r = (r1 + r2 + r3 + r4) / 4
49
            g = (g1 + g2 + g3 + g4) / 4
50
            b = (b1 + b2 + b3 + b4) / 4




here I attach my whole code and image, I hope the uploaded image can be shown well. thank you so much for your answer!!!

image: https://drive.google...iew?usp=sharing

"""
anti-aliasing on image

"""
import pygame, sys, math, random
pygame.init()
window = pygame.display.set_mode((768,480))
pygame.display.set_caption("Window")
# DECLARATIONS

X = 768
Y = 480

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
MONO = (255, 255, 255)

size = 400

surf = pygame.image.load('test.png').convert_alpha()

gameLoop=True
while gameLoop:
    for event in pygame.event.get():
        
            gameLoop = False

    window.fill(BLACK)
    window.blit(surf, (0,0))
    pygame.display.flip()
    
            

def resize(surf, size):
    """
    Anti-aliasing by average of color code in four pixels
    with subsequent use of the average in a smaller surface
    """
    new_surf = pygame.surface.Surface((3072//1,1920//1))
    
    for j in range(0, 1920, 2):
        for i in range(0, 3072, 2):
            r1, g1, b1, a1 = surf.get_at((i, j))
            r2, g2, b2, a2 = surf.get_at((i+1, j))
            r3, g3, b3, a3 = surf.get_at((i, j+1))
            r4, g4, b4, a4 = surf.get_at((i+1, j+1))

            r = (r1 + r2 + r3 + r4) / 4
            g = (g1 + g2 + g3 + g4) / 4
            b = (b1 + b2 + b3 + b4) / 4

            new_surf.set_at((i//2, j//2), (r, g, b, 255))

    new_size = size // 2
    return new_surf, new_size
            

# MAIN CODE

#surf = draw_figure()
#make_gradient(magenta_1)
surf, size = resize(surf, size)
surf, size = resize(surf, size)    
window.blit(surf, (0, 0))
pygame.display.flip()




Was This Post Helpful? 0
  • +
  • -

#8 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 21 November 2017 - 03:14 AM

Just enlarging the original picture with paint or similar will not do the trick.

Think about it this way: You have a certain amount of pixels, each pixel holds information about its color.
When you enlarge, the pixels are spread out and the empty new pixels are pasted with data from existing one; no truly new data is generated.
Upon later reduction average is calculated on the already 'artificial' data.
Chances are that you get quite bad imperfections.

My answer in post #6 was based on a true picture of double size; i.e. all pixels in the larger picture calculated by the source code.

I don't know anything about your source code. As it results in pictures that are only black and white, I guess that pixels on the rim might have a fractional value that are then rounded off to either black or white. If you have access to the original (not rounded) values, then it should be possible to assign a grey scale value to the pixel in question. If the pixel value is close to white the pixels becomes light grey; if it is close to black it becomes dark grey.
This approach is described in the first of the two AA tutorials: http://www.dreaminco...-anti-aliasing/
Was This Post Helpful? 0
  • +
  • -

#9 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Re: Anti-Alias on image with python

Posted 05 December 2017 - 06:22 AM

hey,
now I fully understand this code. Thanks to you
but still I have something bothers me
do you have any solution without reducing the image pixel I've seen your method use down-sampling(if I am not wrong).
but have you heard about super-sampling? (spatial sampling)

This post has been edited by andrewsw: 05 December 2017 - 06:40 AM
Reason for edit:: removed previous quote, use the Reply button further down the page

Was This Post Helpful? 0
  • +
  • -

#10 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Re: Anti-Alias on image with python

Posted 05 December 2017 - 06:42 AM

I am trying to do it, I hope it can give anti-alias without resizing the image, but what happened is like this picture, the trapezoid become so dark, the original image is white.. why is this happen?

https://drive.google...iew?usp=sharing

actually, if we zoom that image (i put on the right side, the AA has been applied there, but what I want it has clear white like the original image (original image link: Source

here is the code


"""
anti-aliasing on image

"""
import pygame, sys, math, random
pygame.init()
window = pygame.display.set_mode((768,480))
pygame.display.set_caption("Window")
# DECLARATIONS

X = 768
Y = 480

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
MONO = (255, 255, 255)

size = 400

surf = pygame.image.load('test.png').convert_alpha()

gameLoop=True
while gameLoop:
    for event in pygame.event.get():
        
            gameLoop = False

    window.fill(BLACK)
    window.blit(surf, (0,0))
    pygame.display.flip()
    
            

def resize(surf, size):
    """
    Anti-aliasing by average of color code in four pixels
    with subsequent use of the average in a smaller surface
    """
    new_surf = pygame.surface.Surface((768,480))
    
    for j in range(0, 480, 2):
        for i in range(0, 768, 2):
            r1, g1, b1, a1 = surf.get_at((i, j))
            r2, g2, b2, a2 = surf.get_at((i+1, j))
            r3, g3, b3, a3 = surf.get_at((i, j+1))
            r4, g4, b4, a4 = surf.get_at((i+1, j+1))

            r1all = (r1 + r2 + r3 + r4) / 4
            #r1new = (r1 + r2) / 2
            #r2new = (r2 + r2) / 2
            #r3new = (r2 + r3) / 2
            #r4new = (r2 + r4) / 2
            g1all = (g1 + g2 + g3 + g4) / 4
            #g1new = (g1 + g2) / 2
            #g2new = (g2 + g2) / 2
            #g3new = (g2 + g3) / 2
            #g4new = (g2 + g4) / 2
            b1all = (b1 + b2 + b3 + b4) / 4
            #b1new = (b1 + b2) / 2
            #b2new = (b2 + b2) / 2
            #b3new = (b2 + b3) / 2
            #b4new = (b2 + b4) / 2

            new_surf.set_at((i, j), (r1all, g1all, b1all, 255))
            #new_surf.set_at((i+1, j), (r2new, g2new, b2new, 255))
            #new_surf.set_at((i, j+1), (r3new, g3new, b3new, 255))
            #new_surf.set_at((i+1, j+1), (r4new, g4new, b4new, 255))

    new_size = size
    return new_surf, new_size
            
# MAIN CODE

#surf = draw_figure()
#make_gradient(magenta_1)
surf, size = resize(surf, size)
surf, size = resize(surf, size)    
window.blit(surf, (0, 0))
pygame.display.flip()




Was This Post Helpful? 0
  • +
  • -

#11 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 05 December 2017 - 02:57 PM

The problem with your code is that you hard-code the ranges in line 41 and 42.

As the image gets smaller, you assign pixels outside the modified (smal) image; such pixels are per default black.

Go back to my original code to see how the ranges are set by parameters.

I am not familiar with super-sampling.
Was This Post Helpful? 0
  • +
  • -

#12 noles123   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 12
  • Joined: 19-October 17

Re: Anti-Alias on image with python

Posted 05 December 2017 - 03:57 PM

ok got it

I also still not understand

why did you use this function 2 times?


surf, size = resize(surf, size)
surf, size = resize(surf, size)
Was This Post Helpful? 0
  • +
  • -

#13 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 06 December 2017 - 12:40 AM

In my example I make the image at 4 times the final size.
I call the rezise() function two times to half the size first by a factor of 2 and then again a factor of 2, yielding a factor of 4.

In this way the AA is more effective.
If the original picture is pure black/white, this correspond to 0% and 100%
After one call to resize(), saturation is possible at 0%, 25%, 50%, 75% and 100%
After yet another resize() many more intermediate values are in play, yielding a better AA product.
Was This Post Helpful? 0
  • +
  • -

#14 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 411
  • View blog
  • Posts: 1,319
  • Joined: 27-December 13

Re: Anti-Alias on image with python

Posted 27 January 2018 - 05:40 AM

I was surfing around and landed on this thread that is now 6-7 weeks old. I hope the theme is still relevant to some.

Let me show how a two-color figure that is defined my mathematics can easily be antialiased.
This code describes a black/white figure:
import pygame
pygame.init()

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

X = 400
Y = 600

screen = pygame.display.set_mode((X, Y))


def figure(x, y):
    value = -x * 1.55 + 400 - y 
    if value >= 0:
        return WHITE
    else:
        return BLACK


for j in range(Y):
    for i in range(X):
        color = figure(i, j)
        screen.set_at((i, j), color)


pygame.display.flip()

In the figure below, I have zoomed to the border between black and white; it is evident that the border in not anatialiased.
Posted Image

Now, if we change the colorization criteria from only black and white to:
  • value >= 1: White
  • value <= 0: Black
  • value between 0 and 1: Greyscale

The code becomes:
import pygame
pygame.init()

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

X = 400
Y = 600

screen = pygame.display.set_mode((X, Y))


def figure(x, y):
    value = -x * 1.55 + 400 - y 
    if value >= 1:
        return WHITE
    elif value <= 0:
        return BLACK
    else:
        return [value * 255] * 3


for j in range(Y):
    for i in range(X):
        color = figure(i, j)
        screen.set_at((i, j), color)


pygame.display.flip()

This yields a nice antialiased line:
Posted Image

I hope this may be of inspiration.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1