OpenCV自学笔记【API的使用和部分示例】

OpenCV自学笔记

图像读取、显示、保存
  • 读取一张图片
cv.imread("1.jpg",0)
  • 显示一张图片
#以下为OpenCV显示
cv.imshow("image",img) #image为图像的窗口名称,lena为需要加载图像
cv.waitkey(0) #参数为0即为永远等待
#以下为matplotlib显示
from matplotlib import pyplot as plt
plt.imshow(img[:,:,::-1])
  • 保存图像
cv.imwrite() #参数有文件名,要保存在哪里,要保存的图像

绘制图形
  • 绘制直线
cv.line(img,start,end,color,Thickness) 
  • 绘制圆形
cv.circle(img,centerpoint,r,color,Thickness) 
  • 绘制矩形
cv.rectangle(img,leftupper,rightdown,color,Thickness) 
  • 在图像中添加文字
cv.putText(img,text,situation,font,fontsize,color,Thickness,cv.LINE_AA) 
  • 以上操作的示例
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#创建一个全黑图像
img = np.zeros((512,512,3),np.uint8)
#绘制图形
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv.circle(img,(447,63),63,(0,0,255),-1)
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'opencv',(10,500),font,4,(255,255,255),2,cv.LINE_AA)
#显示图像
plt.imshow(img[:,:,::-1])
#plt.title('匹配结果',plt.xticks([]),plt.yticks([]))
plt.show()
图像基本操作
  • 补充获取并修改像素点的值
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread("test\\1.jpg")
px = img[100,100]
blue = img[100,100,0]
img[100,100] = [255,255,255]
img[100,101] = [255,255,255]
img[100,102] = [255,255,255]
plt.imshow(img[:,:,::-1])
plt.show()
  • 获取图像的属性
#获取图像的属性
img.shape       (256,256,3),行2562563通道
img.size        (196608)像素数量
img.dtype       (uint8)
  • 图像通道的拆分与合并
#通道拆分
r,g,b = cv.split(img)
#通道合并
img = cv.merge((b,g,r))
  • 色彩空间的改变
#最常用的为BGR--Gray 和 BGR--HSV
cv.cvtColor(input_image,flag)
'''
flag:
cv.COLOR_BGR2GRAY
cv.COLOR_BGR2HSV
等
'''
算数操作
  • 图像的加减法
img3 = cv.add(img1,img2)
img3 = cv.subtract(img1,img2)

img4 = img1 + img2
img4 = img1 - img2

opencv的加法是饱和操作,即超过最大值则保持最大值;减法低于最小值则保持最小值
直接相加减:250+10=260 260%256=4 //减法250-255=-5,结果为256-5=251

#示例
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图像
img1 = cv.imread("test\\rain.jpg")
img2 = cv.imread("test\\sun.jpg")

#加减法操作
img3 = cv.subtract(img1,img2)
# img3 = cv.subtract(img1,img2)
img4 = img1 + img2
# img4 = img1 - img2

#显示结果
fig,axes = plt.subplots(nrows=1,ncols=2,figsize = (10,8))
axes[0].imshow(img3[:,:,::-1])
axes[0].set_title("cv_add")
axes[1].imshow(img4[:,:,::-1])
axes[1].set_title("straight_add")

plt.show()
  • 图像的乘除法
img3 = cv.mumultiplylti(img1,img2)
img3 = cv.divide(img1,img2)
  • 图像的混合
img3 = cv.addWeighted(img1,0.7,img2,0.3,0)  #前两个参数为权重,第三个为需要再加的常数

图像尺度、位置操作
  • 图像的缩放
#绝对尺寸
cv.resize(img1,(2*cols,2*rows),interpolation=cv.INTER_CUBIC)
#相对尺寸
cv.resize(img1,None,fx=0.5,fy=0.5)
  • 图像的平移
# M为3*3的平移矩阵,dsize为输出图像的大小(列数,行数)
dst = cv.warpAffine(img1,M,dsize)
  • 图像的旋转
# M为旋转矩阵,center旋转中心,angle旋转角度(逆时针),scale缩放比例
M = cv.getRotationMatrix2D(center,angle,scale)
dst = cv.warpAffine(img1,M,dsize)
  • 仿射变换
