一.OpenCv介绍
简介
OpenCV(Open Source Computer Vision Library:opencv官网地址)是一个开源的基于BSD许可的库,它包括数百种计算机视觉算法。文档OpenCV 2.x API描述的是C++ API,相对还有一个基于C语言的OpenCV 1.x API,后者的描述在文档opencv1.x.pdf中。
OpenCV具有模块化结构,这就意味着开发包里面包含多个共享库或者静态库。下面是可使用的模块:
-
核心功能(Core functionality) - 一个紧凑的模块,定义了基本的数据结构,包括密集的多维Mat数组和被其他模块使用的基本功能。
-
图像处理(Image processing) - 一个图像处理模块,它包括线性和非线性图像滤波,几何图形转化(重置大小,放射和透视变形,通用基本表格重置映射),色彩空间转换,直方图等。
-
影像分析(video) - 一个影像分析模块,它包括动作判断,背景弱化和目标跟踪算法。
-
对象侦查(objdetect) - 目标和预定义类别实例化的侦查(例如:脸、眼睛、杯子、人、汽车等等)。
highgui - 一个容易使用的用户功能界面。 -
视频输入输出(videoio) - 一个容易使用的视频采集和视频解码器。
-
GPU - 来自不同OpenCV模块的GPU加速算法。
-
- 3D校准(calib3d) - 基于多视图的几何算法,平面和立体摄像机校准,对象姿势判断,立体匹配算法,和3D元素的重建。
平面特征(features2d) - 突出的特征判断,特征描述和对特征描述的对比。
- 3D校准(calib3d) - 基于多视图的几何算法,平面和立体摄像机校准,对象姿势判断,立体匹配算法,和3D元素的重建。
-
… 一些其他的辅助模块,比如FLANN和谷歌的测试封装,Python绑定和其他。
安装OpenCv-python
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python |
---|
二.opencv基础操作
导入库
在Python中导入OpenCV库:
import cv2
1. 读取图像
使用cv2.imread()
读取图像:
image = cv2.imread('path_to_image.jpg')
# 显示图像
cv2.imshow('Image', image)
cv2.waitKey(0) # 等待键盘输入
2. 显示图像
cv2.imshow(arg1,arg2)
参数:
arg1:显示图像的窗口名称,以字符串类型表示
arg2:要加载的图像
cv2.imshow('Image', image)
cv2.waitKey(0)
3. 保存图像
cv2.imwrite(arg1,arg2)
参数:
- arg1:文件名,要保存在哪里
- arg2:要保存的图像
使用cv2.imwrite()
保存图像:
cv2.imwrite('output_image.jpg', image)
4. 图像基本属性
获取图像的基本属性(如高度、宽度和通道数):
height, width, channels = image.shape
print('Height:', height)
print('Width:', width)
print('Channels:', channels)
5. 改变图像大小
使用cv2.resize()
改变图像大小:
resized_image = cv2.resize(image, (width // 2, height // 2)) # 变成原尺寸的一半
三.绘制几何图像
1. 绘制直线:cv2.line()
cv2.line(img, pt1, pt2, color, thickness=1, lineType=8, shift=0)
- img: 要绘制的图像。
- pt1: 直线起点的坐标,格式为
(x, y)
。 - pt2: 直线终点的坐标,格式为
(x, y)
。 - color: 直线颜色,BGR格式,例如红色为
(0, 0, 255)
。 - thickness: 线条粗细,默认值为
1
。 - lineType: 线型,默认为
8
,表示8-connected线,还可以设置为cv2.LINE_AA
表示抗锯齿线。 - shift: 点坐标的小数点位数,默认值为
0
。
***注:opencv颜色为格式BGR,不是RGB
***
代码示列:
import cv2
import numpy as np
# 创建一个黑色背景图像
image = np.zeros((400, 400, 3), dtype=np.uint8)
# 绘制直线
cv2.line(image, (50, 50), (300, 300), (255, 0, 0), 2) # 蓝色线条
# 显示图像
cv2.imshow('Line', image)
cv2.waitKey(0)
cv2.destroyAllWindows() # 关闭窗口
2. 绘制矩形:cv2.rectangle()
cv2.rectangle(img, pt1, pt2, color, thickness=1, lineType=8, shift=0)
- img: 要绘制的图像。
- pt1: 矩形一个顶点的坐标,格式为
(x, y)
。 - pt2: 矩形对角顶点的坐标,格式为
(x, y)
。 - color: 矩形颜色,BGR格式。
- thickness: 矩形边框的粗细,默认值为
1
。如果设置为-1
,将填充矩形。 - lineType: 线型,保持跟直线一致。
- shift: 点坐标的小数点位数,默认值为
0
。
import cv2
import numpy as np
# 创建一个黑色背景图像
image = np.zeros((400, 400, 3), dtype=np.uint8)
# 绘制矩形
cv2.rectangle(image, (100, 100), (300, 200), (0, 255, 0), 3) # 绿色矩形
cv2.imshow("image",image)
cv2.waitKey()
cv2.destroyAllWindows()
3. 绘制圆:cv2.circle()
cv2.circle(img, center, radius, color, thickness=1, lineType=8, shift=0)
- img: 要绘制的图像。
- center: 圆心坐标,格式为
(x, y)
。 - radius: 圆的半径。
- color: 圆的颜色,BGR格式。
- thickness: 边框的粗细,默认值为
1
,设置为-1
将填充圆。 - lineType: 线型,通常为
8
或cv2.LINE_AA
。 - shift: 点坐标的小数点位数,默认值为
0
。
4. 绘制椭圆:cv2.ellipse()
cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness=1, lineType=8, shift=0)
- img: 要绘制的图像。
- center: 椭圆中心的坐标,格式为
(x, y)
。 - axes: 椭圆的长短轴长度,格式为
(长轴, 短轴)
。 - angle: 椭圆的旋转角度,单位为度。
- startAngle: 椭圆的起始角度,单位为度。
- endAngle: 椭圆的结束角度,单位为度。
- color: 椭圆颜色,BGR格式。
- thickness: 边框的粗细,默认为
1
,设置为-1
将填充椭圆。 - lineType: 线型,同上。
- shift: 点坐标的小数点位数,默认值为
0
。
# 绘制椭圆
cv2.ellipse(image, (200, 200), (100, 50), 0, 0, 180, (0, 255, 255), 2) # 黄色椭圆
cv2.imshow("image",image)
cv2.waitKey()
5. 绘制多边形:cv2.polylines()
和 cv2.fillPoly()
cv2.polylines()
cv2.polylines(img, pts, isClosed, color, thickness=1, lineType=8, shift=0)
- img: 要绘制的图像。
- pts: 顶点数组,格式为
np.array([[点1], [点2], ...])
。 - isClosed: 布尔值,表示多边形是否封闭。
- color: 多边形边框颜色,BGR格式。
- thickness: 边框的粗细,默认值为
1
。 - lineType: 线型,通常为
8
或cv2.LINE_AA
。 - shift: 点坐标的小数点位数,默认值为
0
。
import cv2
import numpy as np
image = np.zeros([500,500,3],dtype=np.uint8)
# 定义多边形的顶点
points = np.array([[100, 50], [200, 150], [100, 250], [0, 150]], np.int32)
print(points)
points = points.reshape((-1, 1, 2))
# 绘制多边形边框
cv2.polylines(image, [points], isClosed=True, color=(255, 0, 255), thickness=2)
cv2.imshow("image",image)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.fillPoly()
cv2.fillPoly(img, pts, color)
- img: 要绘制的图像。
- pts: 顶点数组,格式为
np.array([[点1], [点2], ...])
。 - color: 填充颜色,BGR格式。
import cv2
import numpy as np
image = np.zeros([500,500,3],dtype=np.uint8)
# 定义多边形的顶点
points = np.array([[100, 50], [200, 150], [100, 250], [0, 150]], np.int32)
print(points)
points = points.reshape((-1, 1, 2))
# # 填充多边形
cv2.fillPoly(image, [points], (255, 0, 255)) # 填充紫色
cv2.imshow("image",image)
cv2.waitKey()
cv2.destroyAllWindows()
#points.reshape((-1, 1, 2))
# -1 表示 NumPy 将根据原始数组的元素数量自动计算出第一个维度的大小。
# 由于原始 points 数组的形状为 (4, 2),其中有 4 * 2 = 8 个元素。我们需要将
#其重塑为 (n, 1, 2) 的形状。因为第二维和第三维已经确定为 1 和 2,所以 NumPy
#会计算出第一维的大小为 4,从而生成 points 的新形状 (4, 1, 2)。
6. 绘制文本:cv2.putText()
cv2.putText(img, text, org, fontFace, fontScale, color, thickness=1, lineType=8, bottomLeftOrigin=False)
- img: 要绘制文本的图像。
- text: 要绘制的文本字符串。
- org: 文本起始位置的坐标,格式为
(x, y)
。 - fontFace: 字体类型,可以是
cv2.FONT_HERSHEY_SIMPLEX
等。 - fontScale: 字体大小的缩放因子。
- color: 文本颜色,BGR格式。
- thickness: 文本的线条粗细,默认为
1
。 - lineType: 线型,通常为
8
或cv2.LINE_AA
。 - bottomLeftOrigin: 布尔值,表示是否将文本的起点视为左下角(默认是左上角)。
import cv2
import numpy as np
image = np.zeros([500,500,3],dtype=np.uint8)
cv2.putText(image,"你爹来了",(100,300),cv2.FONT_HERSHEY_SIMPLEX,1,color=(0,255,255))
cv2.imshow("image",image)
cv2.waitKey()
7.获取并修改图像中的像素点
import cv2
img = cv2.imread('1.jpg')
# 获取某个像素点的值
px = img[100,100]
print(px)
# 修改某个位置的像素值
img[100,100] = [0,0,255]
cv2.imshow("img",img)
cv2.waitKey(0)
8. 视频捕捉
从摄像头捕捉视频:
import cv2
cap = cv2.VideoCapture(0) # 0为默认摄像头
while True:
ret, frame = cap.read() # 读取一帧
# 检查读取是否成功
if not ret:
break
cv2.imshow('my Video ', frame)
if cv2.waitKey(1) & 0xFF == ord('q'): # 按‘q’退出
break
cap.release()
cv2.destroyAllWindows()
四.像素
-
像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。
-
常见的图像是RGB三原色图。RGB图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB三种颜色被称为RGB三通道,根据这三个通道存储的像素值,来对应不同的颜色
灰度图像:像素值:0-255之间。0:纯黑;255 白色
二值图像:像素值:0:黑 ; 1 白
好的!下面是对二值图像、灰度图和RGB图的详细介绍,包括它们的特性、使用场景以及如何在 OpenCV 中实现。
1. 二值图像
特性
- 定义:二值图像(Binary Image)是只包含两种像素值的图像,通常是 0(黑色)和 255(白色)。
- 像素值:每个像素的值可以是 0 或 1(在某些情况下是 0 或 255),表示黑或白。
- 存储效率:由于仅使用两个可能的值,二值图像的存储需求通常低于灰度图或RGB图。
使用场景
- 边缘检测:用于提取和强调图像边缘。
- 形态学操作:如膨胀、腐蚀,通常用于处理和分析形状。
- 光学字符识别(OCR):将文本图像转换为计算机可读的格式。
OpenCV 示例代码
import cv2
import numpy as np
# 创建一个二值图像
binary_image = np.zeros((300, 300), dtype=np.uint8)
cv2.circle(binary_image, (150, 150), 100, 255, -1) # 白色圆形
# 显示二值图像
cv2.imshow('Binary Image', binary_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 灰度图
特性
- 定义:灰度图(Grayscale Image)是通过将图像的每个像素映射到一个范围内的灰度值,通常在 0 到 255 之间,不同程度的黑白表示。
- 像素值:每个像素只有一个值,从黑到白的灰度级变化。
- 色彩信息:丢弃了颜色信息(RGB),只保留亮度信息。
使用场景
- 图像处理:许多图像处理算法(如边缘检测、图像分割)在灰度图上表现更好。
- 图像分析:用于人脸识别、物体检测等任务,通常优先采用灰度图。
OpenCV 示例代码
# 创建一个灰度图
gray_image = np.zeros((300, 300), dtype=np.uint8)
cv2.rectangle(gray_image, (50, 50), (250, 250), 128, -1) # 灰色矩形
# 显示灰度图像
cv2.imshow('Gray Image', gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. RGB 图
特性
- 定义:RGB图像使用红色(R)、绿色(G)和蓝色(B)三种颜色进行表示,通常每个颜色通道的值在 0 到 255 之间。
- 色彩信息:通过组合不同的 RGB 值,可以显示出丰富的颜色。
- 通道分离:可以将 RGB 图像分离为三个单独的通道,以便进行独立处理。
使用场景
- 数字摄影:几乎所有数字相机捕获的图像都是 RGB 格式。
- 计算机视觉:在深度学习和图像分析中普遍使用。
OpenCV 示例代码
# 创建一个 RGB 图像
rgb_image = np.zeros((300, 300, 3), dtype=np.uint8)
# 用蓝色填充整个图像
rgb_image[:] = [255, 0, 0] # BGR 格式 (蓝色)
# 显示 RGB 图像
cv2.imshow('RGB Image', rgb_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
五.二值图像处理
这些方法都与图像处理中的阈值化技术密切相关,用于将灰度图像转化为二值图像。
1. 最大值法
- 定义:将图像中所有像素的值与预设的最大值进行比较,像素值高于最大值的被设为白色(或1),低于的设为黑色(或0)。
- 应用:快速分割物体与背景,但对噪声敏感。
import cv2
import numpy as np
def max_thresholding(image, max_value):
_, binary_image = cv2.threshold(image, max_value, 255, cv2.THRESH_BINARY)
return binary_image
2. 平均值法
- 定义:计算图像的平均像素值,像素值高于平均值的被设为白色,低于的则设为黑色。
- 应用:适用于对比度较低的图像,简单易行。
3. 加权值法
- 定义:根据不同的权重计算像素值,可能会考虑不同通道的贡献,然后与某个阈值进行比较。
- 应用:在具有色彩信息的场合,可以更加灵活地处理目标,尤其是在对比度变化较大的情况下。
4. 阈值法(THRESH_BINARY)
- 定义:选择一个固定的阈值,像素值高于此阈值的设为白色,低于的设为黑色。
- 应用:常见的基本阈值化方法,简单易用。
5. 反阈值法(或称为双阈值法THRESH_BINARY_INV))
- 定义:使用两个不同的阈值来进行分割,像素值在高阈值以上的设为白色,低于低阈值的设为黑色,而介于两者之间的则没变化(通常保留为灰度或原值)。
- 应用:常用于边缘检测,能够更好地减少噪声影响。
6. 截断阈值法(THRESH_TRUNC)
- 定义:仅对高于某个阈值的像素赋予某个固定的值(如设为最大值或白色),低于阈值的像素则保持原有值。
- 应用:可以在视觉上突显图像中特定的亮度区域。
7. 低阈值零处理(THRESH_TOZERO)
- 定义:在低于某个阈值的像素被直接设为零(黑色),而高于阈值的像素值保持不变。
- 应用:用于消除低亮度噪声,突出高亮度区域。
8. 超阈值零处理(THRESH_TOZERO_INV)
- 定义:在高于某个阈值的像素被直接设为某个固定值,而低于此阈值的像素被设为零(黑色)。
- 应用:常用于强化高对比度的结构。
9. Otsu阈值法
- 定义:一种自动阈值选择方法,通过最大化类间方差来选择最佳阈值,将图像分为两部分。适用于双峰的灰度直方图。
- 应用:非常有效,尤其在处理背景和前景对比明确的图像时,常用于医学成像和缺陷检测。
import cv2
import numpy as np
#最大值法
def max_thresholding(image, max_value):
_, binary_image = cv2.threshold(image, max_value, 255,cv2.THRESH_BINARY)
return binary_image
#平均值法
def average_thresholding(image):
avg_value = np.mean(image)
_, binary_image = cv2.threshold(image, avg_value, 255,cv2.THRESH_BINARY)
return binary_image
#加权值法
def weighted_thresholding(image, weights):
weighted_image = cv2.transform(image, weights)
_, binary_image = cv2.threshold(weighted_image, np.mean(weighted_image), 255, cv2.THRESH_BINARY)
return binary_image
#阈值法
def simple_thresholding(image, threshold):
_, binary_image = cv2.threshold(image, threshold, 255, v2.THRESH_BINARY)
return binary_image
#反阈值法(双阈值法)
def double_thresholding(image, low_thresh, high_thresh):
binary_image = cv2.inRange(image, low_thresh, high_thresh)
return binary_image
#截断阈值法
def truncated_thresholding(image, threshold):
truncated_image = np.where(image > threshold, 255, image)
return truncated_image.astype(np.uint8)
#低阈值零处理
def low_thresh_zero(image, threshold):
processed_image = np.where(image < threshold, 0, image)
return processed_image.astype(np.uint8)
#超阈值零处理
def high_thresh_zero(image, threshold, fixed_value=255):
processed_image = np.where(image > threshold, fixed_value, 0)
return processed_image.astype(np.uint8)
#Otsu阈值法
def otsu_thresholding(image):
_, binary_image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return binary_image
if __name__ == "__main__":
image = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)
max_binary = max_thresholding(image, 128)
avg_binary = average_thresholding(image)
simple_binary = simple_thresholding(image, 128)
otsu_binary = otsu_thresholding(image)
cv2.imshow('Max Value Binary', max_binary)
cv2.imshow('Average Value Binary', avg_binary)
cv2.imshow('Simple Threshold Binary', simple_binary)
cv2.imshow('Otsu Binary', otsu_binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
1. 灰度图转换—cv2.cvtColor()
函数:cv2.cvtColor()
用来将彩色图像转换为灰度图像。
函数签名:
cv2.cvtColor(src, code)
参数解释:
src
:输入图像,通常是彩色图像。code
:转换代码,用于指定转换的类型。对于灰度图转换,使用cv2.COLOR_BGR2GRAY
或cv2.COLOR_RGB2GRAY
,这取决于图像的色彩空间(BGR 或 RGB)。
示例代码:
import cv2
# 读取彩色图像
color_image = cv2.imread('image.jpg')
# 转换为灰度图像
gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
# 显示图像
cv2.imshow('Gray Image', gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 二值化图像—cv2.threshold()
函数:cv2.threshold()
用来将灰度图像转换为二值图像。
函数签名:
cv2.threshold(src, thresh, maxval, type)
参数解释:
src
:输入的灰度图像。thresh
:阈值,像素值大于该阈值的将被设置为maxval
,否则设置为 0。maxval
:设置为thresh
之上的像素值。type
:阈值类型,常用的有:cv2.THRESH_BINARY
:大于阈值的像素值设置为maxval
,其余设置为 0。cv2.THRESH_BINARY_INV
:大于阈值的像素值设置为 0,其余设置为maxval
。cv2.THRESH_TRUNC
:大于阈值的像素值设置为阈值,其余不变。cv2.THRESH_TOZERO
:小于阈值的像素值设置为 0,其余不变。cv2.THRESH_TOZERO_INV
:大于阈值的像素值不变,其余设置为 0。
返回值:
retval
:阈值(与提供的thresh
相同)。dst
:输出的二值图像。
示例代码:
import cv2
# 读取灰度图像
gray_image = cv2.imread('gray_image.jpg', cv2.IMREAD_GRAYSCALE)
#cv2.IMREAD_GRAYSCALE 是 OpenCV 中用于读取图像时的标志,表示将图像以灰度模式加载。
# 应用阈值
ret, binary_image = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY)
# 显示图像
cv2.imshow('Binary Image', binary_image)
cv2.waitKey(0)
cv2.destroyAllWindows()