localhost中详解OpenCV的函数imread()和函数imshow(),并利用它们实现对图像的读取和显示_opencv imshow-CSDN博客
其实以下均为numpy
显示一张图片
import cv2 ####opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
img=cv2.imread('ldz.jpg')
img
出现一个庞大数组,这里不予显示
#图像的显示,也可以创建多个窗口
cv2.imshow('ldz',img)
#等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(4090)
cv2.destroyAllWindows()
img.shape
结果是(2400, 3840, 3) HWC
显示一张灰度图
img=cv2.imread('ldz.jpg',cv2.IMREAD_GRAYSCALE)
img
img.shape
结果是(2400, 3840)
保存图片
cv2.imwrite('ldz.jpg',img)
type(img)#格式 如numpy.ndarray
img.size#像素点
img.dtype#数据类型
数据读取视频
#数据读取-视频
#cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1。
#如果是视频文件,直接指定好路径即可。
vc = cv2.VideoCapture('test.mp4')
#检查是否打开正确
if vc.isOpened():
open_ ,frame=vc.read()
else:
open=False
while open:
ret, frame=vc.read()
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:
break
#ret 是个布尔值是否读到图片,frame表示具体图片
#如果在10ms 内没有按键值,cv2.waitKey返回为-1,这个时候-1& 0xFF.如果等于27就满足了按下esc键退出
vc.release()
cv2.destroyAllWindows()
截取部分图像数据
img=cv2.imread('cat.jpg')
cat=img[0:40,0:200]
cv_show('cat',cat)
颜色通道提取
#调图时要加上cv2.waitKey和cv2.destroyAllWindows才能防止崩溃
b,g,r=cv2.split(img)
r
r.shape
img=cv2.merge((b,g,r))
img.shape
img=cv2.merge((b,g,r))
img.shape
#只保留R
cur_img=img.copy()
cur_img[:,:,0]=0
cur_img[:,:,1]=0
cv_show('R',cur_img)
边界填充
填充后能使做卷积后,尺寸保持不变,而扩大通道的深度
为什么出来的图片偏蓝色。。。浅蓝色是因为默认通道 bgr plt默认的是rgb 改下bgr to rgb
top_size, bottom_size, left_size, right_size =(50,50.50,50)
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)
import matplotlib. pyplot as plt
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.show0
- BORDER_REPLICATE:夏制法,也就是复制最边缘像素.
- BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制 比如fedcbalabcdefghlhgfedcb
- BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴对称,gfedcb|abcdefgh|gfedcba
- BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
AE的动态拼贴 - BORDER_CONS1ANT:常量法,常数值填充
四个边角分别用x轴和y轴做相应的变换映射到图像坐标中去,取像素点填充
cv.imshow模式是BGR模式,而plt.imshow模式为RGB模式,因此需要转化才能正确显示
前面那个说错了,这个设置了gray参数,只显示灰度图的时候不需要转换
数值计算
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')
img_cat2=img_cat+10#这是numpy里的广播机制 对矩阵的每个值都加10
img_cat[:5,:,0]#打印前五行
img_cat2[:5,:,0]
(img_cat+img_cat2)[:5,:,0]#多的会和255取余
cv2.add(img_cat,img_cat2)[:5,:,0]
图像融合
img_cat+img_dog
#警告这些需要你去学pandas,matplotlib numpy才行 不然这里你不懂doge 啊米诺斯
img_shape
img_dog=cv2.resize(img_dog,(500,414))
ing_dog.shape
#是resize,直接改变大小,reshape仅在改变维度,数据量不匹配就报错了
res=cv2.addWeighted(img_cat,0.4,img_dog,0.6,0)
#因为shape输出的是高和宽,而resize()需要的参数是宽和高
#反着是因为resize的读取是(列数,行数).
#cv2这个库读取到RGB是BGR,错误。BGR指的是颜色通道,shape出来时长宽和颜色通道数
#cv2.imread函数读取图片,颜色通道排列是BGR,plt.imread()读取图片颜色通道是RGB,两个不一样
#发现plt颜色不对,是因为cv2.imread读取的图像保存为BGR格式,而plt.imshow()以为你输入的是RGB
plt.imshow(res)
拉缩图片
res=cv2.resize(img,(0,0),fx=3,fy=1)
plt.imshow(res)#开头记得import matplotlib.pyplot as plt
图像阈值
- 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_INVTHRESH_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()