tnblog
首页
视频
资源
登录

OpenCV 图像金字塔、轮廓与模板匹配(学习笔记)

4682人阅读 2024/1/16 15:39 总访问:3470565 评论:0 收藏:0 手机
分类: opencv

OpenCV 图像金字塔、轮廓与模板匹配(学习笔记)

图像金字塔


初始化代码。

  1. import cv2 #opencv读取的格式是BGR
  2. import numpy as np
  3. import matplotlib.pyplot as plt#Matplotlib是RGB
  4. %matplotlib inline
  5. def cv_show(img,name):
  6. cv2.imshow(name,img)
  7. cv2.waitKey()
  8. cv2.destroyAllWindows()

高斯金字塔


在OpenCV中,高斯金字塔是一种图像处理技术,它用于将一幅图像分解成多个不同分辨率的图像版本,其中每个版本都是原始图像的模糊和缩小版本。
这个过程可以帮助我们在不同尺度上分析和处理图像。


高斯金字塔:向下采样方法(缩小)


高斯金字塔:向上采样方法(放大)


查看原始图片大小。

  1. img=cv2.imread("AM.png")
  2. cv_show(img,'img')
  3. print (img.shape)

(442, 340, 3)


放大操作。(大小翻一倍)

  1. up=cv2.pyrUp(img)
  2. cv_show(up,'up')
  3. print (up.shape)

(884, 680, 3)


缩小一倍。

  1. down=cv2.pyrDown(img)
  2. cv_show(down,'down')
  3. print (down.shape)

(221, 170, 3)


放大两倍

  1. up2=cv2.pyrUp(up)
  2. cv_show(up2,'up2')
  3. print (up2.shape)

(1768, 1360, 3)


放大后再缩小,我们会发现它与原有的图片相比比较模糊。

  1. up=cv2.pyrUp(img)
  2. up_down=cv2.pyrDown(up)
  3. cv_show(np.hstack((img,up_down)),'up_down')

拉普拉斯金字塔


拉普拉斯金字塔的构建基于高斯金字塔,主要计算每一层与其下一层之间的差异,也就是高斯金字塔中的每一层图像与其下一层图像的差异。
将这些细节图像与高斯金字塔的上一层相应尺度的图像相加,就可以还原出原始图像。

  1. down=cv2.pyrDown(img)
  2. down_up=cv2.pyrUp(down)
  3. l_1=img-down_up
  4. cv_show(l_1,'l_1')

图像轮廓


通常我们再获取图像轮廓的时候,调用cv2.findContours(img,mode,method)方法。
img:通常是二值化后的灰度图。
mode:轮廓检索模式。一共有以下四种模式:
cv2.RETR_EXTERNAL:只检索最外面的轮廓;
cv2.RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
cv2.RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
cv2.RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;
method:轮廓逼近方法
cv2.CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
cv2.CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。


为了更高的准确率,使用二值图像。

  1. img = cv2.imread('contours.png')
  2. # 转成灰度图
  3. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  4. # 设置阈值在127-255之间,进行二值化处理
  5. ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
  6. cv_show(thresh,'thresh')

  1. # 检测图像中的对象边界
  2. contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

绘制轮廓

  1. #传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
  2. # 注意需要copy,要不原图会变。。。
  3. draw_img = img.copy()
  4. res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
  5. cv_show(res,'res')


绘制第一个。

  1. draw_img = img.copy()
  2. res = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2)
  3. cv_show(res,'res')

轮廓特征


计算第一个图像的面积和周长。

  1. cnt = contours[0]
  2. #面积
  3. cv2.contourArea(cnt)

8500.5

  1. #周长,True表示闭合的
  2. cv2.arcLength(cnt,True)

437.9482651948929

轮廓近似


