Skip to content

Latest commit

 

History

History
120 lines (85 loc) · 4.41 KB

0.3.md

File metadata and controls

120 lines (85 loc) · 4.41 KB

图像转为不同风格

水彩画:成块状,块之间没有突兀黑边

这个原理其实就是保边滤波,不断去滤,其中可以用金字塔加速,即只对金字塔下采样后的图片进行滤波。这个推荐用 edgePreservingFilter,这是一个频率上的保边滤波,速度相当快,非常适合这种操作。

也可以用 pyrMeanShiftFiltering,本质上是 Meanshift + Pyramid,即这里的滤波是 MeanShift 来完成。也可以用 bilateralFilter 多次滤波。

也可以用 xphoto 模块的 oilPainting,这个好像就是最正统的油画做法。具体原理从网上看到的是:对于每个像素,如果计算 2×size+1 窗口大小的直方图,将最常出现的值赋给该像素点,这样的结果看起来就很像油画了。

# 频域上的保边滤波 edgePreserving;速度相当快,其中 RECURS 速度好于 NORMCONV
out1 = cv2.edgePreservingFilter(src, flags=cv2.RECURS_FILTER, sigma_s=100, sigma_r=0.5)
out2 = cv2.edgePreservingFilter(src, flags=cv2.NORMCONV_FILTER, sigma_s=100, sigma_r=0.5)

# Meanshift + Pyramid
out3 = cv2.pyrMeanShiftFiltering(src, 21, 51)
out4 = cv2.pyrMeanShiftFiltering(src, 11, 31)

# 多次在空域上保边滤波,很慢(可以用金字塔来加速)
out5 = np.copy(src)
# for _ in range(1):
#     out5 = cv2.pyrDown(out5)
for _ in range(7):
    out5 = cv2.bilateralFilter(out5, d=7, sigmaSpace=75, sigmaColor=70)
# for _ in range(1):
#     out5 = cv2.pyrUp(out5)

# OilPainting
for i in [5, 7]:
    for j in [1, 5, 10]:
        out = cv2.xphoto.oilPainting(src, size=i, dynRatio=j)
        result.append((f'oilPainint(size={i}, dynRation={j})', out))

1726141037787

油画:成块状,块之间有突兀黑边

本质上是 滤波 + 检测边缘后描边,直接用 stylization,他这个背后用的滤波也是频率上的滤波,很快。

# 频域上的保边滤波(用了 edgePreservingFilter)
out1 = cv2.stylization(src, sigma_s=60, sigma_r=0.07)
out2 = cv2.stylization(src, sigma_s=60, sigma_r=0.20)

1723168086856

铅笔素描

本质是边缘检测。直接调用 pencilSketch,同样用的滤波也是频率上的滤波,很快。

dst_gray, dst_color = cv2.pencilSketch(src, sigma_s=60, sigma_r=0.07, shade_factor=0.05)

1723168288531

边缘增强

边缘检测,然后加强原图的边缘。直接调用 detailEnhance,同样用的滤波也是频率上的滤波,很快。

# 本质上是对边缘进行锐化增强,这里直接用的 detailEnhance,背后是频率保边滤波 edgePreservingFilter
dst = cv2.detailEnhance(src, sigma_s=10, sigma_r=0.15)

1723168405572

浮雕风格

就是每个像素减去对应周围的一个像素,比如减去左上角、减去左边,要注意是所有像素都统一按照一个方向去减

# 浮雕:本质上就是中间的点减去周围的一个点
from scipy.signal import convolve2d

img1 = np.zeros_like(src)
K1 = np.array([[-1, 0, 0], [0, 1, 0], [0, 0, 0]])
for i in range(3):
    img1[..., i] = convolve2d(src[..., i], K1, mode='same') + 100

img2 = np.zeros_like(src)
K2 = np.array([[0, -1, 0], [0, 1, 0], [0, 0, 0]])
for i in range(3):
    img2[..., i] = convolve2d(src[..., i], K2, mode='same') + 100

show_images([
    ('source', src),
    ('img1', img1),
    ('img2', img2),
], colnum=3, scale=4)

1727507565709

毛玻璃

本质就是对于每个像素,用周围的随机一个位置的像素去替代它。

# 毛玻璃:

rows, cols = src.shape[0:2]

dst = np.zeros_like(src)
for i in range(20, rows-20):
    for j in range(20, cols-20):
        nowr = int(np.random.random() * 20)
        nowc = int(np.random.random() * 20)
        dst[i, j] = src[i+nowr, j+nowc]

show_images([
    ('source', src),
    ('dst', dst),
], colnum=3, scale=4)

1727507711705