#创建变化矩阵
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[100,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
#进行仿射变换
dst = cv.warpAffine(img1,M,(cols,rows))
  • 透射变换
#创建变化矩阵
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]])
T = cv.getPerspectiveTransform(pts1,pts2)

#进行透射变换
dst = cv.warpPerspective(img1,T,(cols,rows))
  • 图像金字塔
cv.pyrUp(img)   #上采样
cv.pyrDown(img)   #下采样

形态学操作

理解图像的领域、连通性。了解不同的形态学操作:腐蚀、膨胀、开闭运算、礼帽和黑帽等及不同操作间的关系

  1. 4邻域N4§(水平和垂直四个像素点),D邻域ND§(对角线四个像素点),8邻域N8§(周围一圈)
  2. 4连通,8连通
  3. m连通:对于值V的像素p和q,若①像素q在集合N4§中 ②q在集合ND§中,且N4§与N4(q)的交集为空。则称这两个像素是m连通的,及4连通和D连通的混和连通。
    lt

上面的右图q位置标注错误,应在右边一格
总结 :形态学:一般作用在二值图像上。连通性:①邻域(4,8,D),②连通性(4,8,m)

腐蚀膨胀

概念:膨胀就是使图像中高亮部分扩张,效果图拥有比原图更大的高亮区域;
腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。
膨胀是求局部最大值的操作,腐蚀是求局部最小值的操作。

  1. 腐蚀

具体操作:用一个结构元素扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“与"操作,如果都为1,则该像素为1,否则为0。如下图所示,结构A被结构B腐蚀后:
fs

上图中的腐蚀结果图的第二行的绿色格子应为白色

腐蚀的作用:消除物体边界点,使目标缩小,可以消除小于结构元素的噪声点。
API接口:

cv.erode(img,kernel,iterations)
#参数分别为:要处理的图像,核结构,腐蚀次数
  1. 膨胀
    具体操作:用一个结构元素扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做"“与”操作,如果都为0,则该像素为0,否则为1。如下图所示,结构A被结构B腐蚀后:
    pz

膨胀的作用:将与物体接触的所有背景点合并到物体中,使目标增大,可填补目标中的孔洞。
API接口:

cv.dilate(img,kernel,iterations)
#参数分别为:要处理的图像,核结构,膨胀次数
  • 示例:5*5卷积核实现腐蚀和膨胀的运算
###############################################################
#5*5卷积核实现腐蚀膨胀运算

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图片
img1 = cv.imread("test\\bin.jpg")
rows,cols = img1.shape[:2]

#创建核结构
kernel = np.ones((5,5),np.uint8)

#图像的腐蚀与膨胀
erosion = cv.erode(img1,kernel=kernel)
dilate = cv.dilate(img1,kernel=kernel)

#图像显示
fig,axes = plt.subplots(nrows=1,ncols=3,figsize = (10,8))
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("orignal")
axes[1].imshow(erosion[:,:,::-1])
axes[1].set_title("erosion")
axes[2].imshow(dilate[:,:,::-1])
axes[2].set_title("dilate")

plt.show()
开闭运算

开闭运算是将腐蚀和膨胀按照一定的次序处理。但这二者不是可逆的,即先开后闭不能得到原来的图像。

  • 开运算
    概念:开运算是先腐蚀后膨胀
    作用:分离物体,消除小区域。
    特点:消除噪点,去除小的干扰块,而不影响原来的图像。
    k

  • 闭运算
    概念:与开运算相反,是先膨胀后腐蚀
    作用:消除/闭合物体里面的孔洞。
    特点:可以填充闭合区域。
    b

开闭运算API:

cv.morphologyEx(img,op,kernel)
#参数:img为待处理图像,op为处理方式,分开运算(cv.MORPH_OPEN),闭运算(cv.MORPH_CLOSE),kernel为核结构
  • 开闭运算示例:
###############################################################
#10*10 卷积核实现开闭运算操作

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图片
img1 = cv.imread("./test/open_origin.jpg")
img2 = cv.imread("./test/close_origin.jpg")

#创建核结构
kernel = np.ones((10,10),np.uint8)

#图像的开运算与闭运算
cv_open  = cv.morphologyEx(img1,cv.MORPH_OPEN,kernel=kernel)
cv_close = cv.morphologyEx(img2,cv.MORPH_CLOSE,kernel=kernel)

