opencv-python常见方法使用教程(二)


前言

接着上篇文章
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)

运行结果
在这里插入图片描述


总结

累了。。。下次继续

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值