图像阈值
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的反转
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
# 显示函数
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#img = cv2.imread("D:/code/jupyter_code/data/lena.jpg")
img=cv2.imread('./data/cat.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 转灰度图
#cv_show1('lena',img)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
# 显示函数
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread("D:/code/jupyter_code/data/lena.jpg")
cv_show1('lena',img)
# 均值滤波
# 简单的平均卷积操作
blur = cv2.blur(img, (3, 3))
# 中值滤波
# 相当于用中值代替
median = cv2.medianBlur(img, 5) # 中值滤波
# 方框滤波
# 基本和均值一样,可以选择归一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True)
# 高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1)
# cv_show1('blur',blur)
# cv_show1('box',box)
# cv_show1('median',median)
# cv_show1('aussian',aussian)
# 展示所有的
res = np.hstack((img,blur,box,aussian,median))
cv_show1('res',res)
卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是1,那么中心元素就保持原来的像素值,否则就变为零。
将前景物体变小,理解成将图像断开裂缝变大。
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread("D:/code/jupyter_code/data/lena.jpg")
cv_show1('img',img)
kernel = np.ones((3,3),np.uint8)
# 函数参数, img是输入的图片, Kernel是卷积核的大小, iterations是重复运行次数。
erosion = cv2.erode(img,kernel,iterations = 1)
cv_show1('erosion',erosion)
kernel = np.ones((30,30),np.uint8)
erosion_1 = cv2.erode(img,kernel,iterations = 1)
erosion_2 = cv2.erode(img,kernel,iterations = 2)
erosion_3 = cv2.erode(img,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv_show1('res',res)
将前景物体变大,理解成将图像断开裂缝变小,与腐蚀相反。
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread("D:/code/jupyter_code/data/dige.png")
cv_show1('img',img)
kernel = np.ones((3,3),np.uint8)
# 函数参数, img是输入的图片, Kernel是卷积核的大小, iterations是重复运行次数。
erosion = cv2.dilate(img,kernel,iterations = 1)
cv_show1('erosion',erosion)
kernel = np.ones((30,30),np.uint8)
img = cv2.imread("D:/code/jupyter_code/data/pie.png")
erosion_1 = cv2.dilate(img,kernel,iterations = 1)
erosion_2 = cv2.dilate(img,kernel,iterations = 2)
erosion_3 = cv2.dilate(img,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv_show1('res',res)
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread("D:/code/jupyter_code/data/dige.png")
cv_show1('img',img)
# 开:先腐蚀,再膨胀
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv_show1('opening',opening)
# 闭:先膨胀,再腐蚀
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv_show1('closing',closing)
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 梯度=膨胀-腐蚀
pie = cv2.imread("D:/code/jupyter_code/data/pie.png")
kernel = np.ones((7,7),np.uint8)
dilate = cv2.dilate(pie,kernel,iterations = 5)
erosion = cv2.erode(pie,kernel,iterations = 5)
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
res = np.hstack((dilate,erosion,gradient))
cv_show1('res',res)
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
#礼帽
img = cv2.imread("D:/code/jupyter_code/data/dige.png")
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
#黑帽
blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
res = np.hstack((img,tophat,blackhat))
cv_show1('res',res)
Sobel算子是典型的基于一阶导数的边缘检测算子,算子引入了类似局部平均的运算,对噪声具有平滑作用,能够很好的消除噪声的影响。缺点:并没有将图像的主题与背景严格地区分开。
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
img = cv2.imread("D:/code/jupyter_code/data/pie.png")
# 水平方向
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,sobelx,sobely,sobelxy))
cv_show1('res',res)
Scharr算子,具有和Sobel算子同样的速 度,且精度更高。可以将Scharr算子看作对Sobel算子的改进,其核通常为:
cv.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]])
src:输入图像
dst:输出图像,大小和类型与 src 相同
ddepth:输出图片的数据深度,由输入图像的深度进行选择
dx:x 轴方向导数的阶数
dy:y 轴方向导数的阶数
scale:缩放比例因子,可选项,默认值为 1
delta:输出图像的偏移量,可选项,默认值为 0
borderType:边界扩充的类型,注意不支持对侧填充(BORDER_WRAP)
Laplacian算子是一种各向同性算子,二阶微分算子,在只关心边缘位置,不考虑其周围的像素灰度差值时较为合适,具有无方向性的优点。对孤立像素的响应要比对边缘或线的响应更强烈,只适用于无噪声图像。存在噪声情况下,使用Laplacian算子检测边缘之前,要进行低通滤波。分割算法都是把Laplacian算子和平滑算子结合起来,生成一个新的模板。
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
img = cv2.imread("D:/code/jupyter_code/data/lena.jpg")
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
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)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show1('res',res)
Canny算子是一个具有滤波,增强,检测的多阶段的优化算子,在进行处理前,Canny算子先利用高斯平滑滤波器来平滑图像以除去噪声,Canny分割算法采用一阶偏导的有限差分来计算梯度幅值和方向,在处理过程中,Canny算子还将经过一个非极大值抑制的过程,最后Canny算子还采用两个阈值来连接边缘。
1、使用高斯滤波器,以平滑图像,滤除噪声。
2、计算图像中每个像素点的梯度强度和方向。
3、应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
4、应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
5、通过抑制孤立的弱边缘最终完成边缘检测。
优点:该方法不容易受噪声干扰,能够检测到真正的弱边缘。
缺点: 易使高频边缘被平滑掉,从而造成边缘丢失。
edges=cv.Canny(image,threshold1,threshold2[,apertureSize[,L2gradient]])
● edges为计算得到的边缘图像。
● image为8位输入图像。
● threshold1表示处理过程中的第一个阈值。
● threshold2表示处理过程中的第二个阈值。
● apertureSize表示Sobel算子的孔径大小。
● L2gradient为计算图像梯度幅度(gradient magnitude)的标识。其默认值为False。
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
img = cv2.imread("D:/code/jupyter_code/data/lena.jpg")
v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show1('res',res)
cv2.pyrDown()函数首先对原始图像进行高斯变换,再通过抛弃偶数行和偶数列实现下采样。
dst_img = cv2.pyrDown(src_img, dstsize)
dst_img:目标图像
src_img:原始图像
dstsize:目标图像大小。 默认行和列都会变成原始图像行和列的1/2, 整幅图像会变成原始图像的1/4。
cv2.pyrUp() 函数首先在原始图像的每个像素的右侧和下侧分别插入零值列和零值行,得到一个偶数行,偶数列(新增的行和列)都是零值的新图,在进行高斯变换,得到上采样的结果图像。
dst_img = cv2.pyrUp(src_img, dstsize)
dst_img:目标图像
src_img:原始图像
dstsize:目标图像大小。 默认行和列都会变成原始图像行和列的2倍, 整幅图像会变成原始图像的4倍。
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show1(name, img): # 长宽高
cv2.imshow(name, img)
cv2.waitKey(0)
img = cv2.imread("D:/code/data/AM.png")
down= cv2.pyrDown(img)
up=cv2.pyrUp(img)
down_up=cv2.pyrUp(down)
l_1=img-down_up
cv_show1('img',img)
cv_show1('down',down)
cv_show1('up',up)
cv_show1('l_1',l_1)