关于python下的opencv简单使用

1. 取色,显示灰度图
对于Opencv,存储一张彩色图片等同于存储三张灰度图(范围为0-255)
三张灰度图存储在图像数据的第三个维度上,对颜色的存储数据与RGB相反

1
2
3
cv2.imshow("blue", image[:, :, 0])
cv2.imshow("green", image[:, :, 1])
cv2.imshow("red", image[:, :, 2])

2. 彩色图像的灰度变换算法
将三个彩色通道的图像作平方和加权平均
其图像也可视作相机cmos芯片上接受光子数的分布图

1
2
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)

3. 图像的裁剪
使用索引号取出图像的一部分
索引顺序为先横行后纵列

1
2
crop = image[100:150, 100:150]
cv2.imshow('image', crop)

4. Opencv的绘制功能,需要使用numpy工具包
Opencv 图像数据,实际是numpy数组

1
2
3
4
5
6
7
8
9
10
11
12
import cv2
import numpy as np
image = np.zeros([300, 300, 3], np.uint8)
#空白画布
#300 行、300 列,且每个元素有 3 个通道的矩阵
#np.uint8 表示无符号 8 位整数,取值范围是 0 到 255,这也是图像数据中常用的数据类型
cv2.line(image, (0, 0), (300,300), (255,0,0), 1)
#线段的,起点坐标,终点坐标,颜色,粗细
#这里的color=(255,0,0)指的是,blue为255
cv2.rectangle(image, (0, 20), (20,40), (0,255,0), 2)
cv2.circle(image, (20, 20), 20, (0,0,255), 1)#粗细为负,表示填充
cv2.putText(image, "hello", (100,50), 0,1,(255,255,255))

5. Opencv的均值滤波
使用均值滤波器处理图片中的噪点

1
2
3
4
5
6
guess = cv2.GaussianBlur(image,(5,5),0)
#最后一个数,意为sigma由内核大小决定
#高斯滤波器——噪点减少,但也破坏图像细节
median = cv2.medianBlur(image,5)
#噪点进一步减少
# 一般图片只会有少数噪点,用均值滤波消除,方便后续图片操作

6. 图像特征的提取

1
2
3
4
5
6
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#先转成灰度
corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 5)
for corner in corners:
x, y = corner.ravel()
cv2.circle(image, (int(x), int(y)), 1, (0, 0, 255), -1)
#通过绘制圆来标记特征点

7. 模板匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
template = gray[75:105, 235:265]
#挑出特征区域
match = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
#cv2.TM_CCOEFF_NORMED为标准相关匹配算法,将两个图像标准化,再计算匹配度

locations = np.where(match >= 0.9)
#locations里含有多个匹配上的特征模板的位置坐标
w, h = template.shape[0:2]#得到template的长和宽
for p in zip(*locations[::-1]):
#注意python中数组调用方法
#[::-1] 是 Python 中切片操作的一种写法,它的作用是将 locations 进行反转。例如,如果 locations = [1, 2, 3],那么 locations[::-1] 的结果就是 [3, 2, 1]
#* 是 Python 中的解包运算符。它的作用是将 locations[::-1] 这个可迭代对象中的元素解包出来。假设 locations = [[1, 2], [3, 4]],那么 locations[::-1] 为 [[3, 4], [1, 2]],*locations[::-1] 就会把 [3, 4] 和 [1, 2] 作为独立的参数传递给后续的函数或操作。
#zip() 是 Python 的内置函数,它接受多个可迭代对象作为参数,将这些可迭代对象中对应位置的元素打包成一个个元组,然后返回由这些元组组成的迭代器。例如,zip([1, 2], [3, 4]) 会返回一个迭代器,迭代器中的元素为 (1, 3) 和 (2, 4)。结合前面的解包操作,zip(*locations[::-1]) 会对反转后的 locations 中每个可迭代元素进行对应位置的打包。
x1, y1 = p[0], p[1]
x2, y2 = x1 + w, y1 + h
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
#此方法对大小敏感。若要找出所有大小的,则放缩图片多试几次

8. 图像的梯度算法
图像梯度 = 图像明暗变化
所以,颜色变化越迅速,即梯度下降越快,颜色越浅
(在灰度图下,则可以用作边缘检测)

1
2
3
4
5
6
7
image = cv2.imread('opencv_logo.jpg', cv2.IMREAD_GRAYSCALE)

laplacian = cv2.Laplacian(image, cv2.CV_64F)
#拉普拉斯算子,大致对应图像的二阶导数
canny = cv2.Canny(image, 100, 200)
#卡尼算法,使用梯度区间来定义边缘
#梯度大于200,确定为边缘。小于100,确定为非边缘

9. 阈值算法
即二值化算法,将灰度图像分为黑与白
*注意Photoshop与opencv的共通

1
2
3
4
5
6
7
ret, thresh = cv2.threshold(image, 10, 255, cv2.THRESH_BINARY)
#阈值为10,最大灰度255
binary_adaptive = cv2.adaptiveThreshold(image, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,115,1)
#分区域,每个区域设置不同自适应阈值
ret1, binary_otsu = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
#大金算法,不需要人为的确定阈值——聚类分析算法

10. 图像形态学(其中的腐蚀与膨胀)
操作需要基于二值化图像
腐蚀与膨胀,常用于清理图像边缘细节
交替使用腐蚀与膨胀,可以获得更多细节,比如封闭与空腔

1
2
3
4
5
6
7
_, binary = cv2.threshold(image, 200, 255, cv2.THRESH_BINARY_INV)
#二值化,使用反向阈值
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(binary, kernel, iterations=1)
#使用kernel来腐蚀binary
dilation = cv2.dilate(binary, kernel, iterations=1)
#使用kernel来膨胀binary

11. 使用电脑的摄像头

1
2
3
4
5
6
7
8
9
capture = cv2.VideoCapture(0)
#摄像头序号
while True:#重复读取每一帧
ret, frame = capture.read()
cv2.imshow('camera',frame)
key = cv2.waitKey(1)
if key != -1:
break
capture.release()