OpenCv学习-python

一.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) - 突出的特征判断,特征描述和对特征描述的对比。
  • … 一些其他的辅助模块,比如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: 线型,通常为 8cv2.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: 线型,通常为 8cv2.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: 线型,通常为 8cv2.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_BGR2GRAYcv2.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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值