Python opencv图像处理基础总结(四) 模板匹配 图像二值化

简介: 模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题

一、模板匹配


1. 匹配原理


模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。


  • 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域
  • 所以模板匹配首先需要一个模板图像(给定的子图像)
  • 另外需要一个待检测图像—源图像
  • 在待检测图像上,从左到右,从上向下,计算模板图像与重叠子图像的匹配度,匹配度越高,两者相同的可能性越大。


2. 匹配算法


  • TM_SQDIFF是平方差匹配;TM_SQDIFF_NORMED是标准平方差匹配。利用平方差来进行匹配,最好匹配为0;匹配越差,匹配值越大。
  • TM_CCORR是相关性匹配;TM_CCORR_NORMED是标准相关性匹配。采用模板和图像间的乘法操作,数越大表示匹配程度较高,0表示最坏的匹配效果。
  • TM_CCOEFF是相关性系数匹配;TM_CCOEFF_NORMED是标准相关性系数匹配。将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性(随机序列)。


从简单的测量(平方差)到更复杂的测量(相关系数),可获得越来越准确的匹配(同时也意味着越来越大的计算代价)。


3. opencv相关API


opencv的目标匹配函数


cv2.matchTemplate(image, templ, method, result=None, mask=None) ->resultmage参数表示待检测源图像,必须是8位整数或32位浮点。templ参数表示模板图像,必须不大于源图像并具有相同的数据类型。method参数表示计算匹配程度的方法。result参数表示匹配结果图像,必须是单通道32位浮点。如果image的尺寸为WxH,templ的尺寸为wxh,则result的尺寸为(W-w+1)x(H-h+1)


opencv的函数minMaxLoc:在给定的矩阵中寻找最大和最小值,并给出它们的位置。 该功能不适用于多通道阵列,如果需要在所有通道中查找最小或最大元素,要先将阵列重新解释为单通道。


minMaxLoc(src, mask=None) ->minVal, maxVal, minLoc, maxLocsrc参数表示输入单通道图像mask参数表示用于选择子数组的可选掩码minVal参数表示返回的最小值,如果不需要,则使用NULL。maxVal参数表示返回的最大值,如果不需要,则使用NULL。minLoc参数表示返回的最小位置的指针(在2D情况下);如果不需要,则使用NULL。maxLoc参数表示返回的最大位置的指针(在2D情况下);如果不需要,则使用NULL。


opencv的函数 rectangle 用于绘制矩形


cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None) ->imgimg参数表示源图像pt1参数表示矩形的一个顶点(左上)
pt2参数表示与pt1相对的对角线上的另一个顶点(右下)
color参数表示矩形线条颜色 (RGB) 或亮度(灰度图像)thickness参数表示组成矩形的线条的粗细程度,取负值时(如CV_FILLED)函数绘制填充了色彩的矩形。lineType参数表示线条的类型shift参数表示坐标点的小数点位数


代码如下:


importcv2ascvimportnumpyasnpdeftemplate_matching():
sample=cv.imread(r'./test/031.png')    # 模板图像target=cv.imread(r'./test/030.jpg')    # 待检测图像cv.imshow('sample', sample)
cv.imshow('target', target)
# 三种模板匹配算法methods= [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED]
height, width=sample.shape[:2]   # 模板图像的高 宽formethodinmethods:
print(method)
result=cv.matchTemplate(image=target, templ=sample, method=method)  # 计算那个区域匹配最好# 在匹配的结果中寻找   最小值  最大值及最小、最大值的位置min_val, max_val, min_loc, max_loc=cv.minMaxLoc(result)
ifmethod==cv.TM_SQDIFF_NORMED:   # 如果是标准平方差匹配  取最小值位置left_top=min_locelse:
left_top=max_locright_bottom= (left_top[0] +width, left_top[1] +height)  # 加上宽  高# 匹配到最佳位置    画小矩形cv.rectangle(img=target, pt1=left_top, pt2=right_bottom, color=(0, 0, 255), thickness=2)
cv.imshow('match-'+np.str(method), target)
template_matching()
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:


模板图像


匹配结果如下:



二、图像二值化


在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。


该函数的阈值操作属于像素级的操作,在灰度图中,每个像素都对应一个灰度值(0~255,0黑、255白),我们将阈值函数 threshold() 应用于图像,图像的灰度值与阈值进行比较,从而实现二值化处理,目的是滤除太大或太小值像素、消除噪声,从而从灰度图中获取二值图像(将图像的灰度值设置为0或255),实现增强整个图像呈现更为明显的黑白效果,同时也大大减少了数据量。