轮廓近似(Contour Approximation)是图像处理和计算机视觉中的一种技术,用于减少轮廓的顶点数目,以简化轮廓的表示。

  1. img = cv2.imread('contours2.png')
  2. # 二值化处理
  3. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  4. ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
  5. contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
  6. cnt = contours[0]
  7. #对第一个图像轮廓进行绘制
  8. draw_img = img.copy()
  9. res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
  10. cv_show(res,'res')

  1. # 计算轮廓周长(弧长)乘以的值越小0.01轮廓绘制越清晰
  2. epsilon = 0.01*cv2.arcLength(cnt,True)
  3. # 用于对轮廓进行多边形逼近
  4. approx = cv2.approxPolyDP(cnt,epsilon,True)
  5. draw_img = img.copy()
  6. res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
  7. cv_show(res,'res')

  1. epsilon = 0.15*cv2.arcLength(cnt,True)

边界矩形

  1. img = cv2.imread('contours.png')
  2. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  3. ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
  4. contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
  5. cnt = contours[0]
  6. # 使用矩形包裹
  7. x,y,w,h = cv2.boundingRect(cnt)
  8. # 绘制矩形框
  9. img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
  10. cv_show(img,'img')

  1. # 计算第一个图的面积
  2. area = cv2.contourArea(cnt)
  3. # 计算包裹这个图的矩形面积
  4. x, y, w, h = cv2.boundingRect(cnt)
  5. rect_area = w * h
  6. extent = float(area) / rect_area
  7. print ('轮廓面积与边界矩形比',extent)

轮廓面积与边界矩形比:0.5154317244724715

外接圆


使用圆进行包裹。

  1. (x,y),radius = cv2.minEnclosingCircle(cnt)
  2. center = (int(x),int(y))
  3. radius = int(radius)
  4. img = cv2.circle(img,center,radius,(0,255,0),2)
  5. cv_show(img,'img')

模板匹配


模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv里有6种,然后将每次计算的结果放入一个矩阵里,作为结果输出。假如原图形是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1)

简单来讲:模板匹配就像在一张图片里找到一张小图片的位置,就像找到拼图的一块在整个拼图上的位置一样。

  1. # 模板匹配
  2. img = cv2.imread('lena.jpg', 0)
  3. template = cv2.imread('face.jpg', 0)
  4. h, w = template.shape[:2]
  1. img.shape

(263, 263)

  1. template.shape

(110, 85)

模板匹配模式 描述
TM_SQDIFF 计算平方不同,计算出来的值越小,越相关
TM_CCORR 计算相关性,计算出来的值越大,越相关
TM_CCOEFF 计算相关系数,计算出来的值越大,越相关
TM_SQDIFF_NORMED 计算归一化平方不同,计算出来的值越接近0,越相关
TM_CCORR_NORMED 计算归一化相关性,计算出来的值越接近1,越相关
TM_CCOEFF_NORMED 计算归一化相关系数,计算出来的值越接近1,越相关


公式:https://docs.opencv.org/3.3.1/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d

  1. methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
  2. 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
  1. res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
  2. res.shape

(154, 179)

  1. min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  2. # 匹配结果矩阵中最小值,匹配结果矩阵中最大值,最小值的位置,最大值的位置
  3. min_val, max_val, min_loc, max_loc

(39168.0, 74403584.0, (107, 89), (159, 62))


遍历所有的模式:

  1. for meth in methods:
  2. img2 = img.copy()
  3. # 匹配方法的真值
  4. method = eval(meth)
  5. print (method)
  6. res = cv2.matchTemplate(img, template, method)
  7. min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  8. # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
  9. if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
  10. top_left = min_loc
  11. else:
  12. top_left = max_loc
  13. bottom_right = (top_left[0] + w, top_left[1] + h)
  14. # 画矩形
  15. cv2.rectangle(img2, top_left, bottom_right, 255, 2)
  16. plt.subplot(121), plt.imshow(res, cmap='gray')
  17. plt.xticks([]), plt.yticks([]) # 隐藏坐标轴
  18. plt.subplot(122), plt.imshow(img2, cmap='gray')
  19. plt.xticks([]), plt.yticks([])
  20. plt.suptitle(meth)
  21. plt.show()

