三、Opencv-Python-Opencv基本操作
三、OpenCV基本操作
图像基本操作
3.1 图像的IO操作
3.1.1 读取图像
import cv2 as cv
cv.imread("图片.jpg",0) # 灰度图像
# 等同于:cv.imread('图片.jpg', cv.IMREAD_GRAYSCALE)
参数:
-
要读取的图像
-
读取方式的标志
-
cv.IMREAD*COLOR:以彩色模式加载图像,任何图像的透明度都将被忽略。这是默认参数。
-
cv.IMREAD*GRAYSCALE:以灰度模式加载图像
-
cv.IMREAD_UNCHANGED:包括alpha通道的加载图像模式。
可以使用1、0或者-1来替代上面三个标志
-
3.1.2 显示图像
import cv2 as cv
cv.imread("图片.jpg",0) # 灰度图像
cv.imshow("窗口名称",加载的图像)
参数:
- 显示图像的窗口名称,以字符串类型表示
- 要加载的图像
3.1.3 保存图像
import cv2 as cv
cv.imread("图片.jpg",0) # 灰度图像
cv.imshow("窗口名称",加载的图像)
cv.imwrite('保存图片的名字',保存的图片)
参数:
- 文件名,要保存在哪里
- 要保存的图像
3.2 绘制几何图形
3.2.1 绘制直线
import cv2 as cv
cv.line(img,start,end,color,thickness)
参数:
- img:要绘制直线的图像
- Start,end: 直线的起点和终点
- color: 线条的颜色
- Thickness: 线条宽度
具体代码:
pt_start = (60, 60)
pt_end = (200, 200)
point_color = (255, 245, 0) # BGR
cv.line(img, pt_start, pt_end, point_color, thickness=5)
3.2.2 绘制圆形
import cv2 as cv
cv.circle(img,centerpoint, r, color, thickness)
参数:
- img:要绘制圆形的图像
- Centerpoint, r: 圆心和半径
- color: 线条的颜色
- Thickness: 线条宽度,为-1时生成闭合图案并填充颜色
# 绘制圆形
center_point = (250, 250)
r = 100
point_color = (255, 245, 0) # BGR
cv.circle(img, center_point, r, point_color, thickness=3)
3.2.3 绘制矩形
import cv2 as cv
cv.rectangle(img,leftupper,rightdown,color,thickness)
参数:
- img:要绘制矩形的图像
- Leftupper, rightdown: 矩形的左上角和右下角坐标
- color: 线条的颜色
- Thickness: 线条宽度
# 绘制矩形
left_upper = (80, 80)
right_down = (200, 200)
point_color = (255, 245, 0) # BGR
cv.rectangle(img, left_upper, right_down, point_color, thickness=3)
3.2.4 向图像中添加文字
cv.putText(img,text,station, font, fontsize,color,thickness,cv.LINE_AA)
参数:
- img: 图像
- text:要写入的文本数据
- station:文本的放置位置
- font:字体
- Fontsize :字体大小
# 向图像中添加文字
text = "Lena"
station = (10, 100)
font = cv.FONT_HERSHEY_DUPLEX
font_size = 2
font_color = (255, 245, 0) # BGR
cv.putText(img, text, station, font, font_size, font_color, thickness=3)
3.3 获取并修改图像中的像素点
我们可以通过行和列的坐标值获取该像素点的像素值。对于BGR图像,它返回一个蓝,绿,红值的数组。对于灰度图像,仅返回相应的强度值。使用相同的方法对像素值进行修改。
import numpy as np
import cv2 as cv
img = cv.imread('lena.jpg')
# 获取某个像素点的值
px = img[100,100]
# 仅获取蓝色通道的强度值
blue = img[100,100,0]
# 修改某个位置的像素值
img[100,100] = [255,255,255]
如下图,左图的位置的像素点修改为右图的白点
3.4 获取图像的属性
图像属性包括行数,列数和通道数,图像数据类型,像素数等。
# 图像属性包括行数,列数和通道数,图像数据类型,像素数等。
print(img.shape) #获取图像的形状,返回值是一个包含行数、列数、通道数的元组。
print(img.size) #获得图像的像素数目。
print(img.dtype) #获得图像的数据类型。
结果:
(512, 512, 3)
786432
uint8
3.5 图像通道的拆分与合并
有时需要在B,G,R通道图像上单独工作。在这种情况下,需要将BGR图像分割为单个通道。或者在其他情况下,可能需要将这些单独的通道合并到BGR图像。你可以通过以下方式完成。
b, g, r = cv.split(img)
print(b)
print(g)
print(r)
# 通道合并
img = cv.merge((b, g, r))
结果:
[[125 125 133 ... 122 110 90]
[125 125 133 ... 122 110 90]
[125 125 133 ... 122 110 90]
...
[ 60 60 58 ... 84 76 79]
[ 57 57 62 ... 79 81 81]
[ 57 57 62 ... 79 81 81]]
[[137 137 137 ... 148 130 99]
[137 137 137 ... 148 130 99]
[137 137 137 ... 148 130 99]
...
[ 18 18 27 ... 73 68 62]
[ 22 22 32 ... 70 71 74]
[ 22 22 32 ... 70 71 74]]
[[226 226 223 ... 230 221 200]
[226 226 223 ... 230 221 200]
[226 226 223 ... 230 221 200]
...
[ 84 84 92 ... 173 172 177]
[ 82 82 96 ... 179 181 185]
[ 82 82 96 ... 179 181 185]]
3.6 色彩空间的改变
OpenCV中有150多种颜色空间转换方法。最广泛使用的转换方法有两种
-
BGR↔Gray
-
BGR↔HSV
cv.cvtColor(input_image,flag)
参数:
- input_image: 进行颜色空间转换的图像
- flag: 转换类型
- cv.COLOR_BGR2GRAY : BGR↔Gray
- cv.COLOR_BGR2HSV: BGR→HSV
具体代码:
# 色彩空间的改变
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
算数操作
1. 图像加法
你可以使用OpenCV的cv.add()函数把两幅图像相加,或者可以简单地通过numpy操作添加两个图像,如res = img1 + img2。两个图像应该具有相同的大小和类型,或者第二个图像可以是标量值。
注意:OpenCV加法和Numpy加法之间存在差异。OpenCV的加法是饱和操作,而Numpy添加是模运算。
将下面的两幅图相加:
实列代码:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 读取图片
img1 = cv.imread("../img/lena.png")
img2 = cv.imread("../img/rain.jpg")
# 2 加法操作
x, y = 300, 50 # 叠放位置
W1, H1 = img1.shape[1::-1] # 大图尺寸
W2, H2 = img2.shape[1::-1] # 小图尺寸
if (x + W2) > W1 : x = W1 - W2 # 调整图像叠放位置,避免溢出
if (y + H2) > H1 : y = H1 - H2
imgCrop = img1[y:y + H2, x:x + W2] # 裁剪大图,与小图 imgS 的大小相同
img3 = cv.add(imgCrop, img2) # cv2 加法,裁剪图与小图叠加
img4 = imgCrop + img2
# 3 图像显示
cv.imshow(u"img3", img3)
cv.imshow(u"img4", img4)
cv.waitKey(0)
2. 图像的混合
这其实也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。图像混合的计算公式如下:
g(x) = (1−α)f0(x) + αf1(x)
通过修改 α 的值(0 → 1),可以实现非常炫酷的混合。
现在我们把两幅图混合在一起。第一幅图的权重是0.7,第二幅图的权重是0.3。函数cv2.addWeighted()可以按下面的公式对图片进行混合操作。
dst = α⋅img1 + β⋅img2 + γ
这里γ取为零。
实例:
addWeighted(InputArray src1,
double alpha,
InputArray src2,
double beta,
double gamma,
OutputArray dst,
int dtype=-1)
参数:
-
第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat。
-
第二个参数,alpha,表示第一个数组的权重。
-
第三个参数,src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数。
-
第四个参数,beta,表示第二个数组的权重值。
-
第五个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数。
-
第六个参数,gamma,一个加到权重总和上的标量值。看下面的式子自然会理解。
-
第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 读取图片
img1 = cv.imread("../img/lena.png")
img2 = cv.imread("../img/rain.jpg")
# 2 混合操作
x, y = 300, 50 # 叠放位置
W1, H1 = img1.shape[1::-1] # 大图尺寸
W2, H2 = img2.shape[1::-1] # 小图尺寸
if (x + W2) > W1:
x = W1 - W2 # 调整图像叠放位置,避免溢出
if (y + H2) > H1:
y = H1 - H2
imgCrop = img1[y:y + H2, x:x + W2] # 裁剪大图,与小图 imgS 的大小相同
img3 = cv.addWeighted(imgCrop, 0.7, img2, 0.3, 0) # cv2 图像混合
# 3 图像显示
cv.imshow(u"img3", img3)
cv.waitKey(0)