importcv2ascvimportnumpyasnp# 全局defthreshold_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary=cv.threshold(src=gray, thresh=0, maxval=255, type=cv.THRESH_BINARY|cv.THRESH_OTSU)
# ret, binary = cv.threshold(src=gray, thresh=0, maxval=255, type=cv.THRESH_BINARY | cv.THRESH_TRIANGLE)# ret, binary = cv.threshold(src=gray, thresh=115, maxval=255, type=cv.THRESH_BINARY)# ret, binary = cv.threshold(src=gray, thresh=127, maxval=255, type=cv.THRESH_BINARY_INV)  # 相反# ret, binary = cv.threshold(src=gray, thresh=127, maxval=255, type=cv.THRESH_TRUNC)# ret, binary = cv.threshold(src=gray, thresh=130, maxval=255, type=cv.THRESH_TOZERO)print(f'threshold value:{ret}')    # 阈值    看图像信息丢失情况cv.imshow('threshold binary image', binary)
# 局部  自适应阈值deflocal_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# dst = cv.adaptiveThreshold(src=gray, maxValue=255, adaptiveMethod=cv.ADAPTIVE_THRESH_MEAN_C,#                      thresholdType=cv.THRESH_BINARY, blockSize=25, C=10)     # blockSize必须是奇数  C 常量dst=cv.adaptiveThreshold(src=gray, maxValue=255, adaptiveMethod=cv.ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType=cv.THRESH_BINARY, blockSize=25, C=10)  # blockSize必须是奇数  C 常量cv.imshow('local binary image', dst)
# 自定义   均值作为阈值defcustom_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
h, w=gray.shape[:2]
m=np.reshape(gray, [1, h*w])
mean=m.sum() / (w*h)
print(f'mean:{mean}')
ret, binary=cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
cv.imshow('custom binary image', binary)
src=cv.imread(r'./test/014.png')
cv.imshow('input image', src)
threshold_image(src)
local_image(src)
custom_image(src)
cv.waitKey(0)
cv.destroyAllWindows()


1. 全局阈值函数


cv2.threshold(src, thresh, maxval, type, dst=None)
src-输入图像(多通道,8位或32位浮点)thresh-阈值maxval-最大值type-阈值类型dst-输出图像(与src相同大小和类型以及相同通道数的数组/图像)


阈值类型


  • cv2.THRESH_BINARY 二值阈值化 —— 像素值大于阈值的设为最大值,小于阈值的设为最小值。
  • cv2.THRESH_BINARY_INV 反向二值阈值化 —— 像素值大于阈值的设为最小值,小于阈值的设为最大值。
  • cv2.THRESH_TRUNC 截断阈值化 —— 像素值大于阈值的设为阈值,小于阈值的保持原来的像素值。
  • cv2.THRESH_TOZERO 超过阈值被置0 —— 像素值大于阈值的置为0,小于阈值的保持原来的像素值。
  • cv2.THRESH_TOZERO_INV 像素值大于阈值的保持原来的像素值,小于阈值的置为0。

这些函数都有两个返回值,第一个返回值为使用的阈值,第二个就是阈值化后的图像。


最大类间方差法(OTSU算法 大津法)


对于图像二值化的简单阈值法,我们需要自己提供一个阈值,而最大类间方差法可以根据图像特性,选择最佳的阈值,故它也被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响。按照最大类间方差法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。


它是按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。


  • 应用:是求图像全局阈值的最佳方法,应用不言而喻,适用于大部分需要求图像全局阈值的场合。
  • 优点:计算简单快速,不受图像亮度和对比度的影响。
  • 缺点:对图像噪声敏感;只能针对单一目标分割;当目标和背景大小比例悬殊、类间方差函数可能呈现双峰或者多峰,这个时候效果不好。


代码如下:


