- 模板匹配
- 梯度算法
- 阈值算法
- 形态学算法
- 调用设备摄像头
模板匹配
OpenCV的模板匹配是一种图像处理技术,用于在一幅图像中寻找和模板图像最相似的匹配区域。它在计算机视觉和图像识别领域有着广泛的应用。
模板匹配的基本原理是,将一个模板图像与目标图像进行逐像素的比较,并计算它们之间的相似度。这个相似度值通常使用像素差异度量方法,例如平方差或相关性等。
OpenCV提供了函数matchTemplate()
用于执行模板匹配。它的基本用法如下:
void matchTemplate(InputArray image, InputArray templ, OutputArray result, int method);
image
是输入图像,即待搜索的目标图像。templ
是模板图像,即要搜索的模板。result
是输出结果,用于存储匹配结果的矩阵。method
是匹配方法,可以是以下值之一:TM_SQDIFF
:平方差匹配法TM_SQDIFF_NORMED
:标准化的平方差匹配法TM_CCORR
:相关性匹配法TM_CCORR_NORMED
:标准化的相关性匹配法TM_CCOEFF
:相关系数匹配法TM_CCOEFF_NORMED
:标准化的相关系数匹配法
模板匹配后,会生成一个与原始图像一样大小的矩阵,其中的每个像素都表示该位置和模板的匹配程度。你可以使用minMaxLoc()
函数找到矩阵中的最小值和最大值位置,从而定位到最佳匹配区域。
模板匹配方法的选择取决于你的具体任务和图像特点。不同的方法对光照变化、尺度变化、透视变形等有不同的鲁棒性。你可以根据实际情况进行尝试和调整。
OpenCV的模板匹配提供了一种简单而强大的方式来定位图像中的特定模式。它可以应用于目标检测、物体识别、人脸识别等各种应用场景中。
import cv2
import numpy as np
image=cv2.imread("D:\shapes.png")
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
template=gray[30:160,20:160]
match=cv2.matchTemplate(gray,template,cv2.TM_CCOEFF_NORMED) # 标准相关匹配算法
locations=np.where(match>=0.9)
w,h=template.shape[0:2]
for p in zip(*locations[::-1]):
x1,y1 = p[0],p[1]
x2,y2 = x1 + w, y1 + h
cv2.rectangle(image,(x1,y1),(x2,y2),(0,255,0),2)
cv2.imshow("image",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
梯度算法
图像处理的梯度算法是一种用于计算图像中像素梯度的方法。梯度指的是图像中像素值变化最为剧烈的方向,通过计算梯度可以揭示图像中的边缘、纹理等特征,广泛应用于图像处理领域。
图像处理的梯度算法有多种,常见的包括Sobel算子、Prewitt算子和Laplacian算子等。这些算法通过在图像中进行滤波操作来计算像素的梯度。一般来说,这些算法会对图像进行卷积操作,通过将某个像素点与其周围像素点进行加权求和来计算其梯度值。
拉普拉斯变换
拉普拉斯变换可以用于图像边缘检测,其输出图像中的像素值表示该像素在图像中的灰度值与其周围像素灰度值的差异程度,从而检测出图像中的边缘信息。
Laplacian()
函数的基本用法如下:
dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
src
表示输入图像,可以是灰度图像或彩色图像(在彩色图像上进行处理时,会先转换为灰度图像)。ddepth
表示输出图像的数据类型,通常使用cv2.CV_64F
进行计算,保证输出结果的精度和取值范围。dst
可选参数,表示输出图像。ksize
可选参数,表示拉普拉斯核的大小。默认值为 3,表示使用 3x3 的核。可以选择其他奇数大小的核,如 1、5、7,以满足不同的需求。scale
可选参数,表示结果的比例因子,用于调整输出图像的幅值范围。默认值为 1。delta
可选参数,表示结果的偏移量,在计算完成后添加到输出图像中。默认值为 0。borderType
可选参数,表示图像边界的填充方式。默认值为cv2.BORDER_DEFAULT
。
Laplacian()
函数将输入图像应用拉普拉斯算子操作,并返回结果作为输出图像。通过调整 ksize
、scale
和 delta
等参数,可以对输出图像进行进一步的调整和处理。
使用 Laplacian()
函数可以实现图像的边缘检测、形状分析和图像增强等应用。
import cv2
gray = cv2.imread( "D:\girl.png" , cv2.IMREAD_GRAYSCALE)
laplacian = cv2.Laplacian(gray,cv2.CV_64F)
cv2.imshow( " gray", gray)
cv2.imshow( "laplacian", laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.Laplacian()
函数对图像进行拉普拉斯变换。其中,cv2.CV_64F
表示使用 64 位浮点型数据类型进行计算,以保证每个像素值的精度和取值范围。
可以看出,颜色不变化的区域(比如纯白的背景、纯灰的帽子),经过梯度算法处理之后为黑色,而有颜色变化的区域为白色
canny边缘检测
Canny 算法是一种多阶段的算法,其具体步骤如下:
- 对图像进行灰度化处理,将其转换为单通道的灰度图像。
- 对图像进行高斯滤波,以去除噪声和细节信息。
- 计算图像中每个像素点的梯度和方向,得到图像的梯度图像和角度图像。
- 对梯度图像进行非极大值抑制,即对梯度图像中的每个像素,只保留沿着梯度方向上的局部最大值,并抑制其他值。
- 对抑制后的梯度图像进行双阈值处理,即将像素值大于高阈值的像素视为边缘点,将像素值小于低阈值的像素视为非边缘点,对于位于两者之间的像素要根据其邻近像素的值进行进一步的判断和处理。
- 对处理后的边缘图像进行连接处理,以填补其中的间断和空洞。
- 输出最终的边缘图像。
Canny()
函数的基本用法如下:
edges = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
image
表示输入图像,可以是灰度图像或彩色图像(在彩色图像上进行处理时,会先转换为灰度图像)。threshold1
和threshold2
分别表示边缘检测的阈值,控制边缘的灵敏度和准确性。threshold1
应小于threshold2
,通常选择的比例为 1:2 或 1:3。edges
可选参数,表示输出的边缘图像。如果不指定该参数,则会重新创建一个与输入图像类型和大小相同的图像作为输出。apertureSize
可选参数,表示 Sobel 算子的大小,默认值为 3。L2gradient
可选参数,表示计算梯度时是否使用 L2 范式。默认值为False
,表示使用 L1 范式计算梯度。
使用 Canny()
函数可以实现图像的边缘检测、目标检测和特征提取等应用,是图像处理中一种常用的技术。
import cv2
gray = cv2.imread( "D:\girl.png" , cv2.IMREAD_GRAYSCALE)
canny = cv2.Canny(gray,100,200)
cv2.imshow( " gray", gray)
cv2.imshow( "canny", canny)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.Canny() 函数对灰度图像进行边缘检测。其中,100 和 200 分别表示边缘检测的阈值,即高阈值和低阈值。
若像素<100,则不为边缘;若>200,则为边缘;若在100与200之间,与边缘相连则为边缘,不相连则不为边缘。
Canny 算法会根据这两个阈值来确定边缘的强度和连续性,从而提取出图像的边缘信息。
可以看出,图像的轮廓被提取出来。
import cv2
gray = cv2.imread( "D:\girl.png" , cv2.IMREAD_GRAYSCALE)
canny = cv2.Canny(gray,100,200)
canny2 = cv2.Canny(gray,0,100)
cv2.imshow( "canny", canny)
cv2.imshow( "canny2", canny2)
cv2.waitKey(0)
cv2.destroyAllWindows()
对于canny算法中低阈值和高阈值两个参数,阈值大,边界少,阈值小,边界多。
可以看出canny边界比canny2少
阈值算法
阈值处理,即二值化,将连续分布的灰度范围分为黑与白。
阈值检测的基本思想是将图像中的像素值与一个设定的阈值进行比较,将像素值大于或小于该阈值的像素分成不同的类别。从而实现对图像的分割、提取和去噪等处理。常用的阈值检测方法包括全局阈值、局部阈值等。
全局阈值是指将整幅图像分成明显的两类,其中一个类是图像中的所有像素均小于设定的阈值,另一类则是所有像素均大于该阈值。这种方法常用于基于全局像素强度的目标检测和分割,例如质量控制、背景分离等。
局部阈值分割方法则基于图像的局部特征对图像进行分割。例如,自适应阈值分割方法将每个像素的阈值设定为其周围像素值的平均值或中位数值,这样可以更好地适应图像中的不同区域。另一种常用的局部阈值方法是基于 Otsu 算法的自动阈值分割,适用于复杂图像中的目标检测和分割。
import cv2
gray = cv2.imread("D:\scene.jpg",cv2.IMREAD_GRAYSCALE)
ret,binary = cv2.threshold(gray,50,255,cv2.THRESH_BINARY)
cv2.imshow( "gray", gray)
cv2.imshow( "binary", binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
在代码 ret, binary = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
中,50 和 255 分别代表的是阈值和最大值。
cv2.threshold()
是 OpenCV 库中常用的图像二值化函数,用于将灰度图像转换为二值图像,其主要参数如下:
gray
表示输入的灰度图像。50
表示设定的阈值,在二值化过程中灰度值大于该值的像素均被置为最大值(默认为255),小于该值的像素值则被置为0。255
表示在进行二值化后,设定的最大值(Maxval),即将灰度值大于阈值的像素置为该最大值。cv2.THRESH_BINARY
表示二值化的方法,即对灰度图进行阈值分割时采用的方法。在 THRESH_BINARY 二值化方法中,像素值大于阈值的像素被置为最大值(255),小于等于阈值的像素则被置为0。
函数的返回值包括两个参数:ret
和 binary
。其中,ret
表示被使用的阈值(在这里就是50),binary
表示二值化后的图像。
通过使用 cv2.threshold()
函数进行图像二值化处理,可以将图像转换为黑白二值图像,并提取我们需要的目标图像区域,为后续的图像处理和分析提供基础。
自适应阈值算法
自适应阈值算法:把图片分成很多区域,每个区域独立计算阈值
import cv2
gray = cv2.imread("D:\scene.jpg",cv2.IMREAD_GRAYSCALE)
binary_adaptive = cv2.adaptiveThreshold(
gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,115,1)
cv2.imshow( "gray", gray)
cv2.imshow( "adaptive", binary_adaptive)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.adaptiveThreshold()
函数的参数解释如下:
gray
: 表示输入的灰度图像。255
: 是最大阈值(maxValue),用于将灰度值大于阈值的像素置为最大值(在这里为255)。cv2.ADAPTIVE_THRESH_GAUSSIAN_C
: 表示自适应方法,可以选择cv2.ADAPTIVE_THRESH_MEAN_C
或cv2.ADAPTIVE_THRESH_GAUSSIAN_C
。cv2.THRESH_BINARY
: 表示二值化的方法,将阈值分割后的像素值进行二进制阈值化。115
: 是阈值的大小,用于根据附近像素的平均强度计算自适应阈值。1
: 是用于指定阈值类型的块大小(在这里是1),块大小是包含像素的邻域大小。
Otsu 算法
基于 Otsu 算法的自动阈值分割是一种常用的图像处理方法,用于将图像进行二值化处理。该算法通过分析图像的灰度直方图,自动选择一个合适的阈值,将图像分割为前景和背景两部分。是一种常用且有效的图像处理技术,广泛应用于目标检测、形态学处理、边缘检测等领域。
Otsu 算法不需要人为计算阈值,会自动计算出恰当的阈值
import cv2
gray = cv2.imread("D:\scene.jpg",cv2.IMREAD_GRAYSCALE)
ret1,binary_otsu = cv2.threshold(gray,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow( "gray", gray)
cv2.imshow( "otsu", binary_otsu)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.threshold()
函数的参数解释如下:
gray
: 表示输入的灰度图像。0
: 确定全局阈值的初始值,在这里设置为0。255
: 当阈值处理完成后,大于阈值的像素会被置为最大值(在这里为255)。cv2.THRESH_BINARY + cv2.THRESH_OTSU
: 这里使用了THRESH_BINARY
方法进行二值化处理,并结合了THRESH_OTSU
方法。THRESH_OTSU
方法会根据图像的直方图自动选择一个合适的阈值,使得图像的前景和背景能够得到最佳的分离。
形态学算法
图像的形态学算法是一种基于图像形态学理论的图像处理方法,主要用于图像增强、去噪、分割、边缘检测等任务。形态学算法主要关注图像中物体的形状和结构,通过对图像进行膨胀、腐蚀、开运算、闭运算等操作,改变图像的形态特征。
下面是几个常用的形态学算法:
-
膨胀(Dilation):通过在图像中的每个像素位置上滑动一个结构元素,将结构元素与图像进行逐像素的逻辑计算,将像素值设为周围像素中的最大值。膨胀操作可以增加图像中的亮区域大小,填充物体间的空隙。
-
腐蚀(Erosion):与膨胀相反,腐蚀操作将结构元素与图像逐像素进行逻辑计算,并将结果像素值置为周围像素的最小值。腐蚀操作可以减小图像中的亮区域大小,去除小的噪点。
-
开运算(Opening):先进行腐蚀操作,再进行膨胀操作。开运算可以去除噪点,同时保持物体的整体形状。
-
闭运算(Closing):先进行膨胀操作,再进行腐蚀操作。闭运算可以填充物体间的小空隙,平滑物体边界。
-
骨架提取(Skeletonization):通过连续的腐蚀操作,逐渐减小物体的大小,直到物体变成骨架。骨架提取可以提取物体的主要轮廓和形状信息。
-
模板匹配(Template Matching):根据预先定义的模板图像,通过滑动窗口在目标图像上进行匹配,找到与模板最匹配的位置。模板匹配可用于目标检测和识别。
图像的形态学算法能够对图像进行形态特征的提取、变换和重建,对于图像分析和处理具有重要作用。在实际应用中,根据具体的任务需求和图像特点,选择合适的形态学算法可以有效地改善图像质量和提取所需的信息。
腐蚀和膨胀
# 腐蚀和膨胀
import cv2
import numpy as np
gray=cv2.imread("D:\words.png",cv2.IMREAD_GRAYSCALE)
_,binary=cv2.threshold(gray,200,255,cv2.THRESH_BINARY_INV)
kernel=np.ones((5,5),np.uint8)
erosion=binary
iterations = 1
for i in range(iterations):
erosion = cv2.erode(erosion, kernel)
cv2.imshow("binary",binary)
cv2.imshow("erosion",erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
使用cv2.threshold()
函数对灰度图像进行阈值化处理,将灰度值大于200的像素设置为255(白色),小于等于200的像素设置为0(黑色),并将结果保存到变量binary中。这里使用了cv2.THRESH_BINARY_INV
参数,表示将二值化图像进行反转,即将255像素值的部分设为0,将0像素值的部分设为255。
创建了一个5x5的全1数组作为腐蚀操作的结构元素kernel。
通过一个迭代循环,使用cv2.erode()
函数对erosion进行一次腐蚀操作。通过多次迭代可以增强腐蚀的效果。
要使腐蚀效果更加明显,可以增加腐蚀操作的迭代次数。通过多次执行腐蚀操作,可以进一步减小物体的大小并消除更多的噪点。
将迭代次数iterations修改为3.
# 逐步迭代腐蚀操作
iterations = 3
for i in range(iterations):
erosion = cv2.erode(erosion, kernel)
膨胀同理
import cv2
import numpy as np
gray=cv2.imread("D:\words.png",cv2.IMREAD_GRAYSCALE)
_,binary=cv2.threshold(gray,200,255,cv2.THRESH_BINARY_INV)
kernel=np.ones((5,5),np.uint8)
dilation_1=binary
iterations = 1
for i in range(iterations):
dilation_1 = cv2.dilate(dilation_1, kernel)
dilation_5=binary
iterations = 5
for i in range(iterations):
dilation_5 = cv2.dilate(dilation_5, kernel)
cv2.imshow("binary",binary)
cv2.imshow("dilation_1",dilation_1)
cv2.imshow("dilation_3",dilation_5)
cv2.waitKey(0)
cv2.destroyAllWindows()
调用设备摄像头
# 摄像头
import cv2
capture = cv2.VideoCapture(0)
while True:
ret,frame = capture.read()
cv2.imshow("camera",frame)
key = cv2.waitKey(1)
if key!=-1:
break
capture.release()
cv2.destroyAllWindows()
使用cv2.VideoCapture()
函数创建一个视频捕获对象(摄像头对象),并将其赋值给变量capture。这里的参数0表示使用默认的摄像头设备。
接下来,使用一个无限循环,不断读取摄像头捕获的视频帧。capture.read()
函数返回两个值,ret表示读取是否成功(True/False),frame表示当前捕获的视频帧。这些值分别赋值给ret和frame变量。
是本人举着吹风机女士啦~qaq