OpenCv图像处理笔记总结

画图

import numpy as np
import cv2
import matplotlib.pyplot as plt
# 显示图片
def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

# 画直线;image:在该图像上绘制直线;(0, 0):直线起点; (300, 300):直线终点; green:直线颜色; 3:线的粗线
green = (0, 255, 0)
cv2.line(image, (0, 0), (300, 300), green, 3) 

# 画矩形;(50, 50):矩形左上角坐标;(100, 100):矩形右下角坐标;blue:矩形框颜色;5:矩形粗细, 如果是负值,则是填充效果
red = (255, 0, 0)
cv2.rectangle(image, (50, 50), (100, 100), blue, 5)

# 画圆形; (cX, cY)是圆中心; r是半径; white是线颜色; 2是线宽
image = np.zeros((300, 300, 3), dtype = 'uint8')
(cX, cY) = image.shape[1]//2, image.shape[0]//2
cv2.circle(image, (cX, cY), r, white, 2)

几何变换

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread('test.jpg')
# 翻转 -1:水平垂直翻转  0:垂直翻转  1:水平翻转
image = cv2.flip(image, 0)

# 裁剪
image = image[0:200, 300:500]

# 图像加减法
cv2.add(np.uint8([200]), np.uint8([100])) # 超过255,则取255
cv2.subtract(np.uint8([50]), np.uint8([100])) # 小于0,则取0
M = np.ones(image.shape, dtype='uint8')*100
cv2.add(image, M) # 所有像素加100

# 按位计算
rectangle = np.zeros((300, 300, 3), dtype='uint8')
white = (255, 255, 255)
cv2.rectangle(rectangel, (25, 25), (275, 275), white, -1)
circle = np.zeros((300, 300, 3), dtype='uint8')
cv2.circle(circle, (150, 150), 150, white, -1)
image = cv2.bitwise_and(rectangle, circle) # 按位与
image = cv2.bitwise_or(rectangle, circle)  # 按位或
image = cv2.bitwise_xor(rectangke, circle) # 异或:相同为0,不同为1
image = cv2.bitwise_not(circle)            # 取非

# 遮挡
masK = np.zeros(image.shape, dtype='uint8')
white = (255, 255, 255)
cv2.rectange(mask, (50, 50), (250, 350), white, -1)
masked = cv2.bitwise_and(image, mask)

# 切分、合并
(R, G, B) = cv2.split(image)
merged = cv2.merge([R, G, B])

# 高斯图像金字塔
image = cv2.pyrDown(image) # 降低分辨率
image = cv2.pyrUp(image) # 增大分辨率
# 拉普拉斯图像金字塔, 主要用来提取物体边界轮廓
down_image1 = cv2.pyrDown(image)
down_image2 = cv2.pyrDown(down_image1)
up_image = cv2.pyrUp(down_image2)
laplace_image = down_image1 - up_image

形态学

# 结构元素可以是矩形/椭圆/十字形,通过cv2.getStructuringElement()获取
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))    # 矩形
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 椭圆
kernel3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))   # 十字形

# Erosion腐蚀,通过结构元素在原图小区域内取局部最小值,作用是可以去掉图像中白色的小点
erosion = cv2.erode(image, kernel1, iterations = 2) # iterations代表腐蚀次数

# Dilation膨胀,通过结构元素在原图小区域内取局部最大值,作用是将图像中白色的点变大
dilation = cv2.dilate(image, kernel1, iterations = 2) # iterations代表腐蚀次数

# Opening开运算(先腐蚀后膨胀),消除小白点
image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel1)

# Closing闭运算(先膨胀后腐蚀),消除小黑点
image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel1)

# 先开运算,后闭运算 将会同时去除黑点、白点噪点
image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel1)
image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel1)

# Gradient形态学梯度(dilation - erosion), 得到物体的轮廓
gradient = cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel1)

# TopHat/WhiteHat 顶帽/白帽 原图-开运算图 显示去除的白色部分
WhiteHat = cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel1)
# BlackHat 黑帽 闭运算图-原图 显示去除的黑色部分
BlackHat = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel1)

图像平滑

# Averaging平均
kernelsizes = (3, 3)
blur = cv2.blur(image, kernel)

# Gaussian高斯模糊(kernel是一个高斯分布的权重系数,方框中心的系数值最大,高斯模糊就是求加权平均)
# 高斯模糊只考虑像素之间的空间关系,不考虑像素值之间的关系,因此边界会被模糊掉
blur = cv2.GaussianBlur(image, kernel, 0) # 第三个参数是标准差

# Median中值模糊(求卷积核内的中值)
blur = cv2.medianBlur(image, kernel)

# Bilateral双边滤波,作用是能够保持边界清晰的情况下有效去除噪音
# Bilateral双边滤波同时使用空间高斯权重、灰度值相似性高斯权重
# 空间高斯函数:确保只有邻近区域的像素对中心点有影响;灰度值相似性高斯函数:确保只有与中心像素灰度值相近的才会被用来做模糊运算
# diameter邻域直径, sigmaColor灰度值相似性高斯函数标准差, sigmaSpace空间高斯函数标准差
image = cv2.bilateralFilter(image, diameter, sigmaColor, sigmaSpace)  

颜色空间转换

import cv2
# RGB
image = cv2.imread('test.jpg')
(R, G, B) = cv2.split(image)
zeros = np.zeros(image.shape[:2], dtype='uint8')
cv2.merge([R, zeros, zeros]) # 注意:如果不采用这种方式显示,将是灰度图
cv2.merge([zeros, G, zeros])
cv2.merge([zeros, zeros, B])

# HSV, H(hue):色调  S(saturation):饱和度  V(value):明度
# 色调H:取值范围0°-360°,红色为0°,绿色为120°,蓝色为240°
# 饱和度S:表示颜色接近光谱色的程度,饱和度高,颜色则深而艳,取值范围0%-100%
# 明度V:表示颜色明亮的程度,取值范围为0%(黑)到100%(白)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)

# GrayScale
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

二值化

# 二值化:将图片转换成只有white和black颜色
image = cv2.imread('test.jpg')
gray = cv2.cvtColor(iamge, cv2.COLOR_BGR2GRAY)
# 二值化处理方式:cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV
# 图像:gray  阈值:127  最大值:255  
ret1, img= cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 自动设置二值化全局阈值
ret1, img= cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 自适应阈值 
# cv2.ADAPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值; cv2.ADAPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域的加权和,权重为高斯窗口:; 
# Block Size:邻域大小; C:常数,阈值就等于平均值或加权平均值减去这个常数
img = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 3)

图像梯度

# Laplacian算子, 卷积核:[[0 1 0], [1 -4 1], [0 1 0]]
image = cv2.imread('test.jph')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
laplacian = cv2.Laplacian(image, cv2.CV_64F)

# Sobel算子,x方向算子核:[[-1 0 1], [-2 0 2], [-1 0 1]]; y方向算子核:[[-1 -2 -1], [0 0 0], [1 2 1]]
# x方向求导数:这里是0代表求一阶导数,最大求二阶导
# y方向求导数:这里是1代表求二阶导数
# 如果ksize = -1,则转为Scharr算子,x方向算子核:[[-3 0 3], [-10 0 10], [-3 0 3]]; y方向算子核:[[-3 -10 3], [0 0 0], [3 10 3]]
sobelx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)

Canny边缘检测

  • 一种流行的边缘检测算法,是John F.Canny在1986年提出的。由四步组成:噪声去除、计算图像梯度、非极大值抑制、滞后阈值
# 第一个参数:输入图像
# 第二个参数:minVal
# 第三个参数:maxVal
# 第四个参数:Sobel卷积核大小,默认是3
# 第五个参数:L2gradient(默认False), 用来设定梯度大小的方程,True采用G=sqrt(Gx^2+Gy^2), False采用G=Gx^2+Gy^2
image = cv2.Canny(image, minVal, maxVal)

# 自动设置阈值的Canny检测, 这里sigma一般默认取0.33
v = np.median(image)
minVal = int(max(0, (1.0-sigma)*v))
maxVal = int(min(255, (1.0+sigma)*v))
image = cv2.Canny(image, minVal, maxVal)

视频操作

# 从文件读取视频内容
cap = cv2.VideoCapture('test.mp4')
# 每一帧图片
ret, frame = cap.read() # ret为True代表获取成功
# 视频每秒传输帧数
fps = cap.get(cv2.CAP_PROP_FPS)
# 视频图像的宽度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# 视频图像的高度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 设置读取到的图像大小
ret = cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
ret = cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

# 保存视频方法
# 1.创建VideoWrite对象
# 2.指定FourCC编码(4字节码,可用的编码形式可以去fourcc.org查询):XVID-比较合适,MJPG-小视频,X264-大视频
# 3.播放帧率;播放帧的width、height;isColor: True代表彩色,False代表灰度
fourcc = cv2.VideoWrite_fourcc(*'XVID')
out = cv2.VideoWrite('output.avi', fourcc, fps, (width, height))
out.write(frame)

# 从摄像头读取视频内容
cap = cv2.VideoCapture(0) # 0表示从摄像头获取
# 检测摄像头是否成功初始化
cap.isOpened()
# 如果初始化有问题,用下面这个函数做摄像头初始化
cap.open()

# 不断刷新图像,单位ms,返回值是当前键盘按键值
cv2.waitKey(1) 

人脸检测

  • 《Rapid Object Detection using a Boosted Cascade of Simple Features》
image = cv2.imread('test.jpg')
# 级联分类器
# xml配置文件可以从github中下载https://github.com/opencv/opencv/tree/master/data/haarcascades
detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
# image:输入图像
# scaleFactor=1.1 代表每次缩小图像的比例,默认是1.1
# minNeighbors=3 匹配成功所需要的周围矩形框的数目,人脸默认是3
# minSize: 匹配人脸的最小范围
# flags:
    # CASCADE_DO_CANNY_PRUNING:利用canny边缘检测排除一些边缘很少或者很多的图像
    # CASCADE_SCALE_IMAGE:正常比例检测
    # CASCADE_FIND_BIGGEST_OBJECT:只检测最大的物体
    # CASCADE_DO_ROUGH_SEARCH:粗略的检测
rects = detector.detectMultiScale(image, scaleFactor, minNeighbors, 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)
# 关闭摄像头
cap.release()
# 在图片上写标签
cv2.putText(image, 'label', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

实时人脸检测

import cv2 as cv
import numpy as np

cap = cv.VideoCapture(0)
if not cap.isOpened():
    cap.open(0)
while True:
    ret, frame = cap.read()
    # 注意xml文件可以从github中下载获得,并放在该执行文件同级目录下
    # https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml
    detector = cv.CascadeClassifier('haarcascade_frontalface_alt.xml')
    rects = detector.detectMultiScale(frame, 1.1, 3, minSize=(10,10),flags=cv.CASCADE_SCALE_IMAGE)
    for (x, y, w, h) in rects:
        cv.rectangle(frame,(x,y),(x+w, y+h),(0,255,0),2)
    cv.imshow("image",frame)
    if cv.waitKey(1) == ord('e'):
        break
cap.release()
cv.destroyAllWindows()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值