#图像显示
fig,axes = plt.subplots(nrows=1,ncols=4,figsize = (10,8))
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("orignal_open")
axes[1].imshow(cv_open[:,:,::-1])
axes[1].set_title("open")
axes[2].imshow(img2[:,:,::-1])
axes[2].set_title("orignal_close")
axes[3].imshow(cv_close[:,:,::-1])
axes[3].set_title("close")

plt.show()
礼帽和黑帽
  • 礼帽运算(顶帽,白帽)

礼帽是原图像与“开运算结果图之差”
因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

礼帽运算用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用礼帽运算进行背景提取

  • 黑帽运算
    黑帽是“闭运算结果图”与原图像之差

黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。
黑帽运算用来分离比邻近点暗一些的斑块。

顶帽与黑帽API:

cv.morphologyEx(img,cv.op,kernel)
#与开闭运算同一API,传入op的参数改为:cv.MORPH_TOPHAT,cv.MORPH_BLACKHAT

示例:

###############################################################
#顶帽和黑帽运算操作

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图片
img1 = cv.imread("./test/open_origin.jpg")
img2 = cv.imread("./test/close_origin.jpg")

#创建核结构
kernel = np.ones((10,10),np.uint8)

#图像的顶帽和黑帽
cv_top  = cv.morphologyEx(img1,cv.MORPH_TOPHAT,kernel=kernel)
cv_black = cv.morphologyEx(img2,cv.MORPH_BLACKHAT,kernel=kernel)

#图像显示
fig,axes = plt.subplots(nrows=1,ncols=4,figsize = (10,8))
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("orignal_top")
axes[1].imshow(cv_top[:,:,::-1])
axes[1].set_title("top")
axes[2].imshow(img2[:,:,::-1])
axes[2].set_title("orignal_black")
axes[3].imshow(cv_black[:,:,::-1])
axes[3].set_title("black")

plt.show()

9

图像平滑

1.图像噪声
1.1椒盐噪声

椒盐噪声也称为脉冲噪声,是图像中经常见到的一种噪声,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。椒盐噪声的成因可能是影像讯号受到突如其来的强烈干扰而产生、类比数位转换器或位元传输错误等。例如失效的感应器导致像素值为最小值,饱和的感应器导致像素值为最大值。
6

1.2高斯噪声

⾼斯噪声是指噪声密度函数服从⾼斯分布的⼀类噪声。由于⾼斯噪声在空间和频域中数学上的易处理性,这种噪声(也称为正态噪声)模型经常被⽤于实践中。⾼斯随机变量z的概率密度函数由下式给出:
4
3
2

2.图像滤波
2.1均值滤波

优点:算法简单,计算速度快
缺点:去噪的同时去除了很多细节部分,将图像变得模糊
API:

cv.blur(src, ksize, anchor, borderType)
#src:输⼊图像
#ksize:卷积核的⼤⼩
#anchor:默认值 (-1,-1) ,表示核中⼼
#borderType:边界类型

示例:

###############################################################
#均值滤波操作

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图片
img1 = cv.imread("./test/dog_jiaoyan.jpg")
img2 = cv.imread("./test/dog_guess.jpg")

#均值滤波
cv_jiaoyan  = cv.blur(img1,(10,10),anchor=(-1,-1))
cv_guess = cv.blur(img2,(10,10),anchor=(-1,-1))

#图像显示
fig,axes = plt.subplots(nrows=1,ncols=4,figsize = (10,8))
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("img1")
axes[1].imshow(cv_jiaoyan[:,:,::-1])
axes[1].set_title("cv_jiaoyan")

axes[2].imshow(img2[:,:,::-1])
axes[2].set_title("img2")
axes[3].imshow(cv_guess[:,:,::-1])
axes[3].set_title("cv_guess")

plt.show()
2.2高斯滤波

二维高斯的概率分布函数如下:
1

式中假设了:均值为0,σx = σy
gauss

高斯平滑流程:
1.首先确定坐标分布,以中心点为原点(0,0)
2.根据公式计算出权重矩阵
3.将权重矩阵归一化
4.计算高斯模糊,与权重矩阵相乘
5.将所有点的值相加代替掉中心点的值。
6.对所有点进行此过程。
(若为彩色图像,则对RGB三个通道分别进行高斯平滑)

