一些小tips:
文件夹必须这样放
一、图像的基本操作
1.jupyter中 shift+回车 可以直接运行一个模块
1.2灰度图中0最暗是黑色 255最亮
1.5
1 import cv2
2 import matplotlib.pyplot as plt
3 import numpy as np
4 %matplotlib inline
这些是常用的包的导入
2.import as的用法:
在Python中,如果import的语句比较长,导致后续引用不方便,可以使用as语法,比如:
import dir1.dir2.mod
# 那么,后续对mod的引用,都必须是dir1.dir2.mod
dir1.dir2.mod.X
那么,为了简化输入,可以使用as语法:
import dir1.dir2.mod as m
# 那么,后续对mod的引用,可以直接使用m
m. X
# 需要注意的是,使用as语法之后,只能通过as后面名字来访问导入的moudle
import mod as m
m.X # OK
mod.X # Error
3.opencv默认读取图片格式是BGR(三通道,范围是0-255)
4.读取图像命令
img=cv2.imread('cat.jpg') 读取图片 并且是本路径下的图片
5.显示图像命令
cv2.imshow=('img1',img) 第一个参数是显示图像必须要临时取的名字,第二个是图像的定义名(即4中的img)
cv2.waitKey(数值) 即等待时间,毫秒级。例如cv2.waitKey(1000),即图片显示后等待1s,数值若为0,则表示任意键终止 配合cv2.destoryallwindows()这条使用
6
img.shape
运行此命令后显示(414,530,3) 这三个参数不固定,显示的是h w 和图片的通道数3
7.读取灰度图
img=cv2.imread(‘cat.jpg’,cv2.IMREAD_GRAYSCALE)
这时读取的就是灰度图,运行img.shape后得到的就是(414,530) 表示没有三通道了,只是一个灰度图
8.保存图片
cv2.imwrite(‘mycat.png’,img)
9.img.size运行后得到20700表示此图片有20700个像素点组成
10.img.dtype运行后得到dtype(‘uint8’)表示储存这些像素值的数字数uint8类型。 dtype表示数据类型
11.读取视频的一系列操作
vc=cv2.VideoCapture('test.mp4') #传入视频流
#检测视频能否正常读取
if vc.isOpened():
open,frame=vc.read()
else:
open=False
其中read()是一帧一帧地读取视频中的图片,返回的第一个参数open是bool值,用来表示视频是否正常打开,第二个参数frame保存的是每一帧的图片
while open:
ret,frame=vc.read()
if frame is None:
break;
if ret==true;
gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #把frame传进去进行2gray的操作
cv2.imshow('result',gray)
if cv2.waitKey(10) & 0xFF==27: #27代表ESC ,waitKey代表处理完一帧等待的时间(毫秒级)
break;
vc.release()
cv2.destroyALLWindows()
12.截取部分图像
img=cv2.imread(‘cat.jpg’)
cat=img[0:50,0:200]
cv2.imread('cat',cat)
13.颜色通道提取
b.g.r=cv2.split(img)执行后再执行一个单独的
r
就会显示r通道上所有的像素值
r.shape运行后得到的还是(414,500) 两外俩结果也一样 都跟灰度图的h w保持一致
分开之后可以把这三种颜色merge在一起
img=cv2.merge(b,g,r)
然后运行img.shape之后得到还是(414,500,3)的结果,表明三通道重新merge在一起了
14.只保留R通道
cur_img=img.copy()
cur_img[:,:,0]=0 #第一个通道即B通道所有数为0
cur_img[:,:,1]=0 #第二个通道即G通道所有数为0
cv2.imread('R',cur_img) #显示只有R通道时候的图像
##只保留G通道的代码
cur_img=img.copy()
cur_img[:,:,0]=0 #第一个通道即B通道所有数为0
cur_img[:,:,2]=0 #第二个通道即R通道所有数为0
cv2.imread('G',cur_img) #显示只有G通道时候的图像
15.边界填充
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,borderType=cv2.BORDER_REFLECT)
reflect101=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REFLECT_101)
wrap=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_WRAP)
constant=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_CONSTANT,value=0)
以上为五种边界填充的方法:
BORDER_REPLICATE:复制法,直接复制最边缘的像素
BORDER_REFLECT:反射法,对图像中的像素在两边进行复制 如:fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101:反射法,以最边缘的像素为轴进行反射 如:fedcb|abcdefgh|gfedcb 相对上面这种方法少了重复的部分,会更加的对称,看上去更加自然一点
BORDER_WRAP:外包装法 如cdefgh|abcdefgh|abcdefg 这个还有些不太懂。。。
BORDER_CONSTANT:常量法,使用常数值填充,会多一个value变量
#显示图像
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(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
就会六张显示在同一张图中
subplot中的三个参数 第一个表示行数 第二个表示列数 第三个表示是第几张图片
16.数值计算
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg') #先读两张图
img_cat2=img_cat+10 #假如图像中为500*500 且是rgb三通道的,那么此操作意味在500*500*3的每一个数都加10
img_cat+img_cat2 #若使用img_cat+img_cat2操作,如果计算结果超过了255,那么其显示结果不会超过255,相当于%256
opencv提供了cv2.add函数
cv2.add(img_cat,img_cat2) #opencv提供了cv2.add函数则是不同算法,如果计算结果大于255的话不会像上述计算过程一样取余,超过255的结果就按照255来,没越界就用计算结果
img_cat+img_dog #图像融合操作,前提是两张图片size一样
img_dog=cv2.resize(img_dog,(500,414)) #输入想变换的图像 resize操作 参数顺序为w h
执行img_dog.shape之后显示的是(414,500,3)#显示的是h w 通道数
res=cv2.resize(img,(0,0),fx=3,fy=1) #w h参数为0 0表示不指定具体参数,后面多的fx表示为原图w的多少倍,fy表示h为原图的多少倍 即像素数为原来的几倍
res=cv2.addWeighted(img_cat,0.4,img_dog,0.6,0) #R=X*0.4+Y*0.6+b 这五个参数分别是x 0.4 y 0.6 0(偏置项) 偏置项一般来提亮或者变暗
二、阈值与平滑处理
1.图像阈值
ret, dst = cv2.threshold(src, thresh, maxval, type) #等号左边的两个返回参数第一个还不知道什么用,第二个参数可以改成你想要的图像名字
src: 输入图,只能输入单通道图像,通常来说为灰度图
dst: 输出图
thresh: 阈值 常用的有127
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值 灰度的话这个值设为255
type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINRY; 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的反转
2.图像平滑
#均值滤波
#简单的平均卷积操作
blur = cv2.blur(img, (3, 3)) #img表示被处理的图像 (3,3)表示核的尺寸,通常用奇数*奇数 blur是均值滤波函数
#方框滤波
#可以选择归一化 归一化之后和均值滤波一样
box=cv2.boxFilter(img,-1,(3,3),normalize=True) #img是原图 -1基本不会变 (3,3)是核尺寸 true表示选择了归一化(3*3个像素值加载一起要除以9)
cv2.imshow('box',box)
cv2.WaitKey(0)
cv2.destoryAllWindows()
#选择不归一化(所有超过255的越界值最后赋予255)
box=cv2.boxFilter(img,-1,(3,3),normalize=False) #img是原图 -1基本不会变 (3,3)是核尺寸 False表示没有选择归一化(没有处以9)
cv2.imshow('box',box)
cv2.WaitKey(0)
cv2.destoryAllWindows()
#高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1) #最后一个参数是sigma标准差
cv2.imshow('aussian',aussian)
cv2.WaitKey(0)
cv2.destoryAllWindows()
#中值滤波
# 相当于用中值代替*
median = cv2.medianBlur(img, 5) #表示核尺寸是5*5的,选择第13大的数字(中值、中位数)
#展示所有
res=np.hstack((blur,aussian,median)) #hstack是横着展示 horizontal 水平的 vstack是竖着展示 vertial垂直的;注意双层括号
cv2.imshow('median vs average',res)
cv2.WaitKey(0)
cv2.destoryAllWindows()
三、腐蚀(erode)操作(去毛刺)和膨胀(dilate)操作
核尺寸越大 可能被腐蚀的范围就越多(因为核越大 那么核边界接触背景的时候,核中心很靠内)
#腐蚀
img=cv2.imread('dige.jpg')
cv2.imshow('img',img)
cv2.WaitKey(0)
cv2.destoryAllWindows()
kernel=np.ones((5,5),np.uint8) #定义核