python - 没有渐变的抗锯齿?
问题描述
我有一个图像,其边缘看起来超级前卫和块状。我想抗锯齿,但据我所知,通过超级采样,我取附近像素的平均颜色,以使图像看起来不那么锯齿和渐变。但我真的不想要那个。我需要输出曲线,但没有渐变效果。
我尝试使用filter=Image.ANTIALIAS
,这显然无助于获得我想要的东西。
我的输入图像:
我的输出愿望:
这听起来像矢量化吗?这甚至可能吗?
谢谢
解决方案
这个答案解释了如何平滑块状图像。第一步是获取图像的轮廓。然后,将每个轮廓转换为列表。该列表是内插的,因此没有两个连续的点相距太远。最后使用 平滑这个点列表scipy.signal.savgol_filter()
。结果:
更改window_length
参数以获得更平滑的效果:
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()
推荐阅读
- django - Django 模板 {% include %} 后备值
- php - Symfony 3 DTOOneCommand changing null value to 0 after handleRequest
- html - 如何在 Kentico CMS 中编辑模式中的文本
- python - twisted.python.failure.Failure 的“值”属性是否有回溯?如果没有,如何建立回溯?
- sqr - SQR - Last-Page() 在打印 1000000 页时打印 ****
- shell - 我可以在命令行上做一个否定的通配符吗?
- android - WifiManager.disconnect() 在 Android Q 中已弃用
- python - 将嵌套的类字典 txt 文件读入 Pandas 数据帧
- php - 为什么我的请求不能与 orWhereRaw() 一起使用?
- php - 我将如何检查电子邮件是否已在使用中?