opencv常用操作

安装opencv

  • 最新版本的anaconda
    anaconda网址
  • 由于需要python3.6,于是在anaconda里创建一个3.6的环境
conda create -n python36 python=3.6
conda activate python36  //激活环境

此时anaconda navigator里会显示两个环境
在这里插入图片描述

  • 安装opencv
pip install opencv-python==3.4.1.15
pip install opencv-contrib-python==3.4.1.15

图像基本操作

  • img1=cv2.imread('files/cat.jpg') 读取图片,将图片转化为一个三维的矩阵。默认加载彩色,如果第二个参数为0则加载灰度图。
    可以打印看img1的一些参数print(img1.shape) print(img1.size)
  • cv2.imshow('hi', img1) 显示图片,只显示一下,使用cv2.waitKey(0)来等待关闭
  • 逐帧读取视频
vc=cv2.VideoCapture('files/test.mp4')
if vc.isOpened():
    open,frame=vc.read()//open为读取的情况,布尔值。frame为读取该帧的图像信息。
else:
    open=False
while open:
    now,frame=vc.read()
    if(frame is None):
        break
    if(now==True):
        grey=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        cv2.imshow('window',grey)
        if cv2.waitKey(10) & 0xFF==27:
            break
vc.release()
  • 截取部分图像数据
img1 = cv2.imread('files/cat.jpg')
print(img1.shape)
cv2.imshow('h', img1)
img1 = img1[0:200, 0:100]
cv2.imshow('hi', img1)
print(img1.shape)
cv2.waitKey()
#输出
# (414, 500, 3)
# (200, 100, 3)

在这里插入图片描述

  • 颜色通道提取与合并
img = cv2.imread('files/cat.jpg')
b, g, r = cv2.split(img)
print(b.shape)
print(g.shape)
a=cv2.merge((b,g,r))//参数是一个元组
print(a.shape)
#输出
# (414, 500)
# (414, 500)
# (414, 500, 3)

只保留R

img = cv2.imread('files/cat.jpg')
cv2.imshow('1', img)
img[:, :, 0] = 0;
img[:, :, 1] = 0
cv2.imshow('2', img)
cv2.waitKey(0)

在这里插入图片描述

  • 边界填充
img = cv2.imread('files/cat.jpg')
top, bottom, left, right = 50, 50, 50, 50
cv2.imshow('h',img)
replicate = cv2.copyMakeBorder(img, top, bottom, left, right, borderType=cv2.BORDER_REFLECT)
cv2.imshow('hi',replicate)
cv2.waitKey(0)

在这里插入图片描述

  • 数值计算
img = cv2.imread('files/cat.jpg')
img1 = img + 10//超出256则取模
//也可以两个图片相加,比如img1+img
//cv2.add(img1,img)若溢出则取255
print(img[:5, :, 0])
print(img1[:5, :, 0])
plt.show()
  • 图像融合
    融合的两张图的大小需要相等,先进行resize操作
img1 = cv2.resize(img1, (100, 429))//横向,纵向
img2 = cv2.resize(img1, (0, 0), fx=2, fy=2)//倍数
img1 = cv2.imread('files/cat.jpg')
cv2.imshow('hi', img1)
img1 = cv2.resize(img1, (100, 429))
img2 = cv2.resize(img1, (0, 0), fx=2, fy=2)
cv2.imshow('h', img1)
cv2.imshow('hh',img2)
cv2.waitKey(0)

在这里插入图片描述

img1 = cv2.imread('files/cat.jpg')
img2 = cv2.imread('files/dog.jpg')
img1 = cv2.resize(img1, (499, 429))
#αX1+βX2+b α为X1占的权重,β为X2占的权重,b为提亮
res=cv2.addWeighted(img1,0.4,img2,0.6,0)
cv2.imshow('1',img1)
cv2.imshow('2',img2)
cv2.imshow('3',res)
cv2.waitKey(0)

在这里插入图片描述

图像阈值

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的反转

平滑处理

  1. 均值滤波
    值为以其为中心所在矩阵里的值的平均值
