本文主要给大家展示“Python如何处理图像特效”。内容简单易懂,条理清晰。希望能帮你解开疑惑。让边肖带领大家学习《Python如何处理图像特效》一文。
00-1010读取图像信息:
'''
Author:XiaoMa
日期:2021/11/16
'''
importcv2
importnumpayasnp
进口数学
importmatplotlib.pyplotasplt
img 0=cv2 . imread(' e : \ from zhi Hu \ Forthedesk \ cvfiften 1 . jpg ')
img1=cv2.cvtColor(img0,cv2。颜色_BGR2GRAY)
h,w=img0.shape[:2]
打印(高、低)
cv2.imshow('W0 ',img0)
cv2.imshow('W1 ',img1)
2.cvwaitkey(延迟=0)获得的图像信息如下:
386 686
前言
磨砂玻璃特效的原理是在当前像素的邻域内随机选择一个像素进行替换,从而达到磨砂玻璃的模糊效果。代码如下,添加了注释。有不懂的地方,在评论区留言讨论。
#磨砂玻璃特效
Img 2=NP。零((h,w,3),NP。uint8) #生成等于原始图像的全零矩阵。
foriirang(0,h-6) : #防止下列随机数超出边缘。
forjinrange(0,w-6):
索引=int (NP。随机的。random () * 6) # 0 ~ 6。
(b,g,r)=img0[i指数,j指数]
img2[i,j]=(b,g,r)
cv2.imshow('W2 ',img2)
2.cvwaitkey(延迟=0)的效果如下:
因为在取随机数时必须减去边缘的像素值,所以未填充的区域不可避免地出现在图像的右边缘和下边缘。
我在写博客的时候,突然有了一个计划。如果我们在创建全零矩阵时限制边界,就可以了。我试过了,果然!如下所示:
#磨砂玻璃特效
img 2=NP生成的全零矩阵。零((h-6,w-6,3),NP。uint8) #考虑了随机数的范围。
,变小了
for i in range(0, h - 6): #防止下面的随机数超出边缘
for j in range(0, w - 6):
index = int(np.random.random()*6) #0~6的随机数
(b, g, r) = img0[i + index, j + index]
img2[i, j] = (b, g, r)
cv2.imshow("W2", img2)
cv2.waitKey(delay = 0)
经过上述方式生成的毛玻璃特效就不会出现未填充部位,但图像的尺寸确实小了。
2. 浮雕特效
Python 实现浮雕特效的原理是先勾勒出图像的边界曲线,然后降低边界周围的像素值,从而得到一幅立体的浮雕形式的图像。
#浮雕特效(需要对灰度图像进行操作) img3 = np.zeros((h, w, 3), np.uint8) for i in range(0, h): for j in range(0, w - 2): #减2的效果和上面一样 grayP0 = int(img1[i, j]) grayP1 = int(img1[i, j + 2]) #取与前一个像素点相邻的点 newP = grayP0 - grayP1 + 150 #得到差值,加一个常数可以增加浮雕立体感 if newP > 255: newP = 255 if newP < 0: newP = 0 img3[i, j] = newP cv2.imshow("W3", img3) cv2.waitKey(delay = 0)
得到效果如下:
3. 素描特效
该特效实现较为简单,直接在代码中给出注释:
#素描特效 img4 = 255 - img1 #对原灰度图像的像素点进行反转 blurred = cv2.GaussianBlur(img4, (21, 21), 0) #进行高斯模糊 inverted_blurred = 255 - blurred #反转 img4 = cv2.divide(img1, inverted_blurred, scale = 127.0) #灰度图像除以倒置的模糊图像得到铅笔素描画 cv2.imshow("W4", img4) cv2.waitKey(delay = 0)
4. 怀旧特效
怀旧特效需要专门的 R, G, B 通道的转换公式来对图像的三个通道进行处理,转换公式为:
实现代码如下:
#怀旧特效 img5 = np.zeros((h, w, 3), np.uint8) for i in range(0, h): for j in range(0, w): B = 0.272 * img0[i, j][2] + 0.534 * img0[i, j][1] + 0.131 * img0[i, j][0] G = 0.349 * img0[i, j][2] + 0.686 * img0[i, j][1] + 0.168 * img0[i, j][0] R = 0.393 * img0[i, j][2] + 0.769 * img0[i, j][1] + 0.189 * img0[i, j][0] if B > 255: B = 255 if G > 255: G = 255 if R > 255: R = 255 img5[i, j] = np.uint8((B, G, R)) cv2.imshow("W5", img5) cv2.waitKey(delay = 0)
得到效果如下:
这个特效计算量比起前面的几种还是有点大的,需要对像素点进行遍历,然后计算每一个点的三个通道的值。
5. 流年特效
比起前面的怀旧特效,流年特效只需要对图像的每一个像素点的蓝色通道(B)进行简单调整就可以了,首先是对其开根号,然后乘以一个参数即可,实现代码如下:
#流年特效 img6 = np.zeros((h, w, 3), np.uint8) for i in range(0, h): for j in range(0, w): B = math.sqrt(img0[i, j][0]) *14 # B通道的数值开平方乘以参数14 G = img0[i, j][1] R = img0[i, j][2] if B > 255: B = 255 img6[i, j] = np.uint8((B, G, R)) cv2.imshow("W6", img6) cv2.waitKey(delay = 0)
大家可以多修改参数进行调试,观察不同的参数下的效果。
6. 水波特效
水波特效是使用三角函数得到波纹的传递函数,然后根据设定的中心进行特效的生成,该部分的算法有点难度,多尝试几次就可以了,以后博主有时间会专门出一片水波特效的介绍博文。实现代码如下:
#水波特效 img7 = np.zeros((h, w, 3), np.uint8) wavelength = 20 #定义水波特效波长 amplitude = 30 #幅度 phase = math.pi / 4 #相位 centreX = 0.5 #水波中心点X centreY = 0.5 #水波中心点Y radius = min(h, w) / 2 icentreX = w*centreX #水波覆盖宽度 icentreY = h*centreY #水波覆盖高度 for i in range(0, h): for j in range(0, w): dx = j - icentreX dy = i - icentreY distance = dx * dx + dy * dy if distance > radius * radius: x = j y = i else: # 计算水波区域 distance = math.sqrt(distance) amount = amplitude * math.sin(distance / wavelength * 2 * math.pi - phase) amount = amount * (radius - distance) / radius amount = amount * wavelength / (distance + 0.0001) x = j + dx * amount y = i + dy * amount # 边界判断 if x < 0: x = 0 if x >= w - 1: x = w - 2 if y < 0: y = 0 if y >= h - 1: y = h - 2 p = x - int(x) q = y - int(y) # 图像水波赋值 img7[i, j, :] = (1 - p) * (1 - q) * img0[int(y), int(x), :] + p * (1 - q) * img0[int(y), int(x), :] + (1 - p) * q * img0[int(y), int(x), :] + p * q * img0[int(y), int(x), :] cv2.imshow("W7", img7) cv2.waitKey(delay = 0)
得到效果如下:
由于这张图片刚好波纹附近是头发,导致得到的波纹显得不太清晰,可以换几张图片尝试一下,看看该算法的效果。
7. 卡通特效
该特效主要原理是提取图像的边界轮廓,然后和原图像相与得到最终的卡通化效果,代码如下,已添加注释:
#卡通特效 num_bilateral = 7 #定义双边滤波的数目 for i in range(num_bilateral): #双边滤波处理,除去噪声,保留边界 img_color = cv2.bilateralFilter(img0, d = 9, sigmaColor = 5, sigmaSpace = 3) img_blur = cv2.medianBlur(img1, 7) # 中值滤波处理 img_edge = cv2.adaptiveThreshold(img_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize = 5, C = 2) #边缘检测及自适应阈值化处理,提取边界 img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB) #转换回彩色图像 img8 = cv2.bitwise_and(img0, img_edge) #图像的与运算 cv2.imshow('W8', img8) cv2.waitKey(delay = 0)
得到效果如下:
如果对实现的效果不满意,可以不断调整双边滤波和中值滤波的参数,直到找到较为满意的效果。
8. 将图像都汇总到一张图中
基础操作,没啥可注释的,直接上代码:
#将所有图像保存到一张图中 plt.rcParams['font.family'] = 'SimHei' imgs = [img0, img1, img2, img3, img4, img5, img6, img7, img8] titles = ['原图', '灰度图', '毛玻璃特效', '浮雕特效', '素描特效', '怀旧特效', '流年特效', '水波特效', '卡通特效'] for i in range(9): imgs[i] = cv2.cvtColor(imgs[i], cv2.COLOR_BGR2RGB) plt.subplot(3, 3, i + 1) plt.imshow(imgs[i]) plt.title(titles[i]) plt.xticks([]) plt.yticks([]) plt.suptitle('图像特效处理') plt.savefig('E:\From Zhihu\For the desk\cvfifteenresult.jpg', dpi = 1080) plt.show()
得到最终的总图 :
9. 总体代码
修改一下图像读取路径就可以使用了。还是那句话,建议从头慢慢来一遍,当然如果你只是想给女朋友生成一张素描或者浮雕的话那就无所谓了哈哈哈。
""" Author:XiaoMa date:2021/11/16 """ import cv2 import numpy as np import math import matplotlib.pyplot as plt img0 = cv2.imread('E:\From Zhihu\For the desk\cvfifteen1.jpg') img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY) h, w = img0.shape[:2] print(h, w) cv2.imshow("W0", img0) cv2.imshow("W1", img1) cv2.waitKey(delay = 0) #毛玻璃特效 img2 = np.zeros((h - 6, w - 6, 3), np.uint8) #生成的全零矩阵考虑到了随机数范围,变小了 for i in range(0, h - 6): #防止下面的随机数超出边缘 for j in range(0, w - 6): index = int(np.random.random()*6) #0~6的随机数 (b, g, r) = img0[i + index, j + index] img2[i, j] = (b, g, r) cv2.imshow("W2", img2) cv2.waitKey(delay = 0) #浮雕特效(需要对灰度图像进行操作) img3 = np.zeros((h, w, 3), np.uint8) for i in range(0, h): for j in range(0, w - 2): #减2的效果和上面一样 grayP0 = int(img1[i, j]) grayP1 = int(img1[i, j + 2]) #取与前一个像素点相邻的点 newP = grayP0 - grayP1 + 150 #得到差值,加一个常数可以增加浮雕立体感 if newP > 255: newP = 255 if newP < 0: newP = 0 img3[i, j] = newP cv2.imshow("W3", img3) cv2.waitKey(delay = 0) #素描特效 img4 = 255 - img1 #对原灰度图像的像素点进行反转 blurred = cv2.GaussianBlur(img4, (21, 21), 0) #进行高斯模糊 inverted_blurred = 255 - blurred #反转 img4 = cv2.divide(img1, inverted_blurred, scale = 127.0) #灰度图像除以倒置的模糊图像得到铅笔素描画 cv2.imshow("W4", img4) cv2.waitKey(delay = 0) #怀旧特效 img5 = np.zeros((h, w, 3), np.uint8) for i in range(0, h): for j in range(0, w): B = 0.272 * img0[i, j][2] + 0.534 * img0[i, j][1] + 0.131 * img0[i, j][0] G = 0.349 * img0[i, j][2] + 0.686 * img0[i, j][1] + 0.168 * img0[i, j][0] R = 0.393 * img0[i, j][2] + 0.769 * img0[i, j][1] + 0.189 * img0[i, j][0] if B > 255: B = 255 if G > 255: G = 255 if R > 255: R = 255 img5[i, j] = np.uint8((B, G, R)) cv2.imshow("W5", img5) cv2.waitKey(delay = 0) #流年特效 img6 = np.zeros((h, w, 3), np.uint8) for i in range(0, h): for j in range(0, w): B = math.sqrt(img0[i, j][0]) *14 # B通道的数值开平方乘以参数14 G = img0[i, j][1] R = img0[i, j][2] if B > 255: B = 255 img6[i, j] = np.uint8((B, G, R)) cv2.imshow("W6", img6) cv2.waitKey(delay = 0) #水波特效 img7 = np.zeros((h, w, 3), np.uint8) wavelength = 20 #定义水波特效波长 amplitude = 30 #幅度 phase = math.pi / 4 #相位 centreX = 0.5 #水波中心点X centreY = 0.5 #水波中心点Y radius = min(h, w) / 2 icentreX = w*centreX #水波覆盖宽度 icentreY = h*centreY #水波覆盖高度 for i in range(0, h): for j in range(0, w): dx = j - icentreX dy = i - icentreY distance = dx * dx + dy * dy if distance > radius * radius: x = j y = i else: # 计算水波区域 distance = math.sqrt(distance) amount = amplitude * math.sin(distance / wavelength * 2 * math.pi - phase) amount = amount * (radius - distance) / radius amount = amount * wavelength / (distance + 0.0001) x = j + dx * amount y = i + dy * amount # 边界判断 if x < 0: x = 0 if x >= w - 1: x = w - 2 if y < 0: y = 0 if y >= h - 1: y = h - 2 p = x - int(x) q = y - int(y) # 图像水波赋值 img7[i, j, :] = (1 - p) * (1 - q) * img0[int(y), int(x), :] + p * (1 - q) * img0[int(y), int(x), :] + (1 - p) * q * img0[int(y), int(x), :] + p * q * img0[int(y), int(x), :] cv2.imshow("W7", img7) cv2.waitKey(delay = 0) #卡通特效 num_bilateral = 7 #定义双边滤波的数目 for i in range(num_bilateral): #双边滤波处理 img_color = cv2.bilateralFilter(img0, d = 9, sigmaColor = 5, sigmaSpace = 3) img_blur = cv2.medianBlur(img1, 7) # 中值滤波处理 img_edge = cv2.adaptiveThreshold(img_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize = 5, C = 2) #边缘检测及自适应阈值化处理 img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB) #转换回彩色图像 img8 = cv2.bitwise_and(img0, img_edge) #图像的与运算 cv2.imshow('W8', img8) cv2.waitKey(delay = 0) #将所有图像保存到一张图中 plt.rcParams['font.family'] = 'SimHei' imgs = [img0, img1, img2, img3, img4, img5, img6, img7, img8] titles = ['原图', '灰度图', '毛玻璃特效', '浮雕特效', '素描特效', '怀旧特效', '流年特效', '水波特效', '卡通特效'] for i in range(9): imgs[i] = cv2.cvtColor(imgs[i], cv2.COLOR_BGR2RGB) plt.subplot(3, 3, i + 1) plt.imshow(imgs[i]) plt.title(titles[i]) plt.xticks([]) plt.yticks([]) plt.suptitle('图像特效处理') plt.savefig('E:\From Zhihu\For the desk\cvfifteenresult.jpg', dpi = 1080) plt.show()
以上是“Python如何处理图像特效”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/114461.html