文章目录
图像处理基础
import os
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
获取上一级文件路径
abs_path=os.path.abspath("..")
path = abs_path + r"\data\2-7data"
print(path)
图像显示
def cv_show(name, img):
cv.imshow(name, img)
cv.waitKey(0)
cv.destroyAllWindows()
图像读取
def img_test():
abs_path=r"D:\pythonProject1\opencv_code\2-7data\data"
img = cv.imread(path+r"\lena.jpg")
cv_show("lena", img)
#灰度图
cat=cv.imread(path+"\cat.jpg",cv.IMREAD_GRAYSCALE)
cv_show("cat",cat)
img_test()
##
视频读取
def video_show():
video=cv.VideoCapture(path+r"\test.mp4")
while open:
ret,frame=video.read()#ret返回是否能够读取每一帧图像,frame返回视频中的每一帧图像
gray=cv.cvtColor(frame,cv.COLOR_BGR2GRAY)#将BGR图像转为灰度图
if frame is None:
break
if ret==True:
cv.imshow("video",gray)
c=cv.waitKey(50)#每帧图像延迟100ms
if c==27:
break
cv.destroyAllWindows()
图像切片与通道提取分离
图像切片
def cut_img():
cat=cv.imread(path+"\cat.jpg")
#图像切片
img=cat[0:100,0:200]#分别截取高度,宽度
print(img.shape)#顺序:高、宽
通道提取
#保留R通道
cat[:,:,0]=0#关闭b通道
cat[:,:,1]=0#关闭g通道
b,g,r=cv.split(cat)
print(r)
cv.imshow("cut_img",img)
cv.imshow("cat",cat)
cv.imshow("b_cat",b)
cv.waitKey(0)
cv.destroyAllWindows()
cut_img()
边界填充
def border_caplicate():
cat=cv.imread(path+"\cat.jpg",cv.IMREAD_GRAYSCALE)
top_size,bottom_size,left_size,right_size=(100,100,100,100)#设置边界范围(上下左右)
复制法,直接借助原图边缘区域作为填充区域
replicate=cv.copyMakeBorder(cat,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_REPLICATE)
反射法,gfdecba|abcdefg|gfdecba
reflect=cv.copyMakeBorder(cat,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_REFLECT)
#反射法2,gfdecb|abcdefg|fdecba
reflect101=cv.copyMakeBorder(cat,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_REFLECT101)
### 外包装法,abcdefg|abcdefg|abcdefg
wrap=cv.copyMakeBorder(cat,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_WRAP)
### 常量法,直接设置填充色值
const=cv.copyMakeBorder(cat,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_CONSTANT,value=25)
cv_show('cat',cat)
plt.subplot(231),plt.imshow(cat,'gray'),plt.title('gray')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('replicate')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('reflect')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('reflect101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('wrap')
plt.subplot(236),plt.imshow(const,'gray'),plt.title('const')
plt.show()
##
数值计算
def img_numpy_calculate():
cat=cv.imread(path+"\cat.jpg")
add_cat=cat+50#将图像三个通道的色值均加50,越界时(255)自动对256取余
super_cat=cat+add_cat
print(cat[:5,:,0])
print(add_cat[:5,:,0])
print(super_cat[:5,:,0])
cv_show('cat',cat)
cv_show('add_cat',add_cat)
cv_show('super_cat',super_cat)
图像融合
def img_add():
cat=cv.imread(path+"\cat.jpg")
print(cat.shape)
cv_show("cat",cat)
res=cv.resize(cat,(400,224))#重新指定图像大小
print(res.shape)
cv_show("cat",res)
res1=cv.resize(cat,(0,0),fx=3,fy=2)#横轴扩大3倍,纵轴扩大2倍
cv_show('res1',res1)
直接相加
dog=cv.imread(path+"\dog.jpg")
print(dog.shape)
dog=cv.resize(dog,(cat.shape[1],cat.shape[0]))
print(dog.shape)
cat_add_dog=cat+dog#越界取余
cv_show("cat_add_dog",cat_add_dog)
add=cv.add(cat,dog)#越界直接赋值为255
cv_show("add",add)
### 设置权重相加
res=0.6*cat+0.4*dog+0
res=cv.addWeighted(cat,0.6,dog,0.4,0)
cv_show("res",res)
二值化与平滑处理
import os
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 获取上一级文件路径
abs_path=os.path.abspath("..")
path = abs_path + r"\data\2-7data"
def cv_show(name,img):
cv.imshow(name,img)
cv.waitKey(0)
cv.destroyAllWindows()
cat=cv.imread(path+"\cat.jpg",cv.IMREAD_GRAYSCALE)
图像二值化
def src_thresh():
# 参数
# src:图像
# thresh:阈值
# marval:超出阈值所赋的值
# type: 二值化操作类型
# 返回值
# ret:阈值
# thresh:阈值化处理后的图像
#图像二值化:大于阈值的数取最大值255,否则为0
ret1,thresh1=cv.threshold(cat,127,255,cv.THRESH_BINARY)
#图像二值化:大于阈值设置为0,否则为255
ret2,thresh2=cv.threshold(cat,127,255,cv.THRESH_BINARY_INV)
#大于阈值的部分赋值为该阈值,否则不变
ret3,thresh3=cv.threshold(cat,127,255,cv.THRESH_TRUNC)
#小于阈值的部分设置为0,否则不变
ret4,thresh4=cv.threshold(cat,127,255,cv.THRESH_TOZERO)
#大于阈值的部分设置为0,否则不变
ret5,thresh5=cv.threshold(cat,127,255,cv.THRESH_TOZERO_INV)
title=["cat","THRESH_BINARY","THRESH_BINARY_INV","THRESH_TRUNC","THRESH_TOZERO","THRESH_TOZERO_INV"]
img=[cat,thresh1,thresh2,thresh3,thresh4,thresh5]
for i in range(6):
plt.subplot(2,3,i+1),plt.imshow(img[i],"gray")
plt.title(title[i])
plt.show()
图像平滑处理
def blur():
img=cv.imread(path+"\lenaNoise.png")
# cv_show("img",img)
# 均值滤波,取3*3矩阵的均值作为矩阵中心像素点的色值
blur=cv.blur(img,(3,3))
# cv_show("blur",blur)
# 方框滤波
# 归一化为true,即将处理后的色值归一到0-255之间,与均值滤波效果等同,
box1=cv.boxFilter(img,-1,(3,3),normalize=True)
# cv_show("box1",box1)
# 若normalize为false,则直接对卷积核求和,越界直接截断为255
box2=cv.boxFilter(img,-1,(3,3),normalize=False)
# cv_show("box2",box2)
# 高斯滤波,利用正态分布,距离正态分布均值近的数值权重大,距离均值远的数值权重小
# 参数:src,卷积核大小,标准差
gaussian=cv.GaussianBlur(img,(3,3),1)
# cv_show("gaussian_blur",gaussian)
# 中值滤波,取矩阵的中值作为矩阵中心像素点的色值,对于椒盐噪声而言,中值滤波的效果最好
median=cv.medianBlur(img,3)
# cv_show("median",median)
res=np.hstack((blur,gaussian,median))#横向拼接矩阵
cv.imshow("blur,gaussian,median",res)
cv.waitKey(0)
cv.destroyAllWindows()
blur()
图像形态学处理
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import os
abs_path=os.path.abspath("..")
path=abs_path+r"\data\2-7data"
def cv_show(name,img):
cv.imshow(name,img)
cv.waitKey(0)
cv.destroyAllWindows()
img=cv.imread(path+"\dige.png")
腐蚀与膨胀
def erosion_dilate():
# 形态学-腐蚀操作,去除多余噪点
kernel=np.ones((5,5))
erosion=cv.erode(img,kernel,iterations=1)
# res=np.hstack((img,erosion))
# cv_show("res",res)
# pie=cv.imread(path+"\pie.png")
# kernel=np.ones((10,10))
# erosion=cv.erode(pie,kernel,iterations=1)
# res=np.hstack((pie,erosion))
# cv_show("ee",res)
# 形态学-膨胀操作,去除噪点过度处理的还原
dig_dilate=cv.dilate(erosion,np.ones((5,5)),iterations=1)
res=np.hstack((img,erosion,dig_dilate))
cv_show("erosion_dilate",res)
开运算与闭运算
def morphology_openAndClose():
# 开运算:先腐蚀再膨胀
res_open=cv.morphologyEx(img,cv.MORPH_OPEN,kernel=np.ones((5,5)))
cv_show("morphology_open",res_open)
# 闭运算:先膨胀再腐蚀
res_close=cv.morphologyEx(img,cv.MORPH_CLOSE,kernel=np.ones((5,5)))
cv_show("morphology_close",res_close)
梯度运算:膨胀-腐蚀,得到边缘结果
def morphology_gradient():
# pie=cv.imread(path+"\pie.png")
res=cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel=np.ones((5,5)))
cv_show("morphology_gradient",res)
礼帽与黑帽
# 礼帽:原始输入-开运算,得到噪点,可突出更加明亮区域
# 黑帽:闭运算-原始输入,得到噪点轮廓
def tophatAndblackhat():
tophat=cv.morphologyEx(img,cv.MORPH_TOPHAT,np.ones((5,5)))
cv_show("tophat",tophat)
blackhat=cv.morphologyEx(img,cv.MORPH_BLACKHAT,np.ones((5,5)))
cv_show("blackhat",blackhat)
梯度算子
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import os
abs_path=os.path.abspath("..")
path=abs_path+r"\data\2-7data"
img=cv.imread(path+"\lena.jpg",cv.IMREAD_GRAYSCALE)
def cv_show(name,img):
cv.imshow(name,img)
cv.waitKey(0)
cv.destroyAllWindows()
# cv_show("img",img)
sobel算子
# [-1 0 1 [-1 -2 -1
# Gx= -2 0 2 Gy= 0 0 0
# -1 0 1] 1 2 1]
def sobel_grad_test(img=cv.imread(path+"\pie.png")):
# 参数
# src
# ddepth:图像深度,cv.CV_64F可使色值保留负数而不使其截断
# dx:横轴变换,1表示在横轴变换,0表示不变换
# dy:纵轴变换
# ksize表示卷积核大小
sobelx=cv.Sobel(img,cv.CV_64F,1,0,ksize=3)
sobelx=cv.convertScaleAbs(sobelx)#将计算到的矩阵结果取绝对值
sobely=cv.Sobel(img,cv.CV_64F,0,1,ksize=3)
sobely=cv.convertScaleAbs(sobely)
sobel=cv.addWeighted(sobelx,0.5,sobely,0.5,0)
res=np.hstack((img,sobel))
cv_show("res",res)
# sobel_grad_test(img)
# Scharr算子
# [ -3 0 3 [-3 -10 -3
# Gx= -10 0 10 Gy= 0 0 0
# -3 0 3] 3 10 3]
# laplacian算子
# [ 0 1 0
# Gx= 1 -4 1
# 0 1 0]
Scharr算子
sobelx=cv.Sobel(img,cv.CV_64F,1,0,ksize=3)
sobely=cv.Sobel(img,cv.CV_64F,0,1,ksize=3)
sobelx=cv.convertScaleAbs(sobelx)
sobely=cv.convertScaleAbs(sobely)
sobel=cv.addWeighted(sobelx,0.5,sobely,0.5,0)
# scharr算子
scharrx=cv.Scharr(img,cv.CV_64F,1,0)
scharry=cv.Scharr(img,cv.CV_64F,0,1)
scharrx=cv.convertScaleAbs(scharrx)
scharry=cv.convertScaleAbs(scharry)
scharr=cv.addWeighted(scharrx,0.5,scharry,0.5,0)
laplacian算子
laplacian=cv.Laplacian(img,cv.CV_64F)
laplacian=cv.convertScaleAbs(laplacian)
res=np.hstack((img,sobel,scharr,laplacian))
cv_show("img-sobel-scharr-laplacian",res)
canny边缘检测
import os
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
abs_path=os.path.abspath("..")
path=abs_path+r"\data\2-7data"
img=cv.imread(path+"\lena.jpg",cv.IMREAD_GRAYSCALE)
def cv_show(name,img):
cv.imshow(name,img)
cv.waitKey(0)
cv.destroyAllWindows()
# 1.图像平滑处理:高斯滤波去除影响检测的噪点
# 2.利用sobel算子计算各像素点的梯度及其方向
# 3.非极大值抑制:找出在某一领域内梯度极大的像素点并保留,其余的像素点去除
# 4.双阈值检测,检测确定真实的和潜在的边缘
# 5.通过抑制孤立的弱边缘最终完成边缘检测
# 阈值范围较大会导致边缘检测效果较差
# 阈值范围较小会检测出部分噪点
cv1=cv.Canny(img,80,150)#参数:src,下阈值,上阈值
cv2=cv.Canny(img,50,100)
res1=np.hstack((cv1,cv2))
cv_show("lena",res1)
car=cv.imread(path+"\car.png",cv.IMREAD_GRAYSCALE)
car1=cv.Canny(car,120,250)
car2=cv.Canny(car,50,100)
res2=np.hstack((car1,car2))
cv_show("car",res2)