API:

cv.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)
#src: 输⼊图像
#ksize:⾼斯卷积核的⼤⼩,注意 : 卷积核的宽度和⾼度都应为奇数,且可以不同
#sigmaX: ⽔平⽅向的标准差
#sigmaY: 垂直⽅向的标准差,默认值为0,表示与sigmaX相同
#borderType:填充边界类型

示例:

###############################################################
#高斯滤波操作

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图片
img1 = cv.imread("./test/dog_jiaoyan.jpg")
img2 = cv.imread("./test/dog_guess.jpg")

#高斯滤波
cv_jiaoyan  = cv.GaussianBlur(img1,(5,5),1)
cv_guess = cv.GaussianBlur(img2,(9,9),1)

#图像显示
fig,axes = plt.subplots(nrows=1,ncols=4,figsize = (10,8))
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("img1")
axes[1].imshow(cv_jiaoyan[:,:,::-1])
axes[1].set_title("cv_jiaoyan")

axes[2].imshow(img2[:,:,::-1])
axes[2].set_title("img2")
axes[3].imshow(cv_guess[:,:,::-1])
axes[3].set_title("cv_guess")

plt.show()
2.3中值滤波

中值滤波是⼀种典型的⾮线性滤波技术,基本思想是⽤像素点邻域灰度值的中值来代替该像素点的灰度值。
中值滤波对椒盐噪声(salt-and-pepper noise)来说尤其有⽤,因为它不依赖于邻域内那些与典型值差别很⼤的值。
API:

cv.medianBlur(src, ksize)
#src:输⼊图像
#ksize:卷积核的⼤⼩

示例:

###############################################################
#中值滤波操作 (有效抑制椒盐噪声)

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

#读取图片
img1 = cv.imread("./test/dog_jiaoyan.jpg")
img2 = cv.imread("./test/dog_guess.jpg")

#中值滤波
cv_jiaoyan  = cv.medianBlur(img1,9)
cv_guess = cv.medianBlur(img2,9)

#图像显示
fig,axes = plt.subplots(nrows=1,ncols=4,figsize = (10,8))
axes[0].imshow(img1[:,:,::-1])
axes[0].set_title("img1")
axes[1].imshow(cv_jiaoyan[:,:,::-1])
axes[1].set_title("cv_jiaoyan")

axes[2].imshow(img2[:,:,::-1])
axes[2].set_title("img2")
axes[3].imshow(cv_guess[:,:,::-1])
axes[3].set_title("cv_guess")

plt.show()

直方图

1.灰度直方图

1.1 原理:直⽅图是对数据进⾏统计的⼀种⽅法,并且将统计值组织到⼀系列实现定义好的bin 当中。其中, bin 为直⽅图中经常⽤到的⼀个概念,可以译为 “直条” 或 “组距”,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、⽅向、⾊彩或任何其他特征。

图像直⽅图(Image Histogram)是⽤以表示数字图像中亮度分布的直⽅图,标绘了图像中每个亮度值的像素个数。这种直⽅图中,横坐标的左侧为较暗的区域,⽽右侧为较亮的区域。

直方图例子:在这里插入图片描述
直方图的一些术语和细节
dims:需要统计的特征数⽬。在上例中,dims = 1 ,因为仅仅统计了灰度值。
bins:每个特征空间⼦区段的数⽬,可译为 “直条” 或 “组距”,在上例中, bins= 16。
range:要统计特征的取值范围。在上例中,range = [0, 255]。

直方图的意义:
1.直⽅图是图像中像素强度分布的图形表达⽅式。   
2.它统计了每⼀个强度值所具有的像素个数。
3.不同的图像的直⽅图可能是相同的。

1.2 直方图统计

API:

cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
#images: 原图像。当传⼊函数时应该⽤中括号 [] 括起来,例如:[img]。
#channels: 如果输⼊图像是灰度图,它的值就是 [0];如果是彩⾊图像的话,传⼊的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。 
#mask: 掩模图像。要统计整幅图像的直⽅图就把它设为 None。但是如果你想统计图像某⼀部分的直⽅图的话,你就需要制作⼀个掩模图像,并使⽤它。(后边有例⼦) 
#histSize:BIN的数⽬。也应该⽤中括号括起来,例如:[256]。 
#ranges: 像素值范围,通常为 [0,256]

