8 bits(位值)-> 256 levels(分辨率)
灰度图像:0黑色-255白色,将灰色分成256级,一层
全彩图像RGB:颜色通道(红、绿、蓝),三层,每层的0-255代表该层颜色的亮度,opencv里是BGR
HSV:色调(H),饱和度(S),明度(V)(增加黑色V减小,增加白色S减小)
H 0-180 ,S 0-255 ,V 0-255
与或非
像素:
VGA:640*480
HD:1280*720
FHD:1920*1080
4K:3840*2160
Opencv中最常用的两种颜色空间转换:BGR<->GRAY,BGR<->HSV
bgr先要变换成hsv再目标检测
uint8:8位无符号整型
opencv基础操作代码: 打开照片:import numpy as np //python的矩阵库
import matplotlib.pyplot //加入窗口的库
import cv2 as cv
img = cv.imread("Picturelove.jpg")
#要在项目工作空间的文件夹里的照片才行
"""img = cv2.imread("Picturelove.jpg",cv2.IMREAD_GRAYSCALE)"""
#后面的第二参数是转化成灰度图
# C:UserszhaohaobingPycharmProjectspython-opencv-projectpicture
img = cv.resize(img,None,fx = 0.5,fy = 0.5)
#控制输出图像尺寸(图像,要输出的尺寸大小,长宽各变成几倍)
img_dog = cv2.resize(img_dog, (500, 414))
#输出指定长宽
cv.imshow("love",img)
#照片名字不能用中文的
cv.waitKey(0)
#等待时间,毫米级,0代表任意键才终止
cv.destroyAllWindows()
#任意键关闭
cv.imwrite('picture mylove.png',img)
#将照片保存
#res = np.hstack((img1,img2,img3))
#把()里这n张照片放一起
print(img.shape)
#(1200, 1920, 3) h w c(3层还是1层)
print(type(img))
#格式
print(img.size)
#像素点个数
print(img.dtype)
#uint8 数据类型 8位
读取视频:
import numpy as np
import matplotlib.pyplot
import cv2 as cv
vc = cv.VideoCapture("videoHow do you use your time.mp4")
if vc.isOpened():
open,frame = vc.read()
#open返回一个True或False,vc.read()是取第一帧第二帧...赋给frame
else:
open = False
while open:
ret,frame = vc.read()
if frame is None:
break
if ret == True:
#gray = cv.cvtColor(frame,cv.COLOR_BGRA2GRAY)
#灰度处理
cv.imshow("mytime",frame)
if cv.waitKey(10) == ord("q"):
#按q键退出键推出视频
break
vc.release()
cv.destroyAllWindows()
打开摄像头:
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
#一般电脑内置摄像头为0,可以通过设置成 1 或者其他的来选择别的摄像头
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# Capture frame-by-frame
ret, frame = cap.read()
# if frame is read correctly ret is True
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# Our operations on the frame come here
#gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#你也可以注释掉这行颜色转换的代码
# Display the resulting frame
cv.imshow('myCamera', frame)
if cv.waitKey(1) == ord('q'):
break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
保存视频:
#是从摄像头中捕获视频,沿水平方向旋转每一帧并保存它
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# Define the codec and create VideoWriter object
fourcc = cv.VideoWriter_fourcc(*'XVID')
# ourCC 码以下面的格式传给程序,
# 以 MJPG 为例:cv.VideoWriter_fourcc('M','J','P','G')或者 cv.VideoWriter_fourcc(*'MJPG')。
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
frame = cv.flip(frame, 0)
# write the flipped frame
out.write(frame)
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# Release everything if job is finished
cap.release()
out.release()
cv.destroyAllWindows()
画线:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)
# Draw a diagonal blue line with thickness of 5 px
#(名字,起始点,终止点,颜色(opencv中是BGR),宽度)
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv.imshow('img', img)
cv.waitKey(0)
画矩形:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)
#(名字,左上坐标,右下坐标,颜色(BGR),框线宽度)
#左上角为(0,0)点,向右x正方向,向下y正方向
cv.rectangle(img,(0,0),(100,100),(0,255,0),3)
cv.imshow('img', img)
cv.waitKey(0)
画圆:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)
#(名字,圆心,半径,颜色(BGR),框线厚度(-1及填鸭))
cv.circle(img,(100,100), 66, (0,0,255), -1)
cv.imshow('img', img)
cv.waitKey(0)
画椭圆:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)
#(名字,中心点,长轴短轴长度,整体沿逆时针方向旋转角度,
# 起始角度,终止角度(是不是完成椭圆),颜色,线框宽度
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
cv.imshow('img', img)
cv.waitKey(0)
画多边形:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)
#各个顶点坐标,数据类型int32
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))
cv.imshow('img', img)
cv.waitKey(0)
写字:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((500,500,3), np.uint8)
#调用函数,写的字赋给font
font = cv.FONT_HERSHEY_SIMPLEX
#(名字,要写的文字,位值,字,字体大小,颜色,字体笔画宽度
# cv.LINE_AA(字体类型)
cv.putText(img,'OpenCV',(10,500), font, 8,(255,255,255),2,cv.LINE_AA)
cv.imshow('img', img)
cv.waitKey(0)
图像的基础操作:
import cv2 as cv
img = cv.imread("pictureme.jpg")
#像素的行和列的坐标获取他的像素值
print(img.item(10,10,2))
#修改像素值
img.itemset((10,10,2),100)
print(img.item(10,10,2))
#获取图像属性(行数,列数, 通道数)
print(img.shape)
#图像的像素数目
print(img.size)
#图像的数据类型
print(img.dtype)
截取选定区域:
import cv2 as cv
img = cv.imread("pictureme.jpg")
#截取选定区域
something = img[0:300, 70:350]
cv.imshow('something',something)
cv.waitKey(0)
Opencv中常用的颜色空间就三种BGR、HSV、灰度:
Opencv中最常用的两种颜色空间转换:BGR<->GRAY,BGR<->HSV
bgr先要变换成hsv再目标检测
import cv2 as cv
img1 = cv.imread("pictureme.jpg")
img2 = cv.imread("pictureme.jpg")
#BGR↔Gray 的转换
hsv1 = cv.cvtColor(img1, cv.COLOR_BGRA2GRAY)
#BGR↔HSV 的转换
hsv2 = cv.cvtColor(img1, cv.COLOR_BGR2HSV)
cv.imshow("img1",hsv1)
cv.imshow("img2",hsv2)
cv.waitKey(0)
H(色彩/色度)的取值范围是 [0,179], S(饱和度)的取值范围 [0,255],V(亮度)的取值范围 [0,255]。
颜色跟踪:在 HSV 颜色空间中要比在 BGR 空间 中更容易表示一个特定颜色。
import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while True :
ret,frame = cap.read()
#每一帧先mask处理
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
#np.array 创建一个数组
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
#mask将符合数值区间的黑白提取出来
#mask掩膜1、创造一个与原图大小相同的全白图(像素全是1),原图中像素在设置区间里的赋为1,其他像素点赋为0,两张图片进行与运算(都为1才为1),则得到mask(全黑图提取部分为白色)
mask = cv.inRange(hsv,lower_blue,upper_blue)
#res将提取出来的在还原颜色
# frame和frame先取’与‘操作,在用其结果和mask取’与‘操作
# 将mask中白色地方的颜色在前面结果对应地方中显示出来)
res = cv.bitwise_and(frame,frame,mask = mask)
cv.imshow('frame', frame)
cv.imshow('mask', mask)
cv.imshow('res', res)
if cv.waitKey(5) & 0xff ==ord("q"):
break
cv.destroyAllWindows()
BGR通道分离和合并:
#通道分离
b,g,r = cv.split(frame)
cv.imshow("blue",b)
cv.imshow("green",g)
cv.imshow("red",r)
#第三个通道赋值为零,前面::表示取所有
frame[:,:,2] = 0
#合并
frame = cv.merge([b,g,r])
程序运行时间:
import cv2 as cv e1 = cv.getTickCount() #函数a e2 = cv.getTickCount() #可得函数a运行时间 time = (e2 - e1)/cv.getTickFrequency() print(time)
与& 两个1才为1(黑色是0,白色是1,黑色区域不显示,白色区域显示另一张照片颜色)
and
或| 有1就1 (
not
非~ 0变1 1变0
数值操作:#每个像素点都+10 img_cat2= img_cat +10 #取前五行,所有列,方面后面打印看部分像素值 img_cat[:5,:,0]腐蚀操作:
1、先设置滤波器大小
2、设置迭代次数
3、滤波器从左上依次到右下,如果该地方滤波器内像素剧烈变化,对该地方进行腐蚀,即图形信息变细边小,去掉毛毛刺刺
kernel = np.ones((3,3),np.uint8) #设置he的大小,he越大每次腐蚀的范围就越大
erosion = cv2.erode(img,kernel,iterations = 1) #迭代次数,迭代此时越多腐蚀越多
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
膨胀操作:
与腐蚀操作相反,图像变胖
一般先腐蚀去噪,再膨胀恢复
kernel = np.ones((3,3),np.uint8)
dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)
cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()
开运算、闭运算、梯度运算、礼帽、黑帽:(腐蚀、膨胀综合操作)
#例如图像 # 开:先腐蚀,再膨胀 (刺没了) kernel = np.ones((5,5),np.uint8) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # 闭:先膨胀,再腐蚀 (刺变胖了) kernel = np.ones((5,5),np.uint8) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) # 梯度=膨胀-腐蚀,取膨胀和腐蚀中间的部分 gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel) #礼帽 = 原始输入-开运算结果 (只剩刺) tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) #黑帽 = 闭运算-原始输入(只剩刺的轮廓,也可反应主体信息的轮廓) blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)两照片操作:
import cv2 as cv
import numpy as np
#res = 0.4*cat + 0.6*dog + 0
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)
#两图片相加
def add_demo(m1,m2):
dst = cv.add(m1,m2)
cv.imshow("add_demo",dst)
#两图片相减
def subtract_demo(m1,m2):
dst = cv.subtract(m1,m2)
cv.imshow("subtract_demo",dst)
#两照片相乘
def multiply_demo(m1,m2):
dst = cv.multiply(m1,m2)
cv.imshow("multiply_demo",dst)
#两照片相除
def divide_demo(m1,m2):
dst = cv.divide(m1,m2)
cv.imshow("divide_demo",dst)
#
def logic_demo(m1,m2):
dst = cv.bitwise_and(m1,m2)
cv.imshow("bitwise_and", dst)
img1 = cv.imread("picture班徽(中文).jpg")
img2 = cv.imread("picture班徽En.jpg")
cv.namedWindow('image', cv.WINDOW_NORMAL)
cv.imshow('image1', img1)
cv.imshow('image2', img2)
add_demo(img1,img2)
subtract_demo(img1,img2)
multiply_demo(img1,img2)
divide_demo(img1,img2)
cv.waitKey(0)
cv.destroyAllWindows()
图像阈值:
"""
语法:ret, dst = cv2.threshold(src, thresh, maxval, type)
- dst: 输出图
- src: 输入图,只能输入单通道图像,通常来说为灰度图
- thresh: 阈值
- maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- type:二值化操作的类型,包含以下5种类型
"""
#cv2.THRESH_BINARY:超过阈值部分取maxval(最大值),否则取0 (二值化)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
#cv2.THRESH_BINARY_INV:THRESH_BINARY的反转,超过阈值部分取0,小于部分取最大值
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
#cv2.THRESH_TRUNC:大于阈值部分设为阈值,小于的不变
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
#cv2.THRESH_TOZERO:大于阈值部分不改变,小于的设为0
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
#cv2.THRESH_TOZERO_INV:THRESH_TOZERO的反转,大于阈值部分设为0,小于的不变
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()
- cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
滤波:
图像梯度-Sobel算子:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-490nIwbE-1647413238967)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencv图像梯度-sobel算子.png)]
Gx是水平方向上的检测,Gy是竖直方向上的检测,检测点是九宫格的中间点,距离中心点近的数值大,中心点梯度检测的权重大
X:右减左 A3-A1+2A6-2A4+A9-A7 得到的值越大梯度越大
""" 语法: dst = cv2.Sobel(src, ddepth, dx, dy, ksize) (输入照片、图像深度(一般为-1)、dxdy选择进行哪个方向的检测那个赋1另一个为0,ksize是sobel算子大小) """ #x方向检测 sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) #对图像深度进行取绝对值,以为sobel运算结果可能为负值,在opencv中取值是0-255,为负值以后就变成0,所有要取决绝对值,把负值的部分也显示出来 sobelx = cv2.convertScaleAbs(sobelx) cv_show(sobelx,'sobelx') #Y方向检测 sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobely = cv2.convertScaleAbs(sobely) cv_show(sobely,'sobely') #再求和,(x,权重,y,权重,0(这里是偏置项,设置为0)) sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) cv_show(sobelxy,'sobelxy')均值滤波:
设置一个单位矩阵(he(滤波器)边长需为奇数)例3*3
该he从图像左上角滑动到右下角做内积(对应点相乘)
he的中心点的像素点变为为he内九个像素点的平均值。
# 均值滤波
# 简单的平均卷积操作
blur = cv2.blur(img, (3, 3))
cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
高斯滤波:
设置一个矩阵(he(滤波器)边长需为奇数)例3*3,中间是1,四种根据远近权重不同
该he从图像左上角滑动到右下角做内积 (对应点相乘)
he的中心点的像素点变为为he内九个像素点的平均值。
# 高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1)
cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
中值滤波:
设置一个he(滤波器)边长需为奇数例3*3
该he从图像左上角滑动到右下角
he的中心点的像素点变为为he内九个像素点的平均值。
# 中值滤波
# 相当于用中值代替
median = cv2.medianBlur(img, 5) # 中值滤波
cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()
三种滤波比较:
中值滤波适合处理椒盐噪声;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tpeBTbRQ-1647413238968)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencv三种滤波.jpg)]
模糊处理去噪:#均值模糊-去随机噪声
def blur_demo(image):
dst = cv.blur(image,(15,1))
#(1,3)定义一个滤波器一行三列,前值控制横方向的模糊,后值控制纵方向的模糊
dst = cv.resize(dst ,None,fx = 0.5,fy = 0.5)
#控制输出图像尺寸(图像,要输出的尺寸大小,长宽各变成几倍)
cv.imshow("blur_demo",dst)
#中值模糊-去噪椒盐噪声(小黑点)
def median_blur_demo(image):
dst = cv.medianBlur(image,5)
cv.imshow("median_blur_demo",dst)
#自定义模糊
def custom_blur_demo(image):
kernel = np.ones([5,5],np.float32)/25
#ones([5,5] 5*5大小的全是1的矩阵 /25结果除25保证不溢出
#kernel = np.array([0,-1,0],[-1,5,-1],[0,-1,0],np.float32)
#锐化,自定义滤波器总和要为奇数,或=1做增强,=0做边缘
dst = cv.filter2D(image,-1,kernel = kernel)
cv.imshow("custom_blur_demo",dst)
Carry边缘检测:
1、去噪,使用高斯滤波器,以平滑图像,滤除噪声。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-omyuyMwX-1647413238969)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvcanny_1.png)]
2、利用sobel算子计算图像中每个像素点的梯度强度和方向。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koagvcKX-1647413238969)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvcanny_2.png)]
3、应用非极大值抑制,以消除边缘检测带来的杂散响应。
(非极大值抑制:即一张图像里有多个目标同时目标相互重叠,这时需要进行非极大值抑制保留概率最大的那个)
4、应用双阈值检测来确定真实的和潜在的边缘。
(即进行两次边界检测保证是边界)
5、通过抑制孤立的弱边缘最终完成边缘检测。
img=cv2.imread("lena.jpg",cv2.IMREAD_GRAYSCALE)
#(picture,minVal,maxval) minVal越小、maxVal越小,保留的边界信息越多
v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')
上采样、下采样:
上采样(放大):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RbLEnZwo-1647413238969)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvPyramid_3.png)]
下采样(缩小):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sm14jstA-1647413238970)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvPyramid_2.png)]
#上采样,将照片放大 up=cv2.pyrUp(img) cv_show(up,'up') print (up.shape) #下采样,将照片缩小 down=cv2.pyrDown(img) cv_show(down,'down') print (down.shape)轮廓检测:
"""
语法:
cv2.findContours(img,mode,method)
mode:轮廓检索模式
-(默认是它)RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;
method:轮廓逼近方法,即画轮廓
- CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
- CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
"""
img = cv2.imread('contours.png')
#先灰度再二值
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv_show(thresh,'thresh')
#二值结果,轮廓信息,轮廓层级(传入预处理的图案,检索所有的轮廓,把所有点都画出来)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不原图会变。。。
#把原图像复制过来操作,避免添加了轮廓信息以后原图像被毁
draw_img = img.copy()
#(被画的图像,轮廓信息,默认-1即把所有轮廓都画上来,轮廓颜色,线条宽度)
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show(res,'res')
轮廓近似:
在一个图形中,任意两点间连一条线,两点间的曲线上距离该线的最远点的距该线的距离,与阈值作比较
最远距离<阈值:则用该直线代替;
最远距离>阈值:取该点为独立点,与上述两点进行连线,该点与上述两点间各种曲线上的点继续执行上述操作
#轮廓近似
img = cv2.imread('contours2.png')
#先灰度后二值
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
#做轮廓
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]
#轮廓阈值设置 0.15*周长
epsilon = 0.15*cv2.arcLength(cnt,True)
#轮廓近似 = (输入的轮廓,阈值,true)
approx = cv2.approxPolyDP(cnt,epsilon,True)
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv_show(res,'res')
高斯模糊:
浮点数计算,耗时耗资源
9*9滤波器 一般拆分成一个横3和一个竖3的两个滤波器,连续处理两次,减少运算量,加快速度
#保证加上噪音后数据还在0-255
def clamp(pv):
if pv > 255:
return 255
if pv < 0:
return 0
else :
return pv
#高斯模糊(均值模糊的拓展)基于权重的
#加噪声
def gaussian_noise(image):
h,w,c = image.shape
for row in range(0,h,1):
#从0开始到h每次加1,(row排)
for col in range(w):#(col列)
s = np.random.normal(0,20,3)
#产生随机数的(从0开始到20产生3个
b = image[row, col, 0] #blue
g = image[row, col, 1]
r = image[row, col, 2]
image[row, col, 0] = clamp(b + s[0])
image[row, col, 1] = clamp(b + s[1])
image[row, col, 2] = clamp(b + s[2])
cv.imshow("noise_image",src)
gaussian_noise(src)
#高斯处理
dst = cv.GaussianBlur(src,(0,0),15)
#15为高斯公式中的一个参值
cv.imshow("Gaussian",dst)
边缘保留滤波:(EPF)(美颜)
色彩边缘处,数据差异太大,不参与均值模糊,保留,即高斯双边模糊,差异位值的左右都模糊,差异位值保留
#双边高斯模糊(磨皮效果)
def bi_demo(image):
dst = cv.bilateralFilter(image,0,100,15)
#sigmacolor 取大一点,小的差异模糊掉;sigmaspace取小一点,和会小一点,减小计算量
cv.imshow("bi_demo",dst)
#均值迁移(会有地方过度模糊)(油画效果)
def shift_demo(image):
dst = cv.pyrMeanShiftFiltering(image,10,50)
cv.imshow("bi_demo",dst)
边界填充:
#上下左右填充的多少
top_size,bottom_size,left_size,right_size = (50,50,50,50)
#cv2.copyMakeBorder(图像,上,下,左,右,复制方法)
#BORDER_REPLICATE:复制法,也就是复制最边缘像素
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
#BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
#BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
#BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
#BORDER_CONSTANT:常量法,常数值填充
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)
import matplotlib.pyplot as plt
#plt.subplot(列数,行树,本照片在第几个)
plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
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('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()
模板匹配:
图img1原图,图img2是img1图中一部分,模板匹配就是看img1图中哪个地方最像B
""" 匹配模式: TM_SQDIFF_NORMED:归一化平方,计算结果越接近0越相关 TM_CCORR_NORMED:归一化相关性,计算结果越接近1越相关 TM_CCOEFF_NORMED:归一化相关系数,计算结果越接近1越相关 """ #灰度处理以后 #最后一个输入为匹配模式 #res为2从左上到右下遍历完1以后,每个位置得到的差异值,res长宽分布为 X1-X2+1,Y1-Y2+1 res = cv2.matchTemplate(img1,img2,cv2.TM_SQDIFF_NORMED) #差异化最小值,差异化最大值,差异化最小值时位置的左上坐标,差异化最大值时位置的左上坐标 min_val,max_val.min__loc,max_loc = cv2.minMaxLoc(res)
匹配多个对象:(1中有多个2)
#灰度处理后进行匹配
res = cv2.matchTemplate(img1,img2,cv2.TM_SQDIFF_NORMED)
#设置阈值,预测结果大于0.8的都留下
threshold = 0.8
loc = np.where(res>=threshold)
for pt in zip(*loc[::-1]): #*表示可选参数
bottom right = (pt[0] + w , pt [1]+h)
cv2.rectangle(img_rgb,pt,bottom_right,(0,0,255),2)
cv2.imshow('img.rgb',img reb)
cv2.waitKey(0)
直方图:
bin(横坐标0-255,共256个)
横坐标bin,纵坐标个数,统计图像中不同像素值的个数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWRDQdRX-1647413238970)(C:UserszhaohaobingAppDataRoamingTyporatypora-user-imagesimage-20210224190221661.png)]
#调用包
def plot_demo(image):
plt.hist(image.ravel(),256,[0,256])
plt.show()
#自己写
def image_hist(image):
color = ('blue','green','red')
for i,color in enumerate(color):
hist = cv.calcHist([image],[i],None,[256],[0,256])
plt.plot(hist, color = color)
plt.xlim([0,256])
plt.show()
树莓派教学中的opencv
待整理



