opencv-python 操作


*注:在此笔记中只记录下各种函数的使用,规则

详细讲解见https://opencv.apachecn.org/#/docs/4.0.0/2.1-tutorial_py_image_display

创建,读取,显示,保存图像

创建图像

import numpy as np
img = np.zeros((512,512,3),np.uint8) # 创建一个图像 ,3 是指三个通道,可传入RGB

读取图像

cv2.imread(“本工作目录下的文件名”,-1或0或1) # -1:加载图像,包括alpha通道,0:灰色模式加载图像,1:默认正常模式加载

显示图像

cv.imshow('image', img)   # imshow("窗口名字",要显示的图像)
cv.waitKey(0)
cv.destroyAllWindows()

cv.waitKey() 是一个键盘绑定函数,它的参数是以毫秒为单位的时间。该函数为任意键盘事件等待指定毫秒。如果你在这段时间内按下任意键,程序将继续。如果传的是 0,它会一直等待键盘按下。它也可以设置检测特定的击键,例如,按下键 a 等,我们将在下面讨论。

Note

除了绑定键盘事件,该函数还会处理许多其他 GUI 事件,因此你必须用它来实际显示图像。

cv.destroyAllWindows() 简单的销毁我们创建的所有窗口。如果你想销毁任意指定窗口,应该使用函数 cv.destroyWindow() 参数是确切的窗口名。

eg.下面的程序以灰度模式读取图像,显示图像,如果你按下 's‘ 会保存和退出图像,或者按下 ESC 退出不保存。

import numpy as np
import cv2 as cv img = cv.imread('messi5.jpg',0)
cv.imshow('image',img)
k = cv.waitKey(0)
if k == 27: # ESC 退出
cv.destroyAllWindows()
elif k == ord('s'): # 's' 保存退出
cv.imwrite('messigray.png',img)
cv.destroyAllWindows()

Note

有一种特殊情况,你可以先创建一个窗口然后加载图像到该窗口。在这种情况下,你能指定窗口是否可调整大小。它是由这个函数完成的 cv.namedWindow()。默认情况下,flag 是 cv.WINDOW_AUTOSIZE。但如果你指定了 flag 为 cv.WINDOW_NORMAL,你能调整窗口大小。当图像尺寸太大,在窗口中添加跟踪条是很有用的。

看下面的代码:

cv.namedWindow('image', cv.WINDOW_NORMAL)
cv.imshow('image',img)
cv.waitKey(0)
cv.destroyAllWindows()

保存图像

保存图像,用这个函数 cv.imwrite()

第一个参数是文件名,第二个参数是你要保存的图像。

cv.imwrite('messigray.png',img)

将该图像用 PNG 格式保存在工作目录。

使用 Matplotlib

Matplotlib 是一个 Python 的绘图库,提供了丰富多样的绘图函数。你将在接下来的文章中看到它们。在这里,你将学习如何使用 Matplotlib 来显示图像。你还能用 Matplotlib 缩放图像,保存图像等。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt img = cv.imread('messi5.jpg',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic') # 让图像以灰色形式展示
# 或者选择 plt.imshow(img[:,:,::-1]) #这一步操作,保证和原图像显示的色彩一致
plt.xticks([]), plt.yticks([]) # 隐藏 X 和 Y 轴的刻度值 去掉则会显示刻度
plt.show()

色彩模式与cv2不一样(BGR),因此显示出来的颜色不对,需要改一下

plt.imshow(img[:,:,::-1])    #这一步操作,保证和原图像显示的色彩一致
plt.show()

图像的绘制功能

画线

去画一条线,你需要传递线条的开始和结束的坐标。我们将创建一个黑色图像,并在坐上角到右下角画一条蓝色的线

import numpy as np
import cv2 as cv
# 创建一个黑色的图像
img = np.zeros((512,512,3), np.uint8)
# 画一条 5px 宽的蓝色对角线
cv.line(img,(0,0),(511,511),(255,0,0),5)

cv2.line(图像,(起始坐标),(终点坐标),(颜色),宽度)

画圆

画一个圆,你需要它的圆心和半径。我们将在上面绘制的矩形上画一个内圆。

cv.circle(img,(447,63), 63, (0,0,255), -1)

cv.circle(图像,(圆心坐标x,y),半径,(颜色),加载方式)

画椭圆

画一个椭圆,你需要传好几个参数。一个参数是圆心位置 (x,y)。下个参数是轴的长度 (长轴长度,短轴长度)。角度是椭圆在你逆时针方向的旋转角度。startAngle 和 endAngle 表示从长轴顺时针方向测量的椭圆弧的起点和终点。如整圆就传 0 和 360。更多细节请看 cv.ellipse() 的文档。下面是在这个图像中间画的一个半椭圆例子。

cv.ellipse(img,(256,256),(100,50),0,0,180,(0,255,255),-1)

cv.ellipse(图像,(圆心坐标),(长轴,短轴),起时角度,起点,终点,颜色,加载方式

画矩形

cv.rectangle(img,左上角坐标,右下角坐标,颜色,线条厚度)

画多边形

画多边形,首先你需要顶点的做坐标。将这些点组成一个形状为 ROWSx1x2 的数组,ROWS 是顶点数,它应该是 int32 类型。这里我们绘制一个顶点是黄色的小多边形。

pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))

