opencv笔记上传
title: opencv
date: 2023-03-22 23:29:56
tags:
opencv学习笔记上传
# *创建与显示窗口
# namedWindow(name,flag)
# imshow(name,flag)
# destroyALLWindows()
# resizeWindow(name,width,height)
'''
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
cv2.imshow('new',0)
cv2.resizeWindow('new',1920,1080)
key = cv2.waitKey(0)
if key == 'q' :
exit()
'''
# *打开文件,并显示
# imread()
'''
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
img = cv2.imread('./0.webp',)
cv2.imshow('new',img)
if cv2.waitKey(0) & 0xff==ord('q'):
cv2.destroyAllWindows()
'''
# *保存图片
# imwrite(name,img)
'''
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
img = cv2.imread('./123.png',)
cv2.imshow('new',img)
if cv2.waitKey(0) & 0xff==ord('Q'):
cv2.destroyAllWindows()
elif cv2.waitKey(0) & 0xff==ord('S'):
cv2.imwrite('./1/123.jpg',img)
print("已保存")
'''
# *通过摄像头采集
# VideoCapture()
# cap.read()
# cap.release()
'''
# 创建屏幕
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
# 获取视频设备
cap = cv2.VideoCapture(0)
while True:
ret,frame = cap.read()
cv2.imshow('new',frame)
if cv2.waitKey(5) & 0xff==ord('Q'):
break
cap.release()
cv2.destroyAllWindows()
'''
# *从多媒体读取视频帧
# VideoCapture("输入文件路径")
# cap.read()
# cap.release()
# *视频录制
# VideoWriter(name,格式Fourcc,帧率,分辨率)
# write()
# release()
'''
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
vw = cv2.VideoWriter('./123.mp4',fourcc,25,(1280,720)) # !分辨率需要和摄像头分辨率相同
# 创建屏幕
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
# 申请摄像头
cap = cv2.VideoCapture(0)
if cap.isOpened() : #判断是否打开摄像头
while True:
ret,frame = cap.read()
cv2.imshow('new',frame)
vw.write(frame)
if cv2.waitKey(5) & 0xff==ord('Q'):
break
cap.release()
vw.release()
cv2.destroyAllWindows()
'''
# *鼠标控制
# 鼠标设置回调函数setMouseCallback(windowname,callback,userdate)
# callback(event,x,y,flags,userdate) event --鼠标移动,按下... ||flags --组合键
'''
def mousecallback(event,x,y,flags,userdate):
print(event,x,y,flags,userdate)
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
cv2.setMouseCallback('new',mousecallback,"123")
img = np.zeros((360,640,3),np.uint8)
while True:
cv2.imshow('new',img)
if cv2.waitKey(5) & 0xff==ord('Q'):
break
cv2.destroyAllWindows()
'''
# *Trackbar控件
# createTrackbar(Trackbarname,winname,value:当前值,count:最大值,callback,userdate)
# getTrackBarPos(trackbarname,winname) return 当前值
'''
def callback():
pass
#创建窗口
cv2.namedWindow('trackbar',cv2.WINDOW_NORMAL)
# 创建trackbar
cv2.createTrackbar('R','trackbar',0,255,callback)
cv2.createTrackbar('G','trackbar',0,255,callback)
cv2.createTrackbar('B','trackbar',0,255,callback)
img = np.zeros((480,640,3),np.uint8)
while True:
cv2.imshow('trackbar',img)
R = cv2.getTrackbarPos('R','trackbar')
G = cv2.getTrackbarPos('G','trackbar')
B = cv2.getTrackbarPos('B','trackbar')
img[:] = [B,G,R]
if cv2.waitKey(5) & 0xff==ord('Q'):
break
cv2.destroyAllWindows()
'''
# *OPENCV
# opencv --BGR
# HSV色相 饱和度 / HSB / HSL
# YUV 视频
# ?HSV :
# Hue -色相,即色彩
# Saturation -饱和度,颜色的纯度
# Value -明度
# ?YUV:
# Y 灰色图像
# UV 颜色
# YUV 4:2:0 4:2:2 4:4:4
'''
def callback():
pass
cv2.namedWindow('color',cv2.WINDOW_NORMAL)
img = cv2.imread('./123.png')
# cv2.imshow('color',img)
# 颜色空间转化数组
colorspaces = [cv2.COLOR_BGR2RGBA,
cv2.COLOR_BGR2GRAY,cv2.COLOR_BGR2HSV_FULL,
cv2.COLOR_BGR2YUV]
cv2.createTrackbar('trackcolor','color',0,len(colorspaces),callback)
while True:
index = cv2.getTrackbarPos('trackcolor','color')
# 颜色空间转换api
img_cv = cv2.cvtColor(img,colorspaces[index])
cv2.imshow('color',img_cv)
if cv2.waitKey(5) & 0xff==ord('Q'):
break
cv2.destroyAllWindows()
'''
# *Numpy
# Opencv用到的矩阵都要转换成Numpy数组
# 创建矩阵:
# --array() 创建数组
# --zeros()/ones 创建全0数组/全1
# --full() 创建全值数组
# --identity/eye() 创建单元数组
# 检索与赋值[y,x]
# 获得子数组[:,:]
# ! 创建数组
# # 创建数组array()
# a = np.array([1,2,3])
# b = np.array([[1,2],[3,4]])
# # 创建数组zeros()
# c = np.zeros((480,640,3),np.uint8) #((行的个数,列的个数,通道数/层数),矩阵每一个元素的元素类型)
# # 创建数组ones()
# d = np.ones((8,8,3),np.uint8)
# # 创建数组full()
# e = np.full((8,8,3),255,np.uint8) #((行的个数,列的个数,通道数/层数),每个元素的值,矩阵每一个元素的元素类型)
# # 创建数组identity()
# f = np.identity(3)
# ! 数组的检索与赋值
# [y,x,channel] y在前 从0开始 channel 为二维矩阵的层数
'''
cv2.namedWindow('imgshow',cv2.WINDOW_NORMAL)
img = np.zeros((480,640,3),np.uint8)
# 向矩阵中某个元素赋值
counter = 0
while counter <200:
img[counter,100,0] = 255
img[counter,200,1] = 255
img[counter,300,2] = 255
counter +=1
cv2.imshow('imgshow',img)
if cv2.waitKey(0)&0xff ==ord('Q'):
cv2.destroyAllWindows()
'''
# !获取子矩阵 (ROI) [y1:y2,x1,x2] [:,:]
'''cv2.namedWindow('imgshow',cv2.WINDOW_NORMAL)
img = np.zeros((480,640,3),np.uint8)
sub = img[100:200,100:200]
sub[:,:] = [0,0,255]
cv2.imshow('imgshow',img)
if cv2.waitKey(0)&0xff ==ord('Q'):
cv2.destroyAllWindows()
'''
# *opencv 的重要结构体Mat
# dims -维度 rows.cols -行列数 *data -存放数据的指针 *refcount 引用记数
#Mat 的深拷贝和浅拷贝
# 默认浅拷贝,共用一块内存
# 深拷贝 copy()
'''
img = cv2.imread('./123.png')
img2= img #浅拷贝
img3 = img.copy() #深拷贝
img[10:100,10:100] = [0,0,255]
cv2.imshow('img',img)
cv2.imshow('img2',img2)
cv2.imshow('img3',img3)
cv2.waitKey(0)
'''
# *访问Mat图像的属性
'''
img = cv2.imread('./123.png')
print(img.shape) # (986, 1000, 3)(高度,宽度,通道数)
print(img.size) # 2958000 高度*长度*通道数
print(img.dtype) # uint8 0-255每个元素的位深
'''
# *通道的分离与合并
# split(mat)
# merge((ch1,ch2,ch3...))
'''
img = np.zeros((480,640,3),np.uint8)
b,g,r=cv2.split(img)
b[10:100,10:100] =255
g[10:100,10:100] =255
img2 = cv2.merge((b,g,r))
cv2.imshow('B',b)
cv2.imshow('g',g)
cv2.imshow('img',img)
cv2.imshow('img2',img2)
cv2.waitKey(0)
'''
# *opencv 绘制图型
# !画直线
'''
img = np.zeros((480,640,3),np.uint8)
#line(img,起点,终点,颜色,线宽,线形(越大越平滑-1,4,8,16))
cv2.line(img,(10,20),(300,400),(0,0,255),5,16) #!(x,y) x在前
cv2.imshow('img',img)
cv2.waitKey(0)
'''
# !画椭圆
'''
# ellipse(img,中心点,长宽的一半,角度,从哪个角度开始,从哪个角度结束...)
cv2.ellipse(img ,(320,240),(100,50),0,0,360,(0,255,0),3,16)
'''
# *案例
'''
img = np.zeros((480,640,3),np.uint8)
cv2.namedWindow('mouse',cv2.WINDOW_AUTOSIZE)
def mousecallback(event,x,y,flags,userdate):
print(event,x,y,flags,userdate)
if flags == 1:
img[y,x] = 255
cv2.setMouseCallback('mouse',mousecallback,"123")
while True:
cv2.imshow('mouse',img)
if cv2.waitKey(1) & 0xff==ord('Q'):
break
cv2.destroyAllWindows()
'''
# *图像的加法运算
'''
kunkun = cv2.imread('./123.png')
#图的加法运算就是矩阵的加法运算
print(kunkun.shape)
img = np.ones((986,1000,3),np.uint8) * 20
kunkun2 = cv2.add(kunkun,img)
cv2.imshow('img',kunkun2)
cv2.waitKey(0)
'''
# *图像的减法运算
# cat = cv2.imread('./smallcat1.jpg')
# back = cv2.imread('./back.jpg')
# print(cat)
# print(back)
#图的加法运算就是矩阵的加法运算
# print(kunkun.shape)
# img = np.ones((986,1000,3),np.uint8) * 150
# kunkun2 = cv2.add(kunkun,img) #加更亮
# cv2.imshow('img',kunkun2)
# kunkun3 = cv2.subtract(kunkun,img) #减更暗
# cv2.imshow('img2',kunkun3)
# kunkun4 = cv2.multiply(kunkun,2) #乘法
# kunkun5 = cv2.divide(kunkun,2) #除法
#图像的融合 addWeighted(A,alpha,B,bate,gamma) alapha 和 bate是占比权重 gamma 静态权
# img1=cv2.addWeighted(cat,0.2,back,0.8,0)
# cv2.imshow('img2',img1)
# cv2.waitKey(0)
# *图像的滤波
# !滤波器 -卷积核,滤波叫卷积
# 卷积核的大小
# 3*3 5*5 7*7 卷积核越大,感受野越多,提取特征越好,同时计算量越大
# 卷积的锚点
# 正中心
# 边界扩充
# 如何卷积核大于1 且不进行边界扩充,则输出的图片尺寸减小
# 如果进行扩充,则相等
# N = ( W - F + 2P )/ S + 1
# 输出图像 = 原图大小 卷积核大小 扩充尺寸 步长大小
# filter2D(src(哪一个图像), ddepth(滤波后的位深/-1), kernel(卷积核), anchor(锚点/默认-1), dalta(每次卷积后加的值/ 默认0), borderTypr(边界的类型))
# !低通滤波与高通滤波
# 低通滤波可以去除噪声或平滑图像
# 高通滤波可以查找图像边缘
'''
kernel_5 = np.ones((5,5),np.float32) /25
cat = cv2.imread('./123.png')
dit = cv2.filter2D(cat, -1, kernel_5)
cv2.imshow('cat',cat)
cv2.imshow('dst',dit)
cv2.waitKey(0)
'''
# !方盒滤波与均值滤波
# 方盒滤波 boxFilter(src(哪一个图像), ddepth(滤波后的位深/-1), ksize(卷积核大小), anchor(锚点/默认-1), normalize(), borderTypr(边界的类型))
# normalize = true a = 1/W * H 均值滤波
# = False a = 1
# blur(src, ksize, anchor, borderType)
'''
cat = cv2.imread('./123.png')
dit = cv2.blur(cat,(5,5))
cv2.imshow('cat',cat)
cv2.imshow('dst',dit)
cv2.waitKey(0)
'''
# *高斯滤波
# GaussianBlur(img, kerel, sigmaX, sigmaY, ...)
'''
cat = cv2.imread('./gaussian.png')
dit = cv2.GaussianBlur(cat,(5,5),sigmaX=5)
cv2.imshow('cat',cat)
cv2.imshow('dst',dit)
cv2.waitKey(0)
'''
# *形态学
# 1.基于图像形态进行处理的一些基本方法
# 2.基于二进制的图像进行处理
# 3.卷积核决定图像处理后的效果
# ?腐蚀与膨胀(缩小和放大)
# 开运算
# 闭运算
# 顶帽
# 黑帽
'''
cv2.namedWindow('math',cv2.WINDOW_NORMAL)
cv2.namedWindow('math2',cv2.WINDOW_NORMAL)
kunkun = cv2.imread('./math.png')
# 转为灰度图
kunkun2 = cv2.cvtColor(kunkun,cv2.COLOR_BGR2GRAY)
# !二值化
# ret,dst = cv2.threshold(kunkun2, 180, 255, cv2.THRESH_BINARY)
#Type THRESH_BINARY_INV // THRESH_BINARY
# 自适应阈值二值化 adaptiveThreshold(img,maxVal,adaptiveMethod,type,blockSize,C)
# adaptiveMethod 计算邻进区域的平均值 // 高斯窗口加权平均值
# Type THRESH_BINARY_INV // THRESH_BINARY
dst = cv2.adaptiveThreshold(kunkun2,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,0)
cv2.imshow('math',kunkun2)
cv2.imshow('math2',dst)
cv2.waitKey(0)
'''
# !腐蚀
# erode(img,kernel,iterations) iterations执行的次数
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./j.png')
kernel_3 = np.ones((5,5),np.uint8)
j2 = cv2.erode(j,kernel_3,iterations= 1)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# 获得卷积核
# getStructuringElement(type,size)
# type -- MORPH_RECT(矩形,全1) -- MORPH_ELLIPSE(椭圆) --MORPH_CROSS(十字架)
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./j.png')
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
j2 = cv2.erode(j,kernel,iterations= 1)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# !膨胀
# dilate(img, kernel, iterations=1)
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./j.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
j2 = cv2.erode(j,kernel,iterations= 1)
j2= cv2.dilate(j2,kernel,iterations= 1)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
#! 开运算
# MORPH_OPEN先腐蚀->再膨胀 = 开运算
# 消除黑底白色噪点
# morphologyEx(img, MORPH_OPEN, kernel)
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./hei.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(18,18))
j2 = cv2.morphologyEx(j,cv2.MORPH_OPEN,kernel)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# !闭运算
# MORPH_OPEN膨胀 -> 腐蚀
# 白底黑色噪点
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./dotinj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(8,8))
j2 = cv2.morphologyEx(j,cv2.MORPH_CLOSE,kernel)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# !形态学梯度
# 梯度 MORPH_GRADIENT= 原图 - 腐蚀
# 显示轮廓
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./J.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
j2 = cv2.morphologyEx(j,cv2.MORPH_GRADIENT,kernel)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# !顶帽运算
# 顶帽 (黑底白色噪点)= 原图 - 开运算
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./hei.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(19,19))
j2 = cv2.morphologyEx(j,cv2.MORPH_TOPHAT,kernel)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# !黑帽运算
# 黑帽(白底黑色噪点) = 原图 - 闭运算
'''
cv2.namedWindow('j',cv2.WINDOW_NORMAL)
cv2.namedWindow('j2',cv2.WINDOW_NORMAL)
j = cv2.imread('./dotinj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(9,9))
j2 = cv2.morphologyEx(j,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow('j',j)
cv2.imshow('j2',j2)
cv2.waitKey(0)
'''
# *图像轮廓
# 具有相同颜色或强度的连续点的曲线
# 1.先对图像进行二值化,再进行Canny操作
# 2.画轮廓时会修改输入的图像
# 轮廓查找api
# findContours(img,
# mode, RETR_EXTERNAL = 0 -只检测外围轮廓 RETR_LIST = 1 -检测的轮廓不建立等级关系 RETR_CCOMP = 2 -每层最多两级 RETR_TREE -按树型存储轮廓
# ApproximationMode CHAIN_APPROX_NONE -保存所有轮廓上的点 CHAIN_APPROX_SIMPLE -只保存角点
# ) return contours(查找到的所有轮廓) hierarchy(轮廓之间有没有层级关系)
'''
def drawShape(src, points):
i = 0
while i <len(points):
if(i == len(points)-1) :
x,y = points[i][0]
x1,y1 = points[0][0]
cv2.line(src,(x,y),(x1,y1),(0,255,0),1)
else :
x,y = points[i][0]
x1,y1 = points[i+1][0]
cv2.line(src,(x,y),(x1,y1),(0,255,0),1)
i+=1
# 读文件
cv2.namedWindow('new',cv2.WINDOW_GUI_NORMAL)
img = cv2.imread('./123.png')
# 转为灰度图
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 二值化
ret,dst = cv2.threshold(img2,120,255,cv2.THRESH_BINARY)
# ret,dst = cv2.threshold(kunkun2, 180, 255, cv2.THRESH_BINARY)
#Type THRESH_BINARY_INV // THRESH_BINARY
# !轮廓查找
con,hie = cv2.findContours(dst,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# !轮廓绘制
# drawContours(img, contours, ---- 轮廓坐标点
# contourIdx, ---- 顺序 -1表示所有轮廓
# color, ---- 轮廓的颜色
# thickness ...) ----线宽
cv2.drawContours(img,con,-1,(0,255,0),2)
# !计算轮廓的面积和周长
# contourArea(contour)面积
# contour :轮廓
# arcLength(curve 轮廓, closed 是否闭合)周长
area = cv2.contourArea(con[1])
print()
#! 多边形逼近与凸包
# 逼近approxPolyDP(curve 轮廓, epsilon 精度, closed 是否闭合)
#cv2.approxPolyDP()
# 凸包convexHull(points 轮廓, clockwise True顺时针 逆时针)
# point = cv2.approxPolyDP(con[0],10,closed= True)
# 外界矩形 最小外接矩形 最大外界矩形
# minAreaRect(points 轮廓) return 中点坐标(x,y) width,height angle 最小外接矩形
# maxAreaRect(array /points) 返回 Rect --x,y width,height
#drawShape(img,point)
# print()
cv2.imshow('new',img)
cv2.waitKey(0)
'''
#//////////////////////*车辆统计
'''
import cv2
import numpy as np
# 窗口的展示
# 基本图像的运算与处理
# -背景的去除cv2.createBackgroundSubtractorMOG() history =200
#
# 形态学 --腐蚀,膨胀,开操作,闭操作,顶帽,黑帽
# 轮廓查找
#*流程
# 加载视频
# 通过形态学识别车辆
# 轮廓查找
# 统计
#*创建窗口
cv2.namedWindow('new',cv2.WINDOW_NORMAL)
bgsumog = cv2.createBackgroundSubtractorMOG2(history= 500)
#a = cv2.createBackgroundSubtractorKNN(history= 200)
#* 加载视频
cap = cv2.VideoCapture('./video.mp4')
def center(x,y,w,h):
x1 = int(x + w/2)
y1 = int(y + h/2)
return (x1,y1)
#*获得卷积核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #获得卷积核
kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) #获得卷积核
while True:
ret,frame =cap.read()
if ret == True:
#*灰度化
frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#*高斯去噪
frame_blur = cv2.GaussianBlur(frame_gray,(5,5),sigmaX=5)
#*去背景
frame_mask = bgsumog.apply(frame_blur)
#*二值化
ret,frame_mask = cv2.threshold(frame_mask, 150, 255, cv2.THRESH_BINARY)
#*腐蚀
frame_erode = cv2.erode(frame_mask,kernel,iterations=2)
#*膨胀
frame_dilate = cv2.dilate(frame_erode,kernel,iterations=3)
#*闭操作
frame_closeAction = cv2.morphologyEx(frame_dilate, cv2.MORPH_OPEN, kernel)
frame_closeAction = cv2.morphologyEx(frame_closeAction, cv2.MORPH_OPEN, kernel)
#frame_closeAction = cv2.morphologyEx(frame_closeAction, cv2.MORPH_OPEN, kernel)
frame_erode_2 = cv2.erode(frame_closeAction,kernel)
# frame_dilate_2 = cv2.dilate(frame_erode_2,kernel)
# frame_closeAction_2 = cv2.morphologyEx(frame_erode_2, cv2.MORPH_OPEN, kernel2)
#* 查找轮廓
frame_con,hie = cv2.findContours(frame_closeAction,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for(i,c) in enumerate(frame_con):
(x,y,w,h)= cv2.boundingRect(c)
if (w>=50 and h>=80):
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
#*算中心点
cy = center(x,y,w,h)
cv2.circle(frame,cy,5,(0,255,0),-1)
cv2.imshow('new',frame)
if cv2.waitKey(50) & 0xff==27:
break
cap.release()
cv2.destroyAllWindows()
'''
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
羽老板的心事!
喜欢就支持一下吧