OpenCV1

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • [1. 简介](#1. 简介)
  • [2. 图像基础操作](#2. 图像基础操作)
    • [2.1 图像的IO操作](#2.1 图像的IO操作)
    • [2.2 绘制图形](#2.2 绘制图形)
    • [2.3 获取并修改图像中的像素点](#2.3 获取并修改图像中的像素点)
    • [2.4 获取图像属性](#2.4 获取图像属性)
    • [2.5 图像通道的拆分和合并](#2.5 图像通道的拆分和合并)
    • [2.6 色彩空间转换](#2.6 色彩空间转换)
  • [3. 算术操作](#3. 算术操作)
    • [3.1 图像加法](#3.1 图像加法)
    • [3.2 图像混合](#3.2 图像混合)
  • [4. OpenCV图像处理](#4. OpenCV图像处理)
    • [4.1 几何变换](#4.1 几何变换)
    • [4.2 图像平移](#4.2 图像平移)
    • [4.3 图像旋转](#4.3 图像旋转)
    • [4.4 仿射变换](#4.4 仿射变换)
    • [4.5 透射变换](#4.5 透射变换)
  • 总结

前言

1. 简介

灰度图:0~255

彩色图:RGB三个分量

安装OpenCv之前需要先安装numpy,matplotlib。

java 复制代码
pip install opencv-python
java 复制代码
import cv2

能导入这个就说明安装成功了

安装包含 contrib 扩展模块的版本----》因为我们要利用SIFT和SURF等进行特征提取

java 复制代码
pip install opencv-python opencv-contrib-python

core模块实现了最核心的数据结构及其基本运算,如绘图函数、数组操作相关函数等。

·highgui模块实现了视频与图像的读取、显示、存储等接口。

·imgproc模块实现了图像处理的基础方法,包括图像滤波、图像的几何变换、平滑、阈值分割、形态学

处理、边缘检测、目标检测、运动分析和对象跟踪等。

2. 图像基础操作

2.1 图像的IO操作

java 复制代码
import numpy as py
import cv2 as cv
import matplotlib.pyplot as plt

#读取图像---》默认读取--》彩色
img = cv.imread("../image/dili.jpg")
#显示图像
cv.imshow("dili",img)
cv.waitKey(0)
cv.destroyAllWindows()

cv.waitKey(0)的作用是

这是一个等待键盘输入的函数,参数 0 表示无限期等待用户按下任意键。

OpenCV 的 cv.imshow() 显示窗口需要配合 cv.waitKey() 才能正常停留,否则窗口会瞬间闪过。

只有当用户按下键盘上的任意键后,程序才会继续执行后续代码(这里就是执行 cv.destroyAllWindows())。

如果参数是其他数值(如 cv.waitKey(500)),则表示等待 500 毫秒(0.5 秒)后自动继续,无需按键。

cv.destroyAllWindows()是关闭图像

java 复制代码
img = cv.imread("../image/dili.jpg")

plt.imshow(img[:,:,::-1])
plt.show()

OpenCV 读取图像时,默认使用 BGR 颜色通道顺序(蓝色、绿色、红色)。

Matplotlib 的 imshow() 函数则默认期望图像是 RGB 颜色通道顺序(红色、绿色、蓝色)

第一个 : :表示选取所有行(图像的高度方向)

第二个 : :表示选取所有列(图像的宽度方向)

::-1 :表示对第三个维度(颜色通道)进行反向切片,即把 BGR 顺序反转成 RGB 顺序

java 复制代码
img = cv.imread("../image/dili.jpg",0)

plt.imshow(img,cmap="gray")
plt.show()

img = cv.imread(..., 0) 执行后,img 是一个二维数组(形状为 (高度, 宽度)),每个元素代表对应像素的灰度值(0 为纯黑,255 为纯白),灰度图像没有RGB

Matplotlib 默认的颜色映射表不是灰度(而是 viridis 等彩色映射),如果不指定 cmap="gray",直接显示二维灰度数组,会用彩色伪影来表示不同的灰度值

java 复制代码
#保存图像
cv.imwrite("../image/dili_save.jpg",img)

2.2 绘制图形

java 复制代码
import numpy as py
import cv2 as cv
import matplotlib.pyplot as plt

#创建图形
img = py.zeros((512,512,3),py.uint8)
#绘制线
cv.line(img,(0,0),(511,511),(255,0,0),5)
#显示结果
plt.imshow(img[:,:,::-1])
plt.show()

np.zeros() 创建一个全为 0 的数组,代表黑色图像

(512,512,3) 表示图像尺寸为 512x512 像素,3 个颜色通道(BGR 格式),意思就是长宽为512,高为3,这个高就是RGB

np.uint8 是数据类型,代表每个像素值范围是 0-255

(0,0) 是线段的起点坐标(左上角)

(511,511) 是线段的终点坐标(右下角)

(255,0,0) 是线条颜色,这里是蓝色(BGR 格式)

5 是线条的粗细,单位为像素

java 复制代码
cv.circle(img,(256,256),60,(0,0,255),4)

(256,256)表示圆心,60表示半径,4表示宽度

java 复制代码
cv.circle(img,(256,256),60,(0,0,255),-1)

-1表示填充

java 复制代码
cv.rectangle(img,(100,100),(300,300),(0,255,0),5)

分别是左上角坐标和右下角坐标

java 复制代码
cv.putText(img,"hello",(100,150),cv.FONT_HERSHEY_COMPLEX,5,(255,255,255),3)

5表示字体大小,3表示字体宽度,(100,150)表示字体位置

2.3 获取并修改图像中的像素点

java 复制代码
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
java 复制代码
img = np.zeros((256,256,3),np.uint8)
java 复制代码
plt.imshow(img[:,:,::-1])

其实应该是全黑的,因为我的背景是黑色,所以显示为白色

java 复制代码
img[100,100]

返回的是这个位置的RGB值

java 复制代码
img[100,100,0]

返回的是这个位置,蓝色通道的值

java 复制代码
img[100,100] = [0,0,255]
plt.imshow(img[:,:,::-1])
img[100,100]

2.4 获取图像属性

java 复制代码
img.shape
java 复制代码
img.dtype
java 复制代码
img.size

2.5 图像通道的拆分和合并

java 复制代码
dili = cv.imread("../../py/image/dili.jpg")
plt.imshow(dili[:,:,::-1])
plt.show()
java 复制代码
b,g,r = cv.split(dili)

一个通道就是灰色了

java 复制代码
img2=cv.merge((b,g,r))
plt.imshow(img2[:,:,::-1])

2.6 色彩空间转换

java 复制代码
gray = cv.cvtColor(dili,cv.COLOR_BGR2GRAY)
plt.imshow(gray, cmap="gray")

这样就转换为灰度图了

java 复制代码
hsv = cv.cvtColor(dili,cv.COLOR_BGR2HSV)
plt.imshow(hsv)

3. 算术操作

3.1 图像加法

np相加的话,超过255的话,那么就是和之后取模255---》模运算

cv加法的话,超过255的话,那么就是等于255了---》饱和运算

java 复制代码
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
java 复制代码
rain = cv.imread("../../py/image/rain.jpg")
plt.imshow(rain[:,:,::-1])
java 复制代码
view = cv.imread("../../py/image/view.jpg")
plt.imshow(view[:,:,::-1])
java 复制代码
img1 = cv.add(rain,view)
plt.imshow(img1[:,:,::-1])
java 复制代码
img2= rain+ view
plt.imshow(img2[:,:,::-1])

所以cv的加法更好

3.2 图像混合

就是加法的权重不同

反正就是这样

img = aimg1 +b img2+x

a,b,x都是参数

java 复制代码
img3 = cv.addWeighted(rain,0.3,view,0.7,0)
plt.imshow(img3[:,:,::-1])

权值之和为1,0就是x

4. OpenCV图像处理

4.1 几何变换

java 复制代码
kids = cv.imread("../../py/image/kids.jpg")
plt.imshow(kids[:,:,::-1])
java 复制代码
#绝对尺寸缩放
rows,cols = kids.shape[:2]

kids.shape 是 OpenCV 中图像的形状属性,返回一个元组 (高度, 宽度, 通道数)(对于彩色图像)或 (高度, 宽度)(对于灰度图像)。

第一个元素是图像的高度(行数,rows)

第二个元素是图像的宽度(列数,cols)

第三个元素(如果存在)是通道数(如 RGB 图像为 3)

:2\] 表示截取元组的前 2 个元素,即只获取高度和宽度,忽略通道数(即使图像有通道信息也不处理) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a6edaaa577554e1580c50f4ea6746099.png) ```java res = cv.resize(kids,(cols*2,rows*2)) plt.imshow(res[:,:,::-1]) ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c7a0a345bcb9410d8e52dc50a3d6274a.png) 看坐标就知道变大了 ```java res1=cv.resize(kids,None,fx=0.5,fy=0.5) plt.imshow(res1[:,:,::-1]) ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/03b9ea59a1634037a72164135027fb4e.png) 0.5表示缩小为原来的de0.5倍 ### 4.2 图像平移 ```java #图像平移->平移矩阵 M = np.float32([[1,0,100],[0,1,50]]) ``` 表示往(1,0)方向也就是x方向移动100,y方向移动50 ```java res2 = cv.warpAffine(kids,M,(cols,rows)) plt.imshow(res2[:,:,::-1]) ``` (cols,rows)表示移动后显示范围画布的大小,并不是图像的大小 注意cv中,坐标原点在左上角,x轴往右,y轴往下 ```java res2 = cv.warpAffine(kids,M,(cols*2,rows*2)) plt.imshow(res2[:,:,::-1]) ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/092fd70578494e29b9e9e954a264beeb.png) ### 4.3 图像旋转 ```java #图像旋转 M = cv.getRotationMatrix2D((cols/2,rows/2),90,1) res3 = cv.warpAffine(kids,M,(cols,rows)) plt.imshow(res3[:,:,::-1]) ``` (cols/2,rows/2)是旋转中心,90就是选择角度,1表示对图像的缩放比例 (cols,rows)表示画布的大小 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e5266e1f6b2e4a629ad484e61f69e75a.png) ```java #图像旋转 M = cv.getRotationMatrix2D((cols/2,rows/2),90,0.5) res3 = cv.warpAffine(kids,M,(cols,rows)) plt.imshow(res3[:,:,::-1]) ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8904d10c07eb4aa4ac3dc21cc3407aef.png) ### 4.4 仿射变换 仿射变换就是对图像缩放旋转平移的组合 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/75ca941324164a14babe2a3a3f6d4bf1.png) 点之间的映射,仿射前后,平行的线还是平行的,线的比例关系不变 共线的点还是共线,共面的还是共面 ```java plt.imshow(res3[:,:,::-1]) #%% #仿射变换 #原始图像位置 pts1 = np.float32([[50,50],[200,50],[50,200]]) #仿射变换后位置 pts2 = np.float32([[100,100],[200,50],[100,250]]) #构建仿射变换矩阵 M = cv.getAffineTransform(pts1,pts2) M ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c0f405f99b274c6c93bd6a4d60ea6d40.png) 前面两列是线性变换,后一列是平移 ```java #仿射变换 #原始图像位置 pts1 = np.float32([[50,50],[200,50],[50,200]]) #仿射变换后位置 pts2 = np.float32([[100,100],[200,50],[100,250]]) #构建仿射变换矩阵 M = cv.getAffineTransform(pts1,pts2) #应用仿射变换 res4 = cv.warpAffine(kids,M,(cols,rows)) plt.imshow(res4[:,:,::-1]) ``` (cols,rows)是输出图像大小 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/11ebb2f6575a4065b90afd8af8538a53.png) 仿射变换后,点线的关系和原图是一样的 但是线的长度会发送变化,角度也会 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/dbde3b129bcd4c78bdaf1eb0235f3f46.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0c8d27971f664052a88b336e6f952a15.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2af6968fc3fa4adc94dfc5f085e1d10d.png) ### 4.5 透射变换 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d7ba65e88c5645acb34566503a489878.png) ## 总结

相关推荐
不搞学术柒柒3 小时前
设计模式-行为型设计模式(针对对象之间的交互)
python·设计模式·交互
MThinker3 小时前
02-Media-11-video_player.py 对H.264或H.265格式视频播放器的示例程序
python·音视频·h.265·h.264·micropython·canmv·k230
2301_764441333 小时前
Python常见的排序算法及其特点和实现代码
python·算法·排序算法
MediaTea3 小时前
Python 编辑器:IDLE
开发语言·python·编辑器
ones~3 小时前
Python 简单算法题精选与题解汇总
数据结构·python·算法
胡耀超3 小时前
开源生态与技术民主化 - 从LLaMA到DeepSeek的开源革命(LLaMA、DeepSeek-V3、Mistral 7B)
人工智能·python·神经网络·开源·大模型·llama·deepseek
站大爷IP4 小时前
Python字典:高效数据管理的瑞士军刀
python
星川皆无恙4 小时前
电商机器学习线性回归:基于 Python 电商数据爬虫可视化分析预测系统
大数据·人工智能·爬虫·python·机器学习·数据分析·线性回归
天天进步20154 小时前
Python项目--交互式VR教育应用开发
开发语言·python·vr