Note

  • 如果地三个是 False,你将获得所有点的折线,而不是一个闭合形状。
  • cv.polylines() 能画很多线条。只需创建你想绘制所有线条的列表,然后将其传给这个函数。所有线条都将单独绘制。绘制一组线条比调用 cv.line() 好很多,快很多。

绘图添加文字

cv.putText(img,输入内容,文本的放置位置,字体,字体大小,颜色,线条宽度,cv.LINE__AA)

访问并修改像素点

通过行列坐标来进行访问及修改

黄色为绿色和红色的混合。所以,该图像的所有像素值都应为R=255,G=255,B=0。

>>> import numpy as np
>>> import CV2
>>> img = CV2.imread("img/yellow.jpg")
>>> h,w,c = img.shape
#图像大小为128*128*3
>>> print(h,w,c)
128 128 3
px = img[100,100]     # 获取某个点的像素值

从上面的代码中可以看到,您可以通过行和列坐标访问像素值。注意,对于常见的RGB 图像,OpenCV的imread函数返回的是一个蓝色(Blue)值、绿色(Green)值、红色(Red)值的数组,维度大小为3。而对于灰度图像,仅返回相应的灰度值。

>>> img[100,100]
#OpenCV的读取顺序为B,G,R,由于图像所有像素为黄色,因此,G=255,R=255
array([ 0, 255, 255], dtype=uint8) # 仅访问蓝色通道的像素
>>> blue = img[100,100,0]
>>> print(blue)
0

你也可以使用同样的方法来修改像素值。

>>> img[100,100] = [255,255,255]
>>> print(img[100,100])
[255 255 255]

访问属性

图像大小

img.shape      # 变量.shape

(256,256,3)

img.shape[:2] 取彩色图片的长、宽。

  • 使用彩色模式传参时
cols,rows = img.shape[:2]
# 或者
cols,rows,x = img.shape
  • 使用灰色模式

    cols ,rows = img.shape

如果img.shape[:3] 则取彩色图片的长、宽、通道

关于img.shape[0]、[1]、[2]

img.shape[0]:图像的垂直尺寸(高度)

img.shape[1]:图像的水平尺寸(宽度)

img.shape[2]:图像的通道数

数据类型

img.dtype

dtype('uint8')

像素点数量

img.size

196608

图像的裁剪、拼接、翻转、缩放等 [(https://blog.csdn.net/zh_jessica/article/details/77946346)]

缩放:

一、图像缩放

图像缩放主要使用resize函数

result = cv2.resize(src, dsize[, result[. fx[, fy[, interpolation]]]]) 记得要用新变量来接收

其中src表示原始图像,dsize表示缩放大小,fx和fy也可以表示缩放大小倍数,他们两个(dsize或fx\fy)设置一个即可实现图像缩放

参数说明:

src - 原图

dst - 目标图像。当参数dsize不为0时,dst的大小为size;否则,它的大小需要根据src的大小,参数fx和fy决定。dst的类型(type)和src图像相同

dsize - 目标图像大小。当dsize为0时,它可以通过以下公式计算得出:

所以,参数dsize和参数(fx, fy)不能够同时为0

fx - 水平轴上的比例因子。当它为0时,计算公式如下:

fy - 垂直轴上的比例因子。当它为0时,计算公式如下:

interpolation - 插值方法。共有5种:

INTER_NEAREST - 最近邻插值法

INTER_LINEAR - 双线性插值法(默认)

INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取也叫缩小图像(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。

INTER_CUBIC - 基于4x4像素邻域的3次插值法

INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值

缩小图像 用INTER_AREA更好,放大图像用 INTER_CUBIC更好;

————————————————

代码如下:

import cv2

#读取图片
image = cv2.imread("E:/pythonProject/xin.jpeg") #图片缩放
image1 = cv2.resize(image, (200,200)) #图片显示
cv2.imshow("resize", image1)
cv2.imshow("image", image) #等待窗口
cv2.waitKey(0)

旋转

opencv中对图像的旋转主要是先通过getRotationMatrix2D函数得到图像的旋转矩阵,然后再通过仿射变换函数warpAffine得到旋转后的图像。

函数说明:

cv2.getRotationMatrix2D(center, angle, scale)
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst

参数说明:

getRotationMatrix2D: 得到图像的旋转矩阵

center–表示旋转的中心点

angle–表示旋转的角度degrees

scale–图像缩放因子

warpAffine:

src – 输入的图像

M – 2 X 3 的变换矩阵.

dsize – 输出的图像的size大小

dst – 输出的图像

flags – 输出图像的插值方法

borderMode – 图像边界的处理方式

borderValue – 当图像边界处理方式为BORDER_CONSTANT 时的填充值

代码示范:

img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
#90度旋转 M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img,M,(cols,rows))

平移

  1. 平移translate

    平移通过自定义平移矩阵以及函数warpAffine实现:

代码示范:

img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
# 平移矩阵M:[[1,0,x],[0,1,y]]
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))

反转

  1. 翻转flip

    翻转通过函数flip实现:

函数说明:

cv2.flip(src, flipCode[, dst]) → dst

1

参数说明:

src – 输入的图像

dst – 输出的图像

flipCode – 翻转模式,flipCode==0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)