img=cv2.imread('files/lena.jpg')
cv2.imshow('h',img)
blur=cv2.blur(img,(3,3))//3*3的矩阵
cv2.imshow('b',blur)
cv2.waitKey(0)
  1. 方框滤波
#当最后一个参数为True时等价于均值滤波
#否则在所在矩阵中相加计算时若溢出则不会取模,而是取255
box=cv2.boxFilter(img,-1,(3,3),normalize=False)// 
cv2.imshow('box',box)
  1. 高斯滤波
    距离更近的数值所占权重比较大
aussian = cv2.GaussianBlur(img, (3, 3), 1)
cv2.imshow('aussian', aussian)
  1. 中值滤波
#取周围5*5的矩阵中的数值的中位数
median = cv2.medianBlur(img, 5)  # 中值滤波
cv2.imshow('median', median)
一起展示的方法

```python
res = np.hstack((img,blur,aussian,median))
cv2.imshow('img,blur,aussian,median', res)
cv2.waitKey(0)

好像区别不大

图像形态学处理

  1. 腐蚀操作
img = cv2.imread('files/1.png')
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel, iterations=1)//迭代次数
res = np.hstack((img, erosion))
cv2.imshow('res', res)
cv2.waitKey(0)

在这里插入图片描述

  1. 膨胀
    膨胀和腐蚀大概像是互逆的操作
img = cv2.imread('files/1.png')
kernel = np.ones((5, 5), np.uint8)
dige_dilate = cv2.dilate(img,kernel,iterations = 2)
cv2.imshow('dilate', dige_dilate)

在这里插入图片描述

  1. 开运算与闭运算
  • 开运算:先腐蚀后膨胀
img = cv2.imread('files/1.png')

kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening', opening)
res = np.hstack((img, opening))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

  • 闭运算
    先膨胀 后腐蚀 毛刺无法消除
img = cv2.imread('files/1.png')
kernel = np.ones((10, 10), np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
# cv2.imshow('closing', closing)
res = np.hstack((img, closing))
cv2.imshow('1', res)

在这里插入图片描述

  1. 梯度运算
    梯度运算=膨胀-腐蚀
pie = cv2.imread('files/pie.png')
cv2.imshow('1', pie)
kernel = np.ones((7, 7), np.uint8)
erosion = cv2.erode(pie, kernel, iterations=5)
dilate = cv2.dilate(pie, kernel, iterations=5)
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
res = np.hstack((erosion, dilate, gradient))
cv2.imshow('res', res)

分别为腐蚀,膨胀,梯度

  1. 礼帽与黑帽
  • 礼帽=原始-开运算
img = cv2.imread('files/1.png')
cv2.imshow('1',img)
kernel = np.ones((5, 5), np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)

在这里插入图片描述

  • 黑帽=闭运算-原始
    闭运算为先膨胀后腐蚀,此操作后图中的刺依旧存在,减去原图之后只剩下一个图像的大致轮廓
img = cv2.imread('files/1.png')
kernel = np.ones((5, 5), np.uint8)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
cv2.waitKey(0)
res = np.hstack((img, blackhat))
cv2.imshow('1', res)

在这里插入图片描述

图像梯度处理

  1. 图像梯度-Sobel算子
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
  • ddepth:图像的深度
  • dx和dy分别表示水平和竖直方向,dx为1时则为水平方向
  • ksize是Sobel算子的大小
    水平方向是从左到右,白-黑>0正常显示,黑-白为负数,应取绝对值。
    垂直方向是从下到上
img = cv2.imread('files/lena.jpg', cv2.IMREAD_GRAYSCAL
#水平方向和垂直方向一起算不如分别算完之后相加效果好
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
res = np.hstack((img, sobelxy))
cv2.imshow('1', res)

在这里插入图片描述

  1. Scharr算子
    类似于Sobel,但权重更大,效果更明显
img = cv2.imread('files/lena.jpg', cv2.IMREAD_GRAYSCALE)
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
res=np.hstack((img,scharrxy))

在这里插入图片描述

  1. laplacian算子
    对于变化更加敏感,但是对于噪点也更加敏感
img = cv2.imread('files/lena.jpg', cv2.IMREAD_GRAYSCALE)
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((img, laplacian))
cv2.imshow('res',res)

在这里插入图片描述

Canny边缘检测

img = cv2.imread("files/car.png", cv2.IMREAD_GRAYSCALE)
v1 = cv2.Canny(img, 80, 150)//minval和maxval值小的话得到的细节更多,
v2 = cv2.Canny(img, 50, 100)//但也可能是无用的噪点
res = np.hstack((v1, v2))
cv2.imshow('res', res)

在这里插入图片描述

图像金字塔

  1. 拉普拉斯金字塔
down=cv2.pyrDown(img)
down=cv2.pyrUp(down)
cv2.imshow('1',img-down)

在这里插入图片描述

图像轮廓

cv2.findContours(img,mode,method)

mode:轮廓检索模式

  • RETR_EXTERNAL :只检索最外面的轮廓;
  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
  • RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
  • RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;
    method
    轮廓逼近方法
  • CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
img = cv2.imread('files/car.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
#contours代表获取到的图像的轮廓信息,为list类型
res = cv2.drawContours(img, contours, -1, (0, 0, 255), 2)
#第三个参数为-1时表示所有轮廓,否则代表轮廓的下标
#第四个参数为BGR
#第五个参数代表轮廓的粗细
cv2.imshow('4', res)

在这里插入图片描述

轮廓特征

cnt = contours[0]//得到编号为0的轮廓
print(cv2.contourArea(cnt))//面积
print(cv2.arcLength(cnt, True))//周长,True表示是闭合的

轮廓近似

#普朗克算法
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
draw_img = img.copy()
cnt = contours[0]
epsilon = 0.04 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)

在这里插入图片描述

边界矩形

img = cv2.imread('files/demo1.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
x, y, w, h = cv2.boundingRect(cnt)
#x,y是矩阵左上点的坐标,w,h是矩阵的宽和高
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
#(x,y)是矩阵的左上点坐标
#(x+w,y+h)是矩阵的右下点坐标

在这里插入图片描述

外接圆

x, y, w, h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

在这里插入图片描述

模板匹配

假如原图形是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)

res = cv2.matchTemplate(img, face, cv2.TM_SQDIFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
print(res.shape)
img = cv2.rectangle(img, min_loc, (min_loc[0] + w, min_loc[1] + h), 255, 2)

在这里插入图片描述

  • TM_SQDIFF:计算平方不同,计算出来的值越小,越相关
  • TM_CCORR:计算相关性,计算出来的值越大,越相关
  • TM_CCOEFF:计算相关系数,计算出来的值越大,越相关
  • TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关
  • TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关
  • TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关

匹配多个对象

face = cv2.imread('files/mario_coin.jpg')
img = cv2.imread('files/mario.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('img1',img)
h, w = face.shape[:2]
res = cv2.matchTemplate(img, face, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res > threshold)
for pt in zip(*loc[::-1]):
    bottom_right = (pt[0] + w, pt[1] + h)
    cv2.rectangle(img, pt, bottom_right, (0, 0, 255), 2)
cv2.imshow('img',img)

在这里插入图片描述

直方图

cat = cv2.imread('files/cat.jpg', 0)
hist = cv2.calcHist([cat], [0], None, [256], [0, 256])
plt.hist(cat.ravel(), 256)
#cat.ravel() 是多维矩阵变一维数组

在这里插入图片描述

cv2.calcHist(images,channels,mask,histSize,ranges)
  • images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]
  • channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的参数可以是 [0] [[1]] [[2]] 它们分别对应着 BGR。
  • mask: 掩模图像。统整幅图像的直方图就把它为 None。但是如 果你想统图像某一分的直方图的你就制作一个掩模图像并 使用它。
  • histSize:BIN 的数目。也应用中括号括来
  • ranges: 像素值范围常为 [0256]
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值