此章节是基于本人OpenCV笔记-基础篇的延续,如果对此章节有疑惑的话,可以先看基础篇学习一下。
通过此篇可以学习到美图秀秀等P图软件实现图片效果原理及实现过程
灰度处理是图像处理的重要部分,大部分图像识别都需要使用到图像灰度处理
灰度处理则是对像素进行整合处理,将像素改为单一化数值:
左图为彩色图片像素,右图为灰色图片像素
可见彩色图片像素中的三基色比例数值改为灰度的单一数值
灰度图片中的RGB是相同的,R=G=B值
本人将讲解四种图像灰度处理方法:
图像读取命令:cv2.imread(filename,flags=None),将图像灰度化,则是将flags=0即可
程序示例:
import cv2
img = cv2.imread('imageTest.png',0)
cv2.imshow('img',img)
cv2.waitKey(0)
颜色空间转换函数:
cv2.cvtColor(src,code,dst=None,dstCn=None)
src:改变其颜色空间的图像
code:色彩空间转换代码,cv2.COLOR_BGR2GRAY为灰度转换代码
程序示例:
import cv2
img = cv2.imread('imageTest.png',1)
dst = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('dst',dst)
cv2.waitKey(0)
结果:
与上图灰度相似
灰度图像中的RGB是相同的,因此可以通过RGB求取平均值进行计算
公式:灰度值=(R+G+B)/3
步骤:1、读取图片;2、建立空白模板;3、求RGB平均值,填入模板
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):
for j in range(0,width):
(b,g,r) = img[i,j]
gray = (int(b)+int(g)+int(r))/3
dst[i,j] = np.uint8(gray)
cv2.imshow('dst',dst)
cv2.waitKey(0)
结果:
与以上灰度图片相似
心理学灰度计算公式:
gray = r × 0.299+g × 0.587+b × 0.114
步骤与第三种方法相同:
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#获取图像像素平均值
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):
for j in range(0,width):
(b,g,r) = img[i,j]
gray = int(r)*0.299+int(g)*0.587+int(b)*0.114
dst[i,j] = np.uint8(gray)
cv2.imshow('dst',dst)
cv2.waitKey(0)
结果:
与上图灰度图像相同
颜色反转原理:
获取图像像素信息RGB,使用满像素值 255 减该像素值
步骤:
1、读取图片;2、灰度处理,建立空模板;
3、获取像素,255-对应像素;4、填入模板
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度处理
dst = np.zeros((height,width,1),np.uint8)#建立空白模板
for i in range(0,height):
for j in range(0,width):
ger = gray[i,j]#获取对应像素
dst[i,j] = 255-ger#反转像素
cv2.imshow('dst',dst)
cv2.waitKey(0)
步骤与灰度反转相同,唯一不同则是可以选择三基色中任意一种或者几种进行反转
程序示例:(仅反转蓝基色)
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):
for j in range(0,width):
(b,g,r) = img[i,j] #获取像素BGR
b = 255-b #反转蓝基色
# g = 255-g 反转绿基色
# r = 255-r 反转红基色
dst[i,j] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
马赛克效果则是对范围像素进行同化效果:
如上图,将范围内的多种像素同化为一种像素
步骤:
1、读取图像;2、指定需要马赛克的范围
3、对需要马赛克的图像进行范围取值替代,如上图中取左上像素替代范围内全部像素
4、填入模板,显示图像
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
for m in range(100,300):
for n in range(100,200):
if m%10 == 0 and n%10 == 0:
for i in range(0,10):
for j in range(0,10):
(b,g,r) = img[m,n]
img[i+m,j+n] = (b,g,r)
cv2.imshow('dst',img)
cv2.waitKey(0)
程序解释:此取程序中各十个像素值为范围,十个像素中,取整除十的像素替代范围像素
结果:
此图黄花的左边便是马赛克范围
何为毛玻璃效果呢?
先展示图片:
毛玻璃效果则是使图片像素变得模糊。
图像毛玻璃效果原理与图像马赛克原理相似,都是通过改变指定范围内的像素达成效果的。但是改变的方式不同。
原理图:
图像毛玻璃原理实现是将图像中范围像素进行随机替换,如上图。
步骤流程:
1、读取图像;2、建立空模板,指定随机获取像素范围
3、对随机像素范围进行随机像素获取,并替换原像素
4、填入模板,显示图像
程序示例:
import cv2
import numpy as np
import random
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
mn = 8 #随机范围获取像素
for m in range(0,height-mn):
for n in range(0,width-mn):
index = int(random.random()*8)#random.random:随机生成[0,1)实数
(b,g,r) = img[m+index,n+index]
dst[m,n] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
程序解释:此为指定随机像素范围为8个像素,即在8个像素范围中,随机替换范围像素。
结果:
图片融合效果则是通过两个图片进行重叠混合。
实现步骤:
1、读取图片,获取图片信息
2、指定目标期望范围ROI(ROI范围不可超出两张图片的范围)
3、建立模板,使用cv2.addWeighted函数进行重叠
4、显示图片
重要函数:
cv2.addWeighted:图片混合与叠加
cv2.addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=None)
src1:输入第一张图片
alpha:第一张图片权重
src2:输入第二张图片
beta:第二张图片权重
gamma:亮度调节量
权重:图片所占比例,全值为1.0
程序示例1:
示例图片:
两张不同的图片
import cv2
import numpy as np
img0 = cv2.imread('imageTest.png',1)
img1 = cv2.imread('image1.jpg',1)
imgInfo = img0.shape
height = imgInfo[0]
width = imgInfo[1]
#ROI 目标期望范围
roiH = int(height/2)
roiW = int(width/2)
img0ROI = img0[0:roiH,0:roiW]
img1ROI = img1[0:roiH,0:roiW]
#dst
dst = np.zeros((roiH,roiW,3),np.uint8)
dst = cv2.addWeighted(img0ROI,0.5,img1ROI,0.5,0)
cv2.imshow('img0',img0)
cv2.imshow('img1',img1)
cv2.imshow('dst',dst)
cv2.waitKey(0)
程序解释:此为获取图片左上角四分之一进行重叠
结果:
程序示例2:(全图片重叠)
import cv2
import numpy as np
img0 = cv2.imread('imageTest.png',1)
img1 = cv2.imread('image1.jpg',1)
imgInfo0 = img0.shape
imgInfo1 = img1.shape
height = imgInfo1[0]
width = imgInfo1[1]
img0ROI = img0[0:height,0:width]
img1ROI = img1[0:height,0:width]
dst = np.zeros((height,width,3),np.uint8)
dst = cv2.addWeighted(img1ROI,0.3,img0ROI,0.7,0)
#add src1*a+src2*b 0:亮度调节量
cv2.imshow('dst',dst)
cv2.waitKey(0)
边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。
图片边缘检测在后期学习中是非常重要的部分,尤其是在特征处理分析中。
边缘检测示例:
左图为原图,右图为边缘检测图
边缘检测步骤:
1、读取图片,获取信息
2、灰度图像处理
3、高斯滤波降噪处理
4、cv2.Canny方法处理,显示图片
重要函数讲解:
cv2.GaussianBlur:高斯滤波函数,适用于消除高斯噪声,广泛用于图像处理的减噪过程。
cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
src:输入图像
ksize:高斯内核大小,必须为正数、奇数和零
sigmaX:X方向上的高斯核标准偏差
sigmaX:Y方向上的高斯核标准偏差,如不设置,则与sigmaX相同
cv2.Canny:边缘检测函数
因为此函数比较复杂,在此不过多见解,如想深入了解,可看此文章:Canny边缘检测算法
cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
image:输入原图,必须为单通道图(如灰度图片)
threshold1,threshold2:监测阀值,threshold1为下阀值,threshold2为上阀值。用于检测图像明显边缘值
apertureSize:Sobel算子的大小
程序示例:
import cv2
import numpy as np
import random
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#cv2.imshow('src',img)
#边沿检测:1、灰度图像处理;2、高斯滤波;3、canny方法
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
imgG = cv2.GaussianBlur(gray,(3,3),0)#高斯滤波,降噪(模糊化处理)。
dst = cv2.Canny(img,50,50)
#Canny:img:原图,50,50:上阀值与下阀值
cv2.imshow('img',img)
cv2.imshow('dst',dst)
cv2.waitKey(0)
结果:
注:调整阀值大小可使图片边缘性,阀值越高,图片边缘性越低。
sobel算法原理
sobel算法原理实现边缘
1、算子模板;2、图片卷积;3、阀值判决
算子模板:
y轴 x轴
[1 2 1 [ 1 0 -1
0 0 0 2 0 -2
-1 -2 -1 ] 1 0 -1 ]
图片卷积:
[1,2,3,4]:图像四个像素 [a b c d]:计算模板
a*1+b*2+c*3+d*4=dst
梯度运算:grad = sqrt(a*a+b*b)
阀值判决:
grad > th
实现步骤:
1、读取图片,获取信息
2、图像灰度处理,建立空白模板
3、运用sobel算法原理,判决阀值
4、显示图像
程序示例:
import cv2
import numpy as np
import random
import math
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst = np.zeros((height,width,1),np.uint8)
for i in range(0,height-2):
for j in range(0,width-2):
gy = gray[i,j]*1+gray[i,j+1]*2+gray[i,j+2]*1-gray[i+2,j]*1-gray[i+2,j+1]*2-gray[i+2,j+2]*1
gx = gray[i,j]+gray[i+1,j]*2+gray[i+2,j]-gray[i,j+2]-gray[i+1,j+2]*2-gray[i+2,j+2]
grad = math.sqrt(gx*gx+gy*gy)
if grad>50:
dst[i,j] = 255
else:
dst[i,j] = 0
cv2.imshow('dst',dst)
cv2.waitKey(0)
图像浮雕效果与图像边缘效果类似,通过像素差进行计算边缘。
图像浮雕示例:
上图便是图像浮雕效果,与图像边缘化非常相似。
图像浮雕效果实现原理:
提取相邻两个像素,gray[i,j]与gray[i,j+1]像素;
新gray[i,j]像素 = gray[i,j] - gray[i,j+1] + 150,150是灰度化值,此值越小,黑度越高,反则越白。
图像浮雕效果实现步骤:
1、读取图片,获取信息
2、图像灰度化,建立空白模板
3、获取相邻点,使用公式相减+灰度化值
4、显示结果图片
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# newP = gray0-gray1+150
dst = np.zeros((height,width,1),np.uint8)
for i in range(0,height):
for j in range(0,width-1):
grayP0 = int(gray[i,j])
grayP1 = int(gray[i,j+1])
newP = grayP0-grayP1+150
if newP>255:
newP = 255
if newP < 0:
newP = 0
dst[i,j] = newP
cv2.imshow('dst',dst)
cv2.waitKey(0)
此节讲颜色风格类似于美图秀秀中的滤镜,光暗调节等,这些功能都是通过修改像素所完成的。
获取图像RGB值,通过修改其中一个基色或多个基色倍数,从而达成滤镜效果
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
for i in range(0,height):
for j in range(0,width):
(b,g,r) = img[i,j]
b = b*1.3
g = g*1.3
if b>255:#当结果超出255界值后,修改为255值
b = 255
if g>255:
g = 255
dst[i,j] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
注:此程序修改RGB中,蓝基色与绿基色,使其都增长1.3倍,
结果:
左图为原图,右图为滤镜结果图
通过此对比可看出,修改蓝基色与绿基色后,图像色调偏蓝光。
其他滤镜效果皆是由此修改,读者可自行尝试
图像光暗效果调整也是修改像素中RGB值,不过不是单个修改,而是整体进行修改变换。
程序示例:
import cv2
import numpy as np
img = cv2.imread('imageTest.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
dst1 = np.zeros((height,width,3),np.uint8)
for i in range(0,height):
for j in range(0,width):
(b,g,r) = img[i,j]
b = b*1.2
b1 =b*0.5
g = g*1.2
g1 = g*0.5
r = r*1.2
r1 = r*0.5
if b>255:
b = 255
if g>255:
g = 255
if r>255:
r = 255
dst[i,j] = (b,g,r)
dst1[i,j] = (b1,g1,r1)
cv2.imshow('img',img)
cv2.imshow('dst1',dst1)
cv2.imshow('dst',dst)
cv2.waitKey(0)