代码示范:

# 水平翻转
flip_horiz_img = cv2.flip(pad_img, 1)
# 垂直翻转
flip_verti_img = cv2.flip(pad_img, 0)
# 水平垂直翻转
flip_horandver_img = cv2.flip(pad_img, -1)

拼接

单个图像多次拼接

import  cv2
img =cv2.imread(file_path[i])
img=cv2.hconcat([img,img,img])#水平拼接
img=cv2.vconcat([img,img,img])#垂直拼接

多个相似特征图像拼接(开摆!)

import cv2
import numpy as np def stitch(image):
# 图像拼接
# stitcher = cv2.createStitcher(False) # OpenCV 3.X.X.X使用该方法
stitcher = cv2.Stitcher_create(cv2.Stitcher_PANORAMA) # OpenCV 4.X.X.X使用该方法,cv2.Stitcher_create()也可以
status, pano = stitcher.stitch(image) # 黑边处理
if status == cv2.Stitcher_OK:
# 全景图轮廓提取
stitched = cv2.copyMakeBorder(pano, 10, 10, 10, 10, cv2.BORDER_CONSTANT, (0, 0, 0))
gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] # 轮廓最小正矩形
mask = np.zeros(thresh.shape, dtype="uint8")
(x, y, w, h) = cv2.boundingRect(cnts[0]) # 取出list中的轮廓二值图,类型为numpy.ndarray
cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1) # 腐蚀处理,直到minRect的像素值都为0
minRect = mask.copy()
sub = mask.copy()
while cv2.countNonZero(sub) > 0:
minRect = cv2.erode(minRect, None)
sub = cv2.subtract(minRect, thresh) # 提取minRect轮廓并裁剪
cnts = cv2.findContours(minRect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
(x, y, w, h) = cv2.boundingRect(cnts[0])
stitched = stitched[y:y + h, x:x + w] cv2.imshow('stitched', stitched)
cv2.imwrite('stitched.jpg', stitched)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print('图像匹配的特征点不足') if __name__ == "__main__":
image1 = cv2.imread('data/space1.jpg')
image2 = cv2.imread('data/space2.jpg')
image3 = cv2.imread('data/space3.jpg')
image = image1, image2, image3
stitch(image)

(18条消息) OpenCV-Python 图像全景拼接stitch及黑边处理_Klein-的博客-CSDN博客_stitcher_create

opencv-python学习之旅的更多相关文章

  1. 180分钟的python学习之旅

    最近在很多地方都可以看到Python的身影,尤其在人工智能等科学领域,其丰富的科学计算等方面类库无比强大.很多身边的哥们也提到Python非常的简洁方便,比如用Django搭建一个见得网站只需要半天时 ...

  2. python学习之旅

    python学习分类 python基础    +- day01——python初始.变量.常量.注释.基础数据类型.输入.if day02——while.字符串格式化.运算符.编码初识 day03—— ...

  3. python学习之旅:array 转 list

    最近学习python,记录学习的点滴. >>> import numpy as np >>> a = np.array([[1,2],[3,4]]) >> ...

  4. Python学习之旅(三十八)

    Python基础知识(37):访问数据库(Ⅱ) 二.MySQL MySQL是Web世界中使用最广泛的数据库服务器.SQLite的特点是轻量级.可嵌入,但不能承受高并发访问,适合桌面和移动应用.而MyS ...

  5. Python学习之旅(三十六)

    Python基础知识(35):电子邮件(Ⅱ) 收取邮件就是编写一个MUA作为客户端,从MDA把邮件获取到用户的电脑或者手机上 收取邮件最常用的协议是POP协议,目前版本号是3,俗称POP3 Pytho ...

  6. Python学习之旅(三十三)

    Python基础知识(32):网络编程(Ⅰ) 网络通信是两台计算机上的两个进程之间的通信,而网络编程就是如何在程序中实现两台计算机的通信 P协议负责把数据从一台计算机通过网络发送到另一台计算机 TCP ...

  7. Python学习之旅(三十二)

    Python基础知识(31):图形界面(Ⅱ) Python内置了turtle库,可以在计算机上绘图 运动控制: 1.画笔定位到坐标(x,y):turtle.goto(x,y) 2.向正方向运动 dis ...

  8. Python学习之旅(三十)

    Python基础知识(29):virtualenv virtualenv:用来为一个应用创建一套隔离的Python运行环境 比如,现有两个Python项目,一个是Python2.7的一个是Python ...

  9. Python学习之旅:使用virtualenv创建Python环境及PyQT5环境配置

    一.写在前面 从学 Python 的第一天起,我就知道了使用 pip 命令来安装包,从学习爬虫到学习 Web 开发,安装的库越来越多,从 requests 到 lxml,从 Django 到 Flas ...

  10. python学习之旅1-2(基础知识)

    三,python基础初识. 1.运行python代码. 在d盘下创建一个t1.py文件内容是: print('hello world') 打开windows命令行输入cmd,确定后 写入代码pytho ...

随机推荐

  1. 如何优雅的备份MySQL数据?看这篇文章就够了

    大家好,我是一灯,今天一块学习一下如何优雅安全的备份MySQL数据? 1. 为什么要备份数据 先说一下为什么需要备份MySQL数据? 一句话总结就是:为了保证数据的安全性. 如果我们把数据只存储在一个 ...

  2. 关于for循环当中发生强制类型转换的问题

    Map map1 = new HashMap(); Map map2 = new HashMap(); Map map3 = new HashMap(); List<Map> list = ...

  3. 如何使用 pyqt 读取串口传输的图像

    前言 这学期选修了嵌入式系统的课程,大作业选择的题目是人脸口罩检测.由于课程提供的开发板搭载的芯片是 STM32F103ZET6,跑不动神经网络,所以打算将 OV7725 拍摄到的图像通过串口传输给上 ...

  4. 使用VsCode调试UE5的PuerTs

    使用VsCode调试UE5的PuerTs 1.下载测试的Demo项目 配置PuerTs的步骤这里不赘述. 2.准备工作 2.1 打开项目 正常来说,直接打开项目可以看到如下画面 如果直接点击运行,可以 ...

  5. ES6 学习笔记(六)基本类型String

    字符串String 1.字面量 需要注意的地方: 由单引号或双引号括起来的字符序列. 单双引号可以嵌套,由最外围引号定界字符串 字符串字面量可以拆分成数行,每行必须以反斜线(\)结束,且反斜线都不计入 ...

  6. C#中winform DataGridView常用修改点

    1.修改列名 一般情况下,从数据库里面读取的列名是英文或者拼音,但是,有时候显示需要中文,这样就需要修改列名了. dgv.Columns[0].HeaderCell.Value="编号&qu ...

  7. pytest文档82 - 用例收集钩子 pytest_collect_file 的使用

    前言 pytest 提供了一个收集用例的钩子,在用例收集阶段,默认会查找test_*.py 文件或者 *_test.py文件. 如果我们想运行一个非python的文件,比如用yaml 文件写用例,那么 ...

  8. lambda、map、reduce、filter、sorted函数

    # lambda 函数from functools import reducea = lambda x: x ** 2print(a(3))def power(func, l=[]): return ...

  9. IDEA提交任务到spark standalone集群

    参考文章: 在idea里面怎么远程提交spark任务到yarn集群 代码 注意setJars,提交的代码,要提前打好包.否则会报找不到类的错误 个人理解就相当于运行的main方法是起了一个spark- ...

  10. C温故补缺(四):GDB

    gdb gdb是由GNU软件社区提供的C Debug工具 Pre 在调试前,需要先编译.c程序,且要加上-g使输出文件变得可调式 gcc test.c -g -o test 用gdb test来调试程 ...