示例:

#################################################
# 直方图统计

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#读取图片
img1 = cv.imread("./test/1.jpg",0)
plt.imshow(img1,cmap=plt.cm.gray)
plt.show()

hist = cv.calcHist([img1],[0],None,[256],[0,256])

plt.figure(figsize=(10,6),dpi=100)
plt.plot(hist)
plt.grid()
plt.show()
1.3 掩膜的应用

示例:

#####################################################
#掩膜的应用

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1. 直接以灰度图的⽅式读⼊
img = cv.imread('./test/1.jpg',0)
# 2. 创建蒙版
mask = np.zeros(img.shape[:2], np.uint8)
mask[400:650, 200:500] = 255
# 3.掩模
masked_img = cv.bitwise_and(img,img,mask = mask)
# 4. 统计掩膜后图像的灰度图
mask_histr = cv.calcHist([img],[0],mask,[256],[1,256])
# 5. 图像展示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(img,cmap=plt.cm.gray)
axes[0,0].set_title("原图")
axes[0,1].imshow(mask,cmap=plt.cm.gray)
axes[0,1].set_title("蒙版数据")
axes[1,0].imshow(masked_img,cmap=plt.cm.gray)
axes[1,0].set_title("掩膜后数据")
axes[1,1].plot(mask_histr)
axes[1,1].grid()
axes[1,1].set_title("灰度直⽅图")

plt.show()
直方图均衡化
############################################################
#直方图均衡化

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1. 直接以灰度图的⽅式读⼊
img = cv.imread('./test/1.jpg',0)
# 2. 均衡化处理
dst = cv.equalizeHist(img)
# 3. 结果展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(dst,cmap=plt.cm.gray)
axes[1].set_title("均衡化后结果")
plt.show()
自适应均衡化
########################################################
#自适应均衡化

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

# 1. 以灰度图形式读取图像
img = cv.imread('./test/1.jpg',0)
# 2. 创建⼀个⾃适应均衡化的对象,并应⽤于图像
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
# 3. 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("origin")
axes[1].imshow(cl1,cmap=plt.cm.gray)
axes[1].set_title("result")
plt.show()

边缘检测

Sobel边缘检测
Sobel_x_or_y = cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta,borderType)
#src:传⼊的图像
#ddepth: 图像的深度
#dx和dy: 指求导的阶数,0表示这个⽅向上没有求导,取值为0、1。
#ksize: 是Sobel算⼦的⼤⼩,即卷积核的⼤⼩,必须为奇数1、3、5、7,默认为3。
#注意:如果ksize=-1,就演变成为3x3的Scharr算⼦。
#scale:缩放导数的⽐例常数,默认情况为没有伸缩系数。
#borderType:图像边界的模式,默认值为cv2.BORDER_DEFAULT。

#####
#Sobel函数求完导数后会有负值,还有会⼤于255的值。⽽原图像是uint8,即8位⽆符号数,所以Sobel建⽴的图像位数不够,会有截断。因此要使⽤16位有符号的数据类型,即cv2.CV_16S。处理完图像后,再使⽤cv2.convertScaleAbs()函数将其转回原来的uint8格式,否则图像⽆法显示。
#Sobel算⼦是在两个⽅向计算的,最后还需要⽤cv2.addWeighted( )函数将其组合起来

### API
Scale_abs = cv2.convertScaleAbs(x) # 格式转换函数
result = cv2.addWeighted(src1, alpha, src2, beta) # 图像混合

示例:

##########################################################
# Sobel边缘检测

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 读入图像(灰度)
img1 = cv.imread("./test/1.jpg",0)

#计算Sobel卷积的结果(若要使用Scharr算子,则加上 ksize=-1 )
x = cv.Sobel(img1,cv.CV_16S,1,0)
y = cv.Sobel(img1,cv.CV_16S,0,1)

#将计算结果转换为uint8类型
sobel_x = cv.convertScaleAbs(x)
sobel_y = cv.convertScaleAbs(y)

#将两者相加
sobel_img = cv.addWeighted(x,0.5,y,0.5,0)

#显示图像
fig,axes = plt.subplots(nrows=1,ncols=2)
axes[0].imshow(img1,cmap=plt.cm.gray)
axes[0].set_title("origin")
axes[1].imshow(sobel_img,cmap=plt.cm.gray)
axes[1].set_title("result")