匹配多个对象


匹配多个金币。

  1. img_rgb = cv2.imread('mario.jpg')
  2. img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
  3. template = cv2.imread('mario_coin.jpg', 0)
  4. h, w = template.shape[:2]
  5. res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
  6. threshold = 0.8
  7. # 取匹配程度大于%80的坐标
  8. loc = np.where(res >= threshold)
  9. for pt in zip(*loc[::-1]): # *号表示可选参数
  10. bottom_right = (pt[0] + w, pt[1] + h)
  11. cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)
  12. cv2.imshow('img_rgb', img_rgb)
  13. cv2.waitKey(0)


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

OpenCV 简介与安装

OpenCV 简介与安装[TOC] OpenCV 简介OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库。安...

OpenCV 图像基本操作(学习笔记)

OpenCV 图像基本操作(学习笔记)[TOC] 在一张图像中,每取出一个像素块会分成红绿蓝三种颜色通道,每一种颜色通道都是一...

OpenCV 图像处理(学习笔记)

OpenCV 图像处理(学习笔记)[TOC] 灰度图import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pypl...

OpenCV 图像梯度计算(学习笔记)

OpenCV 图像梯度计算(学习笔记)[TOC] Sobel算子简介Sobel算子是一个图像边缘检测的算法。其基本原理是通过计算像素点梯度...

OpenCV Canny边缘检测(学习笔记)

OpenCV Canny边缘检测(学习笔记)[TOC] Canny边缘检测Canny边缘检测主要是按照如下步骤来进行的边缘检测:1.使用高斯滤波器...

OpenCV 直方图与傅里叶变换(学习笔记)

OpenCV 直方图与傅里叶变换(学习笔记)[TOC] 直方图直方图是一种统计图表,用于展示数据的分布情况。这里将展示图片中直方...

Quartz.NET实例动态改变周期调度。misfireCron

Quartz:Java编写的开源的任务调度作业框架 类似Timer之类定时执行的功能,但是更强大Quartz.NET:是把Quartz转成C# NuGet...

.NET Windows服务发布安装卸载监听脚本。服务调试

一、脚本 为方便不用每次都去写安装卸载的脚本1.安装脚本@echooff @echo开始安装【服务】 %SystemRoot%\Microsoft.NET\Fr...

C ??? 问号和2个问号的用法(类型?对象?)

C# ?C# ???:单问号1.定义数据类型可为空。可用于对int,double,bool等无法直接赋值为null的数据类型进行null的赋值如这...

C outref关键字的用法和区别

说说自己对out、ref的认识,面试问到的几率很高哟。out:classProgram { /* *out、ref都是引用传递,传递后使用都会改变...

cVB.net中全角半角转换方法

///<summary> ///转全角的函数(SBCcase) ///</summary> ///<paramname="input">任意字符串...

redis中主从哨兵和集群这三个有什么区别

主从模式:备份数据、负载均衡,一个Master可以有多个Slaves。sentinel(哨兵)发现master挂了后,就会从slave中重新选举一个...

JS监听inputkeydown,有输入法时打字完成后触发事件

在给输入框绑定input或keydown事件时预期效果是有输入法时,输入中文后触发事件,不希望输一个字母就触发一次事件可以用到c...

下划线换行回车空格ASCII码值与对照表

下划线,ASCII码95换行 , ASCII码10回车 , ASCII码13空格 , ASCII码32ASCII码表:Bin(二进制)Oct(八进制)Dec(十进制)Hex(...

docker常用命令删除镜像命令进入容器docker重启命令等

1. docker version查看 Docker 版本信息2. docker info显示 Docker 系统信息,包括镜像,容器数等3. 运行容器第一次使用:d...
这一世以无限游戏为使命!
排名
2
文章
635
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术