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

  1. 打开摄像头
  2. 颜色空间转换
  3. 阈值分割:二值化(要么变成0要么变成255)
  4. 图像几何变化
  5. 绘图
  6. 图像混合
  7. 图像平滑(卷积/滤波/模糊/降噪):模糊/平滑图片消除图片噪声
    卷积是滤波的数学基础,滤波和模糊都属于卷积,只是卷积核不同
    低通道滤波器就是允许低频信号通过,在图像中边缘与噪点都相当于高频部分,所以低频滤波器用于去除噪点(降噪的原理是使用了低频滤波器)、平滑和模糊图像。
    高频滤波器则反之,用来增强图像边缘,进行锐化处理
  1. 均值滤波:用权重相同的二维卷积核对图像进行滤波,使图像平滑或模糊(求像素的均值)
  2. 高斯滤波(求像素权重):卷积核的中间像素点权重越高,越远离中心像素权重越小(标准正态分布)
  3. 中值滤波(求像素中位数):所有像素元素排序后取中间值,用中值来代替本像素值,适用于去除斑点噪声
  1. 腐蚀与膨胀:针对图像中白色去做
  1. 腐蚀:原理是在原图的小区域内取局部最小值,因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0
  2. 膨胀:原理与腐蚀相反
  1. 轮廓操作
  2. 直方图
  3. 模板匹配(大图中找小图)
  4. 霍夫变换(提取直线、圆)