OpenCV非真实感绘制(铅笔画、卡通画、边沿保持、细节增强)

原文链接:http://www.juzicode.com/opencv-note-non-photorealistic-rendering

OpenCV中提供了几个非真实感绘制的接口函数,我们可以借助这些函数得到卡通画、素描画、美颜以及细节增强的图像。

detailEnhance()用来增强图像的细节:

cv2.detailEnhance(src[,dst[,sigma_s[,sigma_r]]])->dst

edgePreservingFilter()实现边沿保持滤波,可以实现磨皮、美颜的效果:

cv2.edgePreservingFilter(src[,dst[,flags[,sigma_s[,sigma_r]]]])->dst

pencilSketch()生成铅笔素描画,返回2个图像,一个是灰度铅笔画,一个是彩色铅笔画:

cv2.pencilSketch(src[,dst1[,dst2[,sigma_s[,sigma_r[,shade_factor]]]]])->dst1,dst2

stylization()生成卡通画,这点和桔子菌在 论如何把自己变成卡通人物(OpenCV制作卡通化头像) 一文中介绍的卡通画效果类似:

cv2.stylization(src[,dst[,sigma_s[,sigma_r]]])->dst

这些函数的输入图像src都要求是8bit 3通道图像,另外都有2个共同的参数sigma_s和sigma_r,其中sigma_s参数取值范围为0~200,sigma_r参数取值范围为0~1。

下面是一个绘制卡通画的例子:

#VX公众号: 桔子code / juzicode.com 
import cv2  
print('cv2.__version__:',cv2.__version__)
img = cv2.imread('lvyi11.jpg')  
img1=cv2.stylization(img,sigma_s=10,sigma_r=0.3)
cv2.imshow('raw',img)  
cv2.imshow('stylization',img1)  
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

调用其他几个函数,再通过调整sigma_s和 sigma_r参数还可以得到更多风格的结果图像:

#VX公众号: 桔子code / juzicode.com 
import os
import cv2  
print('cv2.__version__:',cv2.__version__)

dbg_is_show = False
def show_img(win_name,img,posx=100,posy=100,wait_time=-1,img_ratio=0.5,is_show=True):
    if is_show is not True:return None
    rows = img.shape[0]
    cols = img.shape[1]
    cv2.namedWindow(win_name, cv2.WINDOW_NORMAL )#cv2.WINDOW_AUTOSIZE)
    cv2.resizeWindow(win_name,(int(cols*img_ratio),int(rows*img_ratio)))
    cv2.moveWindow(win_name,posx,posy)
    cv2.imshow(win_name,img)
    if wait_time>=0:
        cv2.waitKey(wait_time)
    return posx+int(cols*img_ratio),posy+int(rows*img_ratio)

start_posx=100
start_posy=30
if not os.path.isdir('out/'):
    os.makedirs('out/')
img = cv2.imread('lvyi11.jpg') 
for s in range(1,200,25):
    for r in range(1,10,2):
        sigma_s = s
        sigma_r = r*0.1
        img1=cv2.stylization(img,sigma_s=sigma_s,sigma_r=sigma_r) 
        img2=cv2.detailEnhance(img,sigma_s=sigma_s,sigma_r=sigma_r) 
        img3=cv2.edgePreservingFilter(img,sigma_s=sigma_s,sigma_r=sigma_r) 
        img4,img5=cv2.pencilSketch(img,sigma_s=sigma_s,sigma_r=sigma_r,shade_factor = 0.02)
        raw_name='s=%d,r=%f'%(sigma_s,sigma_r)
        x,y=show_img(raw_name,img,start_posx,start_posy)
        x,y=show_img('cartoon',img1,x,start_posy) 
        x,y=show_img('detail enhance',img2,x,start_posy) 
        x,y2=show_img('edge preserv',img3,start_posx,25+y) 
        x,y2=show_img('pencil gray',img4,x,25+y) 
        x,y2=show_img('pencil color',img5,x,25+y) 
        cv2.imwrite('out/cartoon-'+raw_name+'.jpg',img1)
        cv2.imwrite('out/detail-'+raw_name+'.jpg',img2)
        cv2.imwrite('out/edge-'+raw_name+'.jpg',img3)
        cv2.imwrite('out/pencilgray-'+raw_name+'.jpg',img4)
        cv2.imwrite('out/pencilcolor-'+raw_name+'.jpg',img5)
        key=cv2.waitKey(500)&0xff
        if key==ord('c') or key == ord('C'):
            pass
        elif key == ord('q') or key == ord('Q'):break
        
        cv2.destroyWindow(raw_name)
cv2.destroyAllWindows()      

运行结果:

扩展阅读:

论如何把自己变成卡通人物(OpenCV制作卡通化头像)

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注