importcv2ascv# 全局defthreshold_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary=cv.threshold(src=gray, thresh=0, maxval=255, type=cv.THRESH_BINARY|cv.THRESH_OTSU)
print(f'threshold value:{ret}')    # 阈值    看图像信息丢失情况cv.imshow('threshold binary image', binary)
# 局部  自适应阈值deflocal_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst=cv.adaptiveThreshold(src=gray, maxValue=255, adaptiveMethod=cv.ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType=cv.THRESH_BINARY, blockSize=25, C=10)  # blockSize必须是奇数  C 常量cv.imshow('local binary image', dst)
src=cv.imread(r'./test/014.png')
cv.imshow('input image', src)
threshold_image(src)
local_image(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:


2. 局部阈值函数


全局阈值法对于某些光照不均的图像,这种全局阈值分割的效果不好。

而利用局部阈值法,根据图像上的每一个小区域计算与其对应的阀值。因此在同一幅图像上的不同区域采用的是不同的阀值,从而使我们在亮度不同的情况下得到更好的结果。


cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None): 
src-输入图像(8位单通道图像)maxValue-THRESH_BINARYTHRESH_BINARY_INV的最大值adaptiveMethod-自适应阈值算法,平均(ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)thresholdType-阈值类型,必须为THRESH_BINARY或THRESH_BINARY_INV的阈值类型blockSize-块大小(奇数且大于1)C-常量,从平均值或加权平均值中减去的数


代码如下:


importcv2ascvimportnumpyasnp# 全局defthreshold_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary=cv.threshold(src=gray, thresh=0, maxval=255, type=cv.THRESH_BINARY|cv.THRESH_OTSU)
print(f'threshold value:{ret}')    # 阈值    看图像信息丢失情况cv.imshow('threshold binary image', binary)
# 局部  自适应阈值deflocal_image(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst=cv.adaptiveThreshold(src=gray, maxValue=255, adaptiveMethod=cv.ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType=cv.THRESH_BINARY, blockSize=25, C=10)  # blockSize必须是奇数  C 常量cv.imshow('local binary image', dst)
src=cv.imread(r'./test/032.png')
cv.imshow('input image', src)
threshold_image(src)
local_image(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:


目录
相关文章
|
1月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
324 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
7天前
|
计算机视觉 开发者 Python
利用Python进行简单的图像处理
【10月更文挑战第36天】本文将引导读者理解如何使用Python编程语言和其强大的库,如PIL和OpenCV,进行图像处理。我们将从基本的图像操作开始,然后逐步深入到更复杂的技术,如滤波器和边缘检测。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供新的视角和技能,让你能够更好地理解和操作图像数据。
|
1月前
|
计算机视觉 Python
python利用pyqt5和opencv打开电脑摄像头并进行拍照
本项目使用Python的PyQt5和OpenCV库实现了一个简单的摄像头应用。用户可以通过界面按钮打开或关闭摄像头,并实时预览视频流。点击“拍照”按钮可以捕捉当前画面并保存为图片文件。该应用适用于简单的图像采集和处理任务。
99 0
python利用pyqt5和opencv打开电脑摄像头并进行拍照
|
1月前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
68 2
|
1月前
|
算法 数据可视化 计算机视觉
Python中医学图像处理常用的库
在Python中,医学图像处理常用的库包括:ITK(及其简化版SimpleITK)、3D Slicer、Pydicom、Nibabel、MedPy、OpenCV、Pillow和Scikit-Image。这些库分别擅长图像分割、配准、处理DICOM和NIfTI格式文件、图像增强及基础图像处理等任务。选择合适的库需根据具体需求和项目要求。
46 0
|
1月前
|
数据挖掘 计算机视觉 Python
基于Python的简单图像处理技术
【10月更文挑战第4天】在数字时代,图像处理已成为不可或缺的技能。本文通过Python语言,介绍了图像处理的基本方法,包括图像读取、显示、编辑和保存。我们将一起探索如何使用PIL库进行图像操作,并通过实际代码示例加深理解。无论你是编程新手还是图像处理爱好者,这篇文章都将为你打开一扇新窗,让你看到编程与创意结合的无限可能。
|
3月前
|
计算机视觉 开发者 Python
使用Python进行简单图像处理
【8月更文挑战第31天】 本文将介绍如何使用Python编程语言来处理图像。我们将通过代码示例来展示如何读取、显示、编辑和保存图像文件。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供一个清晰的指引,帮助你开始自己的图像处理项目。
|
3月前
|
存储 编解码 API
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
245 1
|
3月前
|
算法 定位技术 vr&ar
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
497 0
一文了解PnP算法,python opencv中的cv2.solvePnP()的使用,以及使用cv2.sovlePnP()方法标定相机和2D激光雷达
|
3月前
|
机器学习/深度学习 人工智能 监控
利用Python和OpenCV实现实时人脸识别系统
【8月更文挑战第31天】本文将引导您了解如何使用Python结合OpenCV库构建一个简易的实时人脸识别系统。通过分步讲解和示例代码,我们将探索如何从摄像头捕获视频流、进行人脸检测以及识别特定个体。本教程旨在为初学者提供一条明晰的学习路径,帮助他们快速入门并实践人脸识别技术。