plt.show()
Laplacian算子 边缘检测

API:

Laplacian_img = cv.Laplacian(img1,-1,ksize=3)
#Src: 需要处理的图像,
#Ddepth: 图像的深度,-1表示采⽤的是原图像相同的深度,⽬标图像的深度必须⼤于等于原图像的深度;
#ksize:算⼦的⼤⼩,即卷积核的⼤⼩,必须为1,3,5,7。

示例:

##########################################################
# Laplacian算子 边缘检测

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 读入图像(灰度)
img1 = cv.imread("./test/1.jpg",0)

#计算Laplacian卷积的结果
Laplacian_img = cv.Laplacian(img1,-1,ksize=3)

#将计算结果转换为uint8类型
result = cv.convertScaleAbs(Laplacian_img)

#显示图像
fig,axes = plt.subplots(nrows=1,ncols=2)
axes[0].imshow(img1,cmap=plt.cm.gray)
axes[0].set_title("origin")
axes[1].imshow(result,cmap=plt.cm.gray)
axes[1].set_title("result")

plt.show()
Canny 边缘检测

API:

cv2.Canny(image, threshold1, threshold2)
#image:灰度图,
#threshold1: minval,较⼩的阈值将间断的边缘连接起来
#threshold2: maxval,较⼤的阈值检测图像中明显的边缘

模板匹配

API:

res = cv.matchTemplate(img,template,method)
#img: 要进⾏模板匹配的图像
#Template :模板
#method:实现模板匹配的算法,主要有:
#1. 平⽅差匹配(CV_TM_SQDIFF):利⽤模板与图像之间的平⽅差进⾏匹配,最好的匹配是0,匹配越差,匹配的值越⼤。
#2. 相关匹配(CV_TM_CCORR):利⽤模板与图像间的乘法进⾏匹配,数值越⼤表示匹配程度较⾼,越⼩表示匹配效果差。
#3. 利⽤相关系数匹配(CV_TM_CCOEFF):利⽤模板与图像间的相关系数匹配,1表示完美的匹配,-1表示最差的匹配。

示例:

#########################################################
# 模板匹配
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img1 = cv.imread("./test/match_origin.jpg")
img2 = cv.imread("./test/match_temp.jpg")
h,w,l = img2.shape

result = cv.matchTemplate(image=img1,templ=img2,method=cv.TM_CCOEFF)

min_val,max_val,min_loc,max_loc = cv.minMaxLoc(result)

top_left = max_loc
botton_right = (top_left[0]+w,top_left[1]+h)

cv.rectangle(img=img1,pt1=top_left,pt2=botton_right,color=(0,255,0),thickness=2)
plt.imshow(img1[:,:,::-1])
plt.title("result"),plt.xticks([]),plt.yticks([])

plt.show()

霍夫变换

霍夫线检测

API:

cv.HoughLines(img, rho, theta, threshold)
#img: 检测的图像,要求是⼆值化的图像,所以在调⽤霍夫变换之前⾸先要进⾏⼆值化,或者进⾏Canny边缘检测
#rho、theta: ρ 和θ的精确度
#threshold: 阈值,只有累加器中的值⾼于该阈值时才被认为是直线。

示例:

##########################################################
# 霍夫线检测
import numpy as np
import random
import cv2 as cv
import matplotlib.pyplot as plt
# 1.加载图⽚,转为⼆值图
img = cv.imread('./test/calendar.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
plt.imshow(gray,cmap=plt.cm.gray)
plt.show()
edges = cv.Canny(gray, 50, 150)
plt.imshow(edges,cmap=plt.cm.gray)
plt.show()
# 2.霍夫直线变换
lines = cv.HoughLines(edges, 0.8, np.pi / 180, 300)
# 3.将检测的线绘制在图像上(注意是极坐标噢)
for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    x1 = int(x0 + 1000 * (-b))
    y1 = int(y0 + 1000 * (a))
    x2 = int(x0 - 1000 * (-b))
    y2 = int(y0 - 1000 * (a))
    cv.line(img, (x1, y1), (x2, y2), (0, 255, 0))
# 4. 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('霍夫变换线检测')
plt.xticks([]), plt.yticks([])
plt.show()

  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值