6 Python-OpenCV(ing)
6.1基本知识6.1.1搭建环境6.1.2读图、显示灰度图、显示图片大小、图片另存6.1.3读取视频数据6.1.4图像切片、R/G/B提取、使用matplotlib显示图像大小6.1.5边界填充6.1.6阈值处理6.1.7腐蚀和膨胀处理
6.1基本知识
6.1.1搭建环境
python目录下执行pip install opencv-python或者进入到https://www.lfd.uci.edu/~gohlke/pythonlibs/找到OpenCV与python对应的版本号和系统下载即可,然后在将其复制到python安装目录,然后在命令端输入pip install ….whl等。
6.1.2读图、显示灰度图、显示图片大小、图片另存
图片由多个像素组成,而像素在OpenCV里则被表示成一个个RGB的矩阵。
import cv2
img
=cv2
.imread('test.jpg') #OpenCV读取当前目录下的图片并赋值给变量
img_gray
= cv2
.cvtColor(img
,cv2
.COLOR_BGR2GRAY) #将读取到图片转成灰度图,参数
1必须先是imread的
cv2
.imshow("img_gray", img_gray
) #显示图片,参数
1是对话框名称,参数
2是显示某种类型的图片
print(img
.shape
) #打印出图片大小
cv2
.imwrite('test1.jpg',img_gray
) #将打开的图片另存为
...
cv2
.waitKey(0) #窗口显示时间,
0表示暂停窗口
cv2
.destroyAllWindows()
6.1.3读取视频数据
import cv2
vc
= cv2
.VideoCapture('movie.avi') #打开当前目录下的视频文件
if vc
.isOpened(): #不能换成
while循环,会卡在读取状态中
oepn
, frame
= vc
.read() #其中open是布尔类型,表示打开,frame即读取的帧
else:
open
= False
while open
:
ret
, frame
= vc
.read() #如果读取到的帧不为空,则就ret否则报错
if frame is None
:
break
if ret
== True
:
gray
= cv2
.cvtColor(frame
, cv2
.COLOR_BGR2GRAY) #将读取到的帧全部转换成灰度图
cv2
.imshow('result', gray
) #一帧一帧的展示出视频
if cv2
.waitKey(10) & 0xFF == 27: #
如果waitkey(0)则变成单帧暂停了,其中参数可调表示播放速度
break
vc
.release()
cv2
.destroyAllWindows()
6.1.4图像切片、R/G/B提取、使用matplotlib显示图像大小
import cv2 #opencv读取的格式是
BGR
import numpy
as np #数组处理库
import matplotlib
.pyplot
as plt #Matplotlib是
RGB
img
= cv2
.imread('test.jpg')
test_demo
= img
[0:200,0:200] #图片切片
cv2
.imwrite('test_demo.jpg',test_demo
) #切片图另存为…
b
,g
,r
=cv2
.split(img
) #按
R/G/B切片图片
cv2
.imwrite('test_demo_b.jpg',b
)
test_rgb
= cv2
.merge((r
,g
,b
)) #将
BGR的图片转成
RGB图片,方便Matplotlib显示
plt
.imshow(test_rgb
)
plt
.show() #暂停matplotlib窗口
6.1.5边界填充
import cv2
import numpy
as np
import matplotlib
.pyplot
as plt
top_size
,bottom_size
,left_size
,right_size
= (50,50,50,50)
img_init
= cv2
.imread('test.jpg')
b
,g
,r
= cv2
.split(img_init
)
img
= cv2
.merge((r
,g
,b
)) #由于是matplotlib显示,修改rgb顺序
'''
BORDER_REPLICATE:复制法,也就是复制最边缘像素。
BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba
|abcdefgh
|hgfedcb
BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb
|abcdefgh
|gfedcba
BORDER_WRAP:外包装法cdefgh
|abcdefgh
|abcdefg
BORDER_CONSTANT:常量法,常数值填充。
'''
replicate
= cv2
.copyMakeBorder(img
, top_size
, bottom_size
, left_size
, right_size
, borderType
=cv2
.BORDER_REPLICATE)
reflect
= cv2
.copyMakeBorder(img
, top_size
, bottom_size
, left_size
, right_size
,cv2
.BORDER_REFLECT)
reflect101
= cv2
.copyMakeBorder(img
, top_size
, bottom_size
, left_size
, right_size
, cv2
.BORDER_REFLECT_101)
wrap
= cv2
.copyMakeBorder(img
, top_size
, bottom_size
, left_size
, right_size
, cv2
.BORDER_WRAP)
constant
= cv2
.copyMakeBorder(img
, top_size
, bottom_size
, left_size
, right_size
,cv2
.BORDER_CONSTANT, value
=0)
plt
.subplot(231), plt
.imshow(img
, 'gray'), plt
.title('ORIGINAL')
plt
.subplot(232), plt
.imshow(replicate
, 'gray'), plt
.title('REPLICATE')
plt
.subplot(233), plt
.imshow(reflect
, 'gray'), plt
.title('REFLECT')
plt
.subplot(234), plt
.imshow(reflect101
, 'gray'), plt
.title('REFLECT_101')
plt
.subplot(235), plt
.imshow(wrap
, 'gray'), plt
.title('WRAP')
plt
.subplot(236), plt
.imshow(constant
, 'gray'), plt
.title('CONSTANT')
plt
.show()
6.1.6阈值处理
import cv2
import numpy
as np
import matplotlib
.pyplot
as plt
img_init
= cv2
.imread('test.jpg')
b
,g
,r
= cv2
.split(img_init
)
img
= cv2
.merge((r
,g
,b
))
img_gray
= cv2
.cvtColor(img
,cv2
.COLOR_BGR2GRAY)
'''
ret
, dst
= cv2
.threshold(src
, thresh
, maxval
, type
)
src: 输入图,只能输入单通道图像,通常来说为灰度图
dst: 输出图
thresh: 阈值
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
type:二值化操作的类型,包含以下
5种类型: cv2
.THRESH_BINARY; cv2
.THRESH_BINARY_INV; cv2
.THRESH_TRUNC; cv2
.THRESH_TOZERO;cv2
.THRESH_TOZERO_INV
cv2
.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取
0
cv2
.THRESH_BINARY_INV THRESH_BINARY的反转
cv2
.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
cv2
.THRESH_TOZERO 大于阈值部分不改变,否则设为
0
cv2
.THRESH_TOZERO_INV THRESH_TOZERO的反转
'''
ret
, thresh1
= cv2
.threshold(img_gray
, 127, 255, cv2
.THRESH_BINARY)
ret
, thresh2
= cv2
.threshold(img_gray
, 127, 255, cv2
.THRESH_BINARY_INV)
ret
, thresh3
= cv2
.threshold(img_gray
, 127, 255, cv2
.THRESH_TRUNC)
ret
, thresh4
= cv2
.threshold(img_gray
, 127, 255, cv2
.THRESH_TOZERO)
ret
, thresh5
= cv2
.threshold(img_gray
, 127, 255, cv2
.THRESH_TOZERO_INV)
titles
= ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images
= [img
, thresh1
, thresh2
, thresh3
, thresh4
, thresh5
]
for i
in range(6):
plt
.subplot(2, 3, i
+ 1), plt
.imshow(images
[i
], 'gray')
plt
.title(titles
[i
])
plt
.xticks([]), plt
.yticks([])
plt
.show()
6.1.7腐蚀和膨胀处理
腐蚀操作的图像一般都是二值(通过阈值处理可以生成二值图像)的。
import cv2
import matplotlib
.pyplot
as plt
import numpy
as np
img_init
= cv2
.imread('test.jpg') #原始照片
img_gray
= cv2
.cvtColor(img_init
,cv2
.COLOR_BGR2GRAY) #灰度照片
ret
,img_bin
= cv2
.threshold(img_gray
, 127, 255, cv2
.THRESH_BINARY_INV) #灰度图转化成二值图
kernel
= np
.ones((30,30),np
.uint8
)
#腐蚀处理
erosion_1
= cv2
.erode(img_bin
,kernel
,iterations
= 1)
erosion_2
= cv2
.erode(img_bin
,kernel
,iterations
= 2)
erosion_3
= cv2
.erode(img_bin
,kernel
,iterations
= 3)
#膨胀处理
dilate_1
= cv2
.dilate(img_bin
,kernel
,iterations
= 1)
dilate_2
= cv2
.dilate(img_bin
,kernel
,iterations
= 2)
dilate_3
= cv2
.dilate(img_bin
,kernel
,iterations
= 3)
#res
= np
.hstack((img_bin
,erosion_1
,erosion_2
,erosion_3
)) #图片合成一张上
#没有调整
RGB,所以颜色有偏差
plt
.subplot(331), plt
.imshow(img_init
),plt
.title("init")
plt
.subplot(332), plt
.imshow(img_gray
),plt
.title("gray")
plt
.subplot(333), plt
.imshow(img_bin
),plt
.title("gray")
plt
.subplot(334), plt
.imshow(erosion_1
),plt
.title("erode_1")
plt
.subplot(335), plt
.imshow(erosion_2
),plt
.title("erode_2")
plt
.subplot(336), plt
.imshow(erosion_3
),plt
.title("erode_3")
plt
.subplot(337), plt
.imshow(dilate_1
),plt
.title("dilate_1")
plt
.subplot(338), plt
.imshow(dilate_2
),plt
.title("dilate_2")
plt
.subplot(339), plt
.imshow(dilate_3
),plt
.title("dilate_3")
plt
.show()