千家信息网

Python如何实现图像特效中的油画效果

发表于:2024-12-01 作者:千家信息网编辑
千家信息网最后更新 2024年12月01日,小编给大家分享一下Python如何实现图像特效中的油画效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一 基本原理如下面
千家信息网最后更新 2024年12月01日Python如何实现图像特效中的油画效果

小编给大家分享一下Python如何实现图像特效中的油画效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一 基本原理

如下面的两幅图所示,油画用对了地方会使得图像一下子显得文艺起来了呢!

拍出的图像

转化为油画

那么将一幅图像转化为油画类型的图案是怎么实现的呢?为了将一幅普通的图像转化为油画,一般需要以下的几个步骤:

(1)将图像转化为灰度图像

(2)将图像划分为一个个小方框(4*4,6*6...),并统计其中的每一个像素点像素值

(3)对方框中的像素点的的灰度值进行量化(可以参考我之前的关于量化的文章),并对不同的等级的像素点数目进行计数

(4)找到方框中灰度等级最多的像素点,并对这些像素点的灰度值求平均

(5)用平均值代替原像素像素值

二 代码实现

首先还是经典操作,读取图像信息:

"""Author:XiaoMadate:2021/12/10"""import cv2import numpy as npimg = cv2.imread(r'E:\From Zhihu\For the desk\cvyouhua.jpg')img = cv2.resize(img, dsize = None, fx = 0.2, fy = 0.2) #由于该算法计算量较大,首先对其大小进行调整cv2.imshow('W0', img)cv2.waitKey(0)#获取图片宽高height, width = img.shape[:2]print(height, width)

得到图像信息如下:

对图像进行油画特效处理,代码已经添加了注释,有注释的不清楚的地方可以在评论区讨论或者私信留言,看到会回复大家的:

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#将图像转化为灰度图像dst = np.zeros((height, width, 3), np.uint8)#创建一个和原图等大小的全零矩阵#-----------------------------------------------------------------------#使用for循环嵌套来遍历图像中的每一个像素点#-----------------------------------------------------------------------for i in range(2, height-2):    for j in range(2, width-2):        # ----------------------------------------------------------        # 方框为4*4,对方框内像素点进行量化并记录不同等级的像素点的个数        # ------------------------------------------------------------        array1 = np.zeros(8, np.uint8)#将像素点的值量化为8份,定义数组记录不同等级像素点的个数        for m in range(-2, 2):            for n in range(-2, 2):                p1 = int(gray[i+m, j+n]/32)#量化操作                array1[p1] = array1[p1] + 1#该数组用来记录不同量化级别下的像素点,比如array1[0]代表等级一下的像素点的个数,即像素值为(0~64)的像素点的个数        #-----------------------------------------------------------        #在上面的数组中寻找最大值,即寻找数目最多的像素等级        #------------------------------------------------------------        currentMax = array1[0]        l = 0#用来封装最大值在数组中的位置        for k in range(0, 8):            if currentMax < array1[k]:                currentMax = array1[k]                l = k        #------------------------        #求数目最多的像素等级的平均        #------------------------        for m in range(-2, 2):            for n in range(-2, 2):                if gray[i + m, j + n] >= (l * 32) and gray[i + m, j + n] <= ((l + 1) * 32):                    (b, g, r) = img[i + m, j + n]        dst[i, j] = (b, g, r)cv2.imshow('youhua', dst)cv2.waitKey(0)cv2.destroyAllWindows()

得到的结果如下:

三 总体实现代码以及保存

总体的代码以及保存方式如下,大家修改一下读取和保存的路径就可以用了,如果想了解一下实现算法可以先敲一遍代码:

"""Author:XiaoMadate:2021/12/15"""import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread(r'E:\From Zhihu\For the desk\cvyouhua.jpg')img = cv2.resize(img, dsize = None, fx = 0.2, fy = 0.2) #由于该算法计算量较大,首先对其大小进行调整cv2.imshow('W0', img)cv2.waitKey(0)#获取图片宽高height, width = img.shape[:2]print(height, width)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#将图像转化为灰度图像dst = np.zeros((height, width, 3), np.uint8)#创建一个和原图等大小的全零矩阵#-----------------------------------------------------------------------#使用for循环嵌套来遍历图像中的每一个像素点#-----------------------------------------------------------------------for i in range(2, height-2):    for j in range(2, width-2):        # ----------------------------------------------------------        # 方框为4*4,对方框内像素点进行量化并记录不同等级的像素点的个数        # ------------------------------------------------------------        array1 = np.zeros(8, np.uint8)#将像素点的值量化为8份,定义数组记录不同等级像素点的个数        for m in range(-2, 2):            for n in range(-2, 2):                p1 = int(gray[i+m, j+n]/32)#量化操作                array1[p1] = array1[p1] + 1#该数组用来记录不同量化级别下的像素点,比如array1[0]代表等级一下的像素点的个数,即像素值为(0~64)的像素点的个数        #-----------------------------------------------------------        #在上面的数组中寻找最大值,即寻找数目最多的像素等级        #------------------------------------------------------------        currentMax = array1[0]        l = 0#用来封装最大值在数组中的位置        for k in range(0, 8):            if currentMax < array1[k]:                currentMax = array1[k]                l = k        #------------------------        #求数目最多的像素等级的平均        #------------------------        for m in range(-2, 2):            for n in range(-2, 2):                if gray[i + m, j + n] >= (l * 32) and gray[i + m, j + n] <= ((l + 1) * 32):                    (b, g, r) = img[i + m, j + n]        dst[i, j] = (b, g, r)cv2.imshow('youhua', dst)cv2.waitKey(0)cv2.destroyAllWindows()#------------------------------------------------#保存图像(以前的文章中介绍过,有不懂的地方可以去考古)#------------------------------------------------plt.rcParams['font.family'] = 'SimHei'       #将全局中文字体改为黑体ImgGroup = [img, gray, dst]ImgTitle = ['原图', '灰度图', '油画']a = plt.figure(figsize=(30, 10)) #创建画布for i in range(0, 3):    ImgGroup[i] = cv2.cvtColor(ImgGroup[i], cv2.COLOR_BGR2RGB)    plt.subplot(1, 3, i + 1)    plt.imshow(ImgGroup[i])    plt.title(ImgTitle[i])    plt.suptitle('图像油画特效')    plt.xticks([])    plt.yticks([])plt.savefig(r'E:\From Zhihu\For the desk\Acvyouhua.jpg')plt.show()

得到结果如下:

以上是"Python如何实现图像特效中的油画效果"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0