opencv是开源计算机视觉库,提供了很多图像处理常用的工具
opencv安装
pip3 install opencv-python
pip3 install opencv-contrib-python
opencv基础操作
import cv2 as cv
#读图片
original = cv.imread('xx/xx.jpg')
print(original.shape) #打印图像的维度信息,第三维表示b(blue)g(green)r(red)
print(original[0,0]) #打印出第一个像素的三维数组信息
#显示图像窗口,但是不阻塞,打开就关掉了
cv.imshow('original',original) #第一个参数为窗口的标题
#切出蓝色通道的数据
blue = np.zeros_like(original)
#将original图像的blue通道的数据赋值给blue图像
blue[:,:,0] = original[:,:,0]
cv.imshow('blue',blue)
#图像裁剪
#获取原图的高和宽
h,w = original.shape[:2]
#求新图像的top和bottom像素位置
t,b = int(h/4),int(h*3/4)
#求新图像的left和right像素位置
l,r = int(w/4),int(w*3/4)
cropped = original[t:b,l:r]
cv.imshow('cropped',cropped)
#图像缩放,第二个参数为缩放后生成的图像的像素数量
resize1 = cv.resize(cropped,(150,100))
cv.imshow('resize1',resize1)
#图像放大,将图像沿x轴和y轴按比例放大4倍
cv.resize(original,None,fx=4,fy=4)
cv.imshow('resize2',resize2)
#图像保存
cv.imwrite(resize1,'resize1.jpg')
#阻塞不让打开的图像关闭
cv.waitKey()
边缘检测
物体的边缘检测是物体识别常用手段
通过识别亮度梯度变化最大的像素点从而检测出物体的边缘
常用边缘检测算法相关API
#索贝尔边缘识别
cv.Sobel(original, cv.CV_64F, True, False, ksize=5)
#参数:
#第一个参数:一般传入灰度图,不需要彩色图
#cv.CV_64F:卷积运算使用数据类型为64位浮点型(保证微分的精度)
#第三个参数:水平方向是否做边缘识别,Ture为做
#第四个参数:垂直方向是否做边关检测
#ksize:卷积核为5*5的方阵
#拉普拉斯边缘识别
cv.Laplacian(original, cv.CV_64F)
#Canny边缘识别(效果好)
#50:水平方向阈值 240:垂直方向阈值
cv.Canny(original, 50, 240)
亮度提升
用直方图均衡化的方式实现亮度提升,有利于边缘识别与物体识别模型的训练,属于图像处理的预处理
直方图就是摄影上的直方图,横坐标表示图像亮度,纵坐标表示该亮度下像素的数量
直方图均衡化:将暗部偏高的像素均衡到亮部去
直方图均衡化API
import cv2 as cv
original = cv.imread('../xx.jpg')
cv.imshow('orignal',original)
#将彩色图的通道模式(第三维)转为灰度模式,第二个参数是大写,所以是常量,返回值为灰度图像
gray = cv.cvcolor(original,COLOR_BGR2GRAY)
#直方图均衡化
equalized_gray = cv.equalizeHist(gray)
cv.waitKey()
示例:对图像的YUV格式(亮度,色度,饱和度)进行亮度均衡化
#将图像的通道模式转为亮度,色度,饱和度模式,返回值为YUV模式的图像
yuv = cv.cvtColor(original, cv.COLOR_BGR2YUV)
#对颜色通道进行亮度均衡化
yuv[:,:,0] = cv.equalizeHist(yuv[:,:,0])
#将图像的模式转回bgr模式
color = cv.cvtColor(yuv,cv.COLOR_YUV2BGR)
cv.imshow('color',color)
cv.waitKey()
角点检测
角点:平直棱线的交汇点(颜色梯度方向改变的像素点的位置)
API
gray = cv.cvtColor(original, cv.COLOR_BGR2GRAY)
#创建Harris角点检测器
corners = cv.cornerHarris(gray, 7, 5, 0.04)
#参数:
#第二个参数:边缘水平方向颜色值改变超过阈值7时即为边缘
#第三个参数:边缘垂直方向颜色值改变超过阈值5时即为边缘
#第四个参数:边缘线方向改变超过阈值0.04弧度即为一个角点
案例
import cv2 as cv
original = cv.imread('../xxx.png')
cv.imshow('Original', original)
#将彩图转为灰度模式
gray = cv.cvtColor(original, cv.COLOR_BGR2GRAY)
cv.imshow('Gray', gray)
#创建角点检测器,返回值是一个标注角点(角点处明度不为0)的图片,维度尺寸和原图一致
corners = cv.cornerHarris(gray, 7, 5, 0.04)
print(gray.shape,corners.shape)
#将corners图像的角点处的明度调大,方便查看
corners[corners > corners.max()*0.01] =255
cv.imshow('corners',corners)
#将角点标注和原始图像混合在一块
mixture = original.copy()
mixture[corners > corners.max() * 0.01] = [0, 0, 255]
cv.imshow('Corner', mixture)
cv.waitKey()
特征点检测(可以提取出特征点信息)
图像的特征点(辨认这个图像是什么的特征)
常用特征点检测有:START特征点检测、SIFT特征点检测
特征点检测结合了边缘检测与角点检测从而识别出图形的特征点。
STAR特征点检测API
import cv2 as cv
#创建START特征点检测器
star = cv.xfeatures2d.StarDetector_create()
# 检测出gray图像所有的特征点
keypoints = star.detect(gray)
# drawKeypoints方法可以把所有的特征点绘制在mixture图像中
cv.drawKeypoints(original, keypoints, mixture,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow('Mixture', mixture)
START方法案例
import cv2 as cv
original = cv.imread('../xx.jpg')
cv.imshow('Original', original)
gray = cv.cvtColor(original, cv.COLOR_BGR2GRAY)
cv.imshow('Gray', gray)
#创建特征点检测器
star = cv.xfeatures2d.StarDetector_create()
# 检测出gray图像所有的特征点
keypoints = star.detect(gray)
#创建原图的副本,用于将原图和特征点放在一起显示
mixture = original.copy()
cv.drawKeypoints(original, keypoints, mixture,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow('Mixture', mixture)
cv.waitKey()
SIFT特征点检测API
# 创建SIFT特征点检测器
sift = cv.xfeatures2d.SIFT_create()
keypoints = sift.detect(gray)
SIFT特征点检测API
import cv2 as cv
original = cv.imread('../xx.jpg')
cv.imshow('Original', original)
#转为灰度图
gray = cv.cvtColor(original, cv.COLOR_BGR2GRAY)
cv.imshow('Gray', gray)
#创建特征点检测器
sift = cv.xfeatures2d.SIFT_create()
keypoints = sift.detect(gray)
mixture = original.copy()
#把所有的特征点绘制在mixture图像中
cv.drawKeypoints(original, keypoints, mixture,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow('Mixture', mixture)
cv.waitKey()
特征点矩阵
特征点矩阵记录了图像的特征点以及每个特征点的梯度信息
只要有足够多的样本,就可以基于隐马尔可夫模型等进行图像内容的识别
API
#获取图像的特征点
sift = cv.xfeatures2d.SIFT_create()
keypoints = sift.detect(gray)
#第二个返回值就是特征值矩阵,特征值矩阵的shape是:(n,128)
_,desc = sift.compute(gray,keypoints)
#第一个参数是灰度图,第二个参数是获取到的特征点信息
案例
import cv2 as cv
import matplotlib.pyplot as mp
original = cv.imread('../xx.jpg')
cv.imshow('Original', original)
gray = cv.cvtColor(original, cv.COLOR_BGR2GRAY)
cv.imshow('Gray', gray)
sift = cv.xfeatures2d.SIFT_create()
keypoints = sift.detect(gray)
#获取特征值矩阵desc
_, desc = sift.compute(gray, keypoints)
print(desc.shape)
#显示特征值矩阵
cv.imshow('desc',desc)
cv.waitKey()
OpenCV其他使用
更多OpenCV常用方法见网站:ex2tron.wang
- 打开摄像头
- 颜色空间转换
- 阈值分割:二值化(要么变成0要么变成255)
- 图像几何变化
- 绘图
- 图像混合
- 图像平滑(卷积/滤波/模糊/降噪):模糊/平滑图片消除图片噪声
卷积是滤波的数学基础,滤波和模糊都属于卷积,只是卷积核不同
低通道滤波器就是允许低频信号通过,在图像中边缘与噪点都相当于高频部分,所以低频滤波器用于去除噪点(降噪的原理是使用了低频滤波器)、平滑和模糊图像。
高频滤波器则反之,用来增强图像边缘,进行锐化处理
- 均值滤波:用权重相同的二维卷积核对图像进行滤波,使图像平滑或模糊(求像素的均值)
- 高斯滤波(求像素权重):卷积核的中间像素点权重越高,越远离中心像素权重越小(标准正态分布)
- 中值滤波(求像素中位数):所有像素元素排序后取中间值,用中值来代替本像素值,适用于去除斑点噪声
- 腐蚀与膨胀:针对图像中白色去做
- 腐蚀:原理是在原图的小区域内取局部最小值,因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0
- 膨胀:原理与腐蚀相反
- 轮廓操作
- 直方图
- 模板匹配(大图中找小图)
- 霍夫变换(提取直线、圆)