没有渐变的抗锯齿功能?

时间:2019-09-06 10:40:28

标签: python opencv gradient antialiasing

我有一张图像,其边缘看上去非常锋利且块状。我想进行抗锯齿,但是据我所知,通过超级采样,我采用附近像素的平均颜色来使图像看起来不那么锯齿和渐变。但是我真的不想要那个。我需要输出弯曲,但没有渐变效果。

我尝试使用filter=Image.ANTIALIAS,这显然无助于获得我想要的东西。

我的输入图片:

My input image


我的输出愿望:

What I want

这听起来像矢量化,这甚至可能吗?

谢谢

1 个答案:

答案 0 :(得分:2)

此答案说明了如何平滑块状图像。第一步是获取图像的轮廓。然后,将每个轮廓转换为列表。该列表是插值的,因此没有两个连续的点相隔太远。最后,使用scipy.signal.savgol_filter()对点列表进行平滑处理。结果:

smoothed

更改window_length参数以获得更平滑的效果:

changing smoothing parameter

import cv2
import numpy as np
import scipy
from scipy import signal
import math

colors = (0,255,0), (255,0,255)
max_dist_between_points = .25

# Get contours
img = cv2.imread('/home/stephen/Desktop/jaggy.png')
gray = 255-cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 123, 123)
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

def distance(a,b): return math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)
def max_dist(points):
    max_dist = 0
    for i in range(len(points)-1):
        dist = distance(points[i], points[i+1])
        if dist > max_dist: max_dist = dist
    return max_dist
def interpolate(points):
    interpolated = [points[0]]
    for i in range(len(points)-1):
        a,b = points[i], points[i+1]
        dist = distance(a,b)
        if dist >= max_dist_between_points:
            midpoint = (a[0]+b[0])/2, (a[1]+b[1])/2
            interpolated.append(midpoint)
        interpolated.append(b)
    return interpolated


# Iterate through each contour
for contour in contours:

    # Reformat the contour into two lists of X and Y values
    points, new_points = list(contour), []
    for point in points: new_points.append(tuple(point[0]))
    points = new_points

    # Interpolate the contour points so that they aren't spread out
    while max_dist(points) > 2:
        print(len(points))
        points = interpolate(points)
    X, Y = zip(*points)

    # Define smoothing parameters
    window_length, polyorder = 155, 3
    # Smoooth
    X = signal.savgol_filter(X, window_length, polyorder)
    Y = signal.savgol_filter(Y, window_length, polyorder)
    # Re zip and iterate through the points
    smooth = list(zip(X,Y))
    for point in range(len(smooth)):
        a,b = smooth[point-1], smooth[point]
        a,b = tuple(np.array(a, int)), tuple(np.array(b, int))
        cv2.line(img, a, b, colors[contours.index(contour)], 2)   

cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()