文章目录
前言
接着上篇文章
opencv-python常见方法使用教程(一)
以下代码是底下示例的都会用到的方法
import cv2
import matplotlib.pyplot as plt
import numpy as np
def show(image):
"""显示图片"""
plt.imshow(image)
plt.axis('off')
plt.show()
def imread(image):
"""读取图片并转换色彩通道"""
image = cv2.imread(image)
image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
return image
一、人脸检测
OpenCV人脸识别效果很一般,但是使用简单,要求精度和效果还是建议使用深度学习框架
1、使用
代码如下:
image = imread('face.jpg')
# 级联分类器
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
rects = detector.detectMultiScale(image,scaleFactor=1.1,minNeighbors=3,minSize=(10,10),flags=cv2.CASCADE_SCALE_IMAGE)
for (x,y,w,h) in rects:
#画矩形框
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
show(image)
运行结果
2、说明
haarcascade_frontalface_default.xml 初学者可能找不到在哪里
这个文件点进 https://github.com/opencv/opencv/tree/master/data/haarcascades 下载
方法参数
- image:输入图像
- scaleFactor=1.1:这个是每次缩小图像的比例,默认是1.1
- minNeighbors=3:匹配成功所需要的周围矩形框的数目,每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3。
- minSize:匹配人脸的最小范围
- flags:可以取如下这些值:
- CASCADE_ DO_ CANNY PRUNING=1利用canny边缘检测来排除一 些边缘很少或者很多的图像区域
- CASCADE_ SCALE_ IMAGE=2, 正常比例检测
- CASCADE FIND_ BIGGEST OBJECT=4,只检测最大的物体
- CASCADE DO_ ROUGH_ SEARCH=8初略的检测
多说几句
其实用OpenCV检测人脸的效果并不是很好,只不过使用比较简单。
对精度要求高建议使用深度学习框架
二、图像平滑
原图
1.Averaging 平均
通过卷积核实现
代码如下:
# 3组卷积核
kernelsizes = [(3,3),(9,9),(15,15)]
plt.figure(figsize=(15,15))
for i,kernel in enumerate(kernelsizes):
# 一行三列的图
plt.subplot(1,3,i+1)
# 平均平滑
blur = cv2.blur(image,kernel)
plt.axis("off")
# 设置标题
plt.title("Blurred"+str(kernel))
plt.imshow(blur)
plt.show()
运行结果
2.高斯模糊
现在把卷积核换成高斯核(简单来说,方框不变,原来每个方框的值是相等的,现在里面的值是符合高斯分布的,方框中心的值最大,其余方框根据距离中心元素的距离递减,构成一个高斯小山包。原来的球平均数现在变成求加权平均数,权就是方框里的值)
代码如下:
kernelsizes = [(3,3),(9,9),(15,15)]
plt.figure(figsize=(15,15))
for i,kernel in enumerate(kernelsizes):
# 一行三列的图
plt.subplot(1,3,i+1)
# 平均平滑
blur = cv2.GaussianBlur(image,kernel,0)
plt.axis("off")
# 设置标题
plt.title("Blurred"+str(kernel))
plt.imshow(blur)
plt.show()
运行结果
3.Median中值模糊
用于卷积框对应像素的中值来代替像素点。可以去除白色黑色点
代码如下:
plt.figure(figsize=(15,15))
for i,kernel in enumerate((3,9,15)):
# 一行三列的图
plt.subplot(1,3,i+1)
# 平均平滑
blur = cv2.medianBlur(image,kernel)
plt.axis("off")
# 设置标题
plt.title("Blurred"+str(kernel))
plt.imshow(blur)
plt.show()
运行结果
4.Bilateral双边滤波
能在保持边界清晰的情况下有效的去除噪音。我们已经知道高斯滤波器是求中心点邻近区域像素的高斯加权平均值。这种高斯滤波器只考虑像素之间的空间关系。而不会考虑像素值之间的关系(像素的相似度)。所以这种方法不会考虑一个像素是否位于便捷。因此边界也会模糊掉,这不是我们想要的。
双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重。空间高斯函数确保只有邻近区域的像素对于中心有影响,灰度值相似高斯函数确保只有与中心像素灰度值相近的才会用来做模糊运算。所以这种方法会确保边界不会被模糊掉,因为边界处的灰度值变化比较大。
代码如下:
# 保证边界清晰的情况下,去除一些小的噪声
params = [(11,21,7),(11,41,21),(15,75,75)]
plt.figure(figsize=(15,15))
# 邻域致敬,灰度值相似性高斯函数标准差,空间高斯函数标准差
for i,(diameter,sigmaColor,sigmaSpace) in enumerate(params):
# 一行三列的图
plt.subplot(1,3,i+1)
# 平均平滑
blur = cv2.bilateralFilter(image,diameter,sigmaColor,sigmaSpace)
plt.axis("off")
# 设置标题
plt.title("Blurred"+str((diameter,sigmaColor,sigmaSpace)))
plt.imshow(blur)
plt.show()
运行结果
三、图像算数
1.图像加法
代码如下:
# 图像加法:最高只会到255,再往上也是返回255
print(cv2.add(np.uint8([200]),np.uint8([100])))
# 普通加法:uint8最高值只到255,再网上加就从零开始算,所以300的值会显示成 300-256 = 44
print(np.uint8([200])+np.uint8([100]))
运行结果
[[255]]
[44]
图像加法也可看成“调亮”
# 生成跟图片形状相同的并且全为100的矩阵
M = np.ones(image.shape,dtype='uint8')*100
# 所有的像素加100(变得更白,相当于调亮度变亮)
image = cv2.add(image,M)
show(image)
运行结果
2、图像减法
代码如下:
#图像减法:对于图像像素来说,最低只会到0
print(cv2.subtract(np.uint8([50]),np.uint8([100])))
#普通减法:实际上是为-50,但是uint8没有负数,只会从0再往下减,256-50=206
print(np.uint8([50])-np.uint8([100]))
运行结果
[[0]]
[206]
图像减法也可看成“调暗”
M = np.ones(image.shape,dtype='uint8')*100
# 所有的像素减100(变得更暗)
image = cv2.subtract(image,M)
show(image)
运行结果
3、按位运算
我们先定义两个图形
代码如下:
image = np.zeros((300,300,3),dtype='uint8')
white = (255,255,255)
cv2.rectangle(image,(25,25),(275,275),white,-1)
show(image)
image1 = np.zeros((300,300,3),dtype='uint8')
cv2.circle(image1,(150,150),150,white,-1)
show(image1)
运行结果
- bitwise_ and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行:二进制“与”操作,1&1=1,1&0=0, 0&1=0,0&0=0
- bitwise_or是对二进制数据进行“或"操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1, 1|0=1, 0|1=1,0|0=0
- bitwise_ xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像索值进行二进制“异或”操作,1 1=0,1 0=1,0 1=1,0 0=0
- bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像索值进行二进制“非”操作,^ 1=0, 0=1
代码如下:
# AND 与操作,有黑就变黑
image2 = cv2.bitwise_and(image,image1)
show(image2)
# OR 或操作,有白就变白
image2 = cv2.bitwise_or(image,image1)
show(image2)
# XOR 异或操作,黑白变白,黑黑和白白变成黑色
image2 = cv2.bitwise_xor(image,image1)
show(image2)
# NOT 非操作,颜色取反
image2 = cv2.bitwise_not(image1)
show(image2)
运行结果
四、切分合并通道
1、通道切分
代码如下:
(R,G,B)= cv2.split(image)
print(R.shape)
print(G.shape)
print(B.shape)
运行结果
(1024, 768)
(1024, 768)
(1024, 768)
展示不同通道图片
cv2.imshow('R',R)
cv2.imshow('G',G)
cv2.imshow('B',B)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果
2、通道合并
merged = cv2.merge([R,G,B])
show(merged)
运行结果
总结
累了。。。下次继续