赞
踩
本文全篇算是个学习笔记,学习油管主视频所编辑
1.opencv 下载
直接在terminal输入 pip install opencv-python 即可,需要注意的是,如果开着翻墙工具的话,是会显示错误的,解决方法很简单,关掉翻墙工具即可。
2.opencv的基本使用
(1)图片类
import opencv #导入opencv包
img = cv2.imread('图片文件路径名') #创建变量接受图片,另外如果将图片文件与py文件放在同一个文件夹的话就可以不用输入全部路径名,像这样,记得写后缀名
cv2.imshow('命名该文件', 图片变量) #显示该图片并以‘’中的名字命名
cv2.waitKey(此处填入毫秒数) #可以维持窗口,若填入0,则不关闭。waitkey的意思是:等待键盘指令并回传该指令
cv2.resize(img,(x,y ) )#一种改变图片尺寸的方式,x,y填入想要的像素,img为前面所创的图片变量
cv2.resize(img,(0,0),fx=i,fy=j)#这是直接按照原来的尺寸让x与y乘以i和j
(2)录像类
video = cv2.VideoCapture(‘文件路径’)#同上
video = cv2.VideoCapture(0)#读取笔记本自带的镜头,若为1则是外接摄像头
ret,frame = video.read()#read函数是用来读取影片的每一帧的,使用一次读取一帧,ret是判断是否读取成功,frame则是该帧的变量,是一个图片
if ret :
cv2.imshow('命名该文件', 影片变量)#同上
#读取该影片每一帧,类似于播放影片
while True:
if ret:
cv2.imshow('命名该文件', 影片变量)
else:
break #影片读取帧失败的原因有二:一是播放完毕,而是影片损坏
cv2.waitKey(1) #此处可以填任意数,可以决定影片播放的快慢,单位是毫秒
#设置影片的尺寸
frame = cv2 .resize(frame,(0,0),fx = 0.4, fy = 0.5) #基本同上
3.numpy与图片的关系
前文中,存图片的变量img的数据类型是numpy.ndarray(阵列)。其中na指多维,整体用[]表示。
我的理解是:图片具有长与宽,颜色的信息,所以是三维阵列,第一维存储的是图片的宽的像素,第一维度的数量表示了宽度。第二维度指的是长度,跟宽度类似。第三维度指的是三原色R,G,B,但是比较特别的是在opencv中,表示颜色的顺序不是R,G,B,而是B,G,R
#创建自己的图片
np.empty( , ) #可以创建一个多维的阵列,第一个变量需要表示阵列的维度以及各个维度的大小;第二个参数则需要填入值的大小,跟数组差不多吧。
对于图片来说,可以有
np.empty((300, 300, 3),np.uint8)
表示该图片有长与宽都是300像素,并且每个像素的三原色取值范围都是0,255(2^8)。
若要形成图片则还需要使用多重循环给每个像素赋三原色的值
4.裁剪图片
很简单,直接 img[x1:x2,y1:y2],需要注意的是,照片的x,y轴是从左上角开始的,x1与y1可以是0也可以不填,不填默认是0
5.常用函数:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #转为灰度图 blur = cv2.GaussianBlur(img, (3, 3), 0) #高斯模糊 canny = cv2.Canny(img, 150, 200) #边缘化 kernal = np.ones((3, 3), np.uint8) #阵列 dilate = cv2.dilate(canny, kernal, 2 ) #膨胀边缘 第一个参数是需要膨胀边缘的图片,二维阵列(核),膨胀n次 erode = cv2.erode(dilate, kernal, iterations = 2) cv2.imshow('img2', gray) cv2.imshow('img', img) cv2.imshow('blur', blur) cv2.imshow('canny', canny) cv2.imshow('dilate', dilate) cv2.imshow('erode', erode) cv2.waitKey(0)
6.在图像上画画
img = np.zeros((600, 600, 3), np.uint8) #使用zeros可以直接设定底色为黑色 cv2.line(img, (0, 0), (img.shape[1], img.shape[0]), (255, 0, 0), 1)#除了img,从左到右的参数,依次是:左上角坐标,右下角坐标(可以写任意不超过设置图像的参数,此处意味从左上到右下),颜色,粗度 cv2.rectangle(img, (0, 0), (300, 400), (0,255,0),cv2.FILLED)#除了img,从左到右依次是,坐上角坐标,右下角坐标,颜色,粗度(此处的意思是填满整个矩形,如果填任意实数则代表粗度) cv2.circle(img, (400, 300), 40, (0, 0, 255),2)#从左到右除了img,圆心,半径,颜色,粗度(也可以如上面矩形画一个实心圆) cv2.putText(img, 'Hello', (100, 500), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2)#……文本内容(putText函数不支持写入中文),第一个字母的左上角坐标,字体,大小,颜色,粗度 cv2.imshow('img', img) cv2.waitKey()
7.过滤颜色
def empty(v): pass img = cv2.imread('media.jpg') img = cv2.resize(img, (0, 0), fx=0.5,fy=0.5) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #HSV与RGB一样,都是表达颜色的方式,但是HSV是利用H(HUE 色调)S(Saturation 饱和度)和V(Value 亮度)来决定颜色的 #相较于RGB来说,HSV更容易过滤掉颜色 cv2.namedWindow('TrackBar') #创建一个新的窗口 cv2.resizeWindow('TrackBar',640 ,320) #创建控制条 cv2.createTrackbar('Hue Min', 'TrackBar', 0, 179, empty)#第一个参数填写控制条名称,第二个参数填写显示控制条的窗口,第三个参数是控制条的最低值,第三则是最大,第五则是回调函数,每次滑动都会调用回调函数 cv2.createTrackbar('Hue Max', 'TrackBar', 179, 179, empty) cv2.createTrackbar('Sat Min', 'TrackBar', 0, 255, empty) cv2.createTrackbar('Sat Max', 'TrackBar', 255, 255, empty) cv2.createTrackbar('Val Min', 'TrackBar', 0, 255, empty) cv2.createTrackbar('Val Max', 'TrackBar', 255, 255, empty) while True: h_min = cv2.getTrackbarPos('Hue Min', 'TrackBar') #将控制条的参数传回 h_max = cv2.getTrackbarPos('Hue Max', 'TrackBar') s_min = cv2.getTrackbarPos('Sat Min', 'TrackBar') s_max = cv2.getTrackbarPos('Sat Max', 'TrackBar') v_min = cv2.getTrackbarPos('Val Min', 'TrackBar') v_max = cv2.getTrackbarPos('Val Max', 'TrackBar') print(h_min, h_max, s_min, s_max, v_min, v_max) lower = np.array([h_min, s_min, v_min]) #将参数的 upper = np.array([h_max, s_max, v_max]) mask = cv2.inRange(hsv, lower, upper) #cv2.inrange函数用于过滤图片 第一个参数是过滤的图片,第二个是最小,第三是最大。这里的最大最小指的是色调,饱和度,亮度,所以用numpy的array类存储 result = cv2.bitwise_and(img, img, mask = mask) #bitwise_and函数是在字节上坐and(+)运算,其实我也弄得不是很清楚,建议搜一下 cv2.waitKey(1) cv2.imshow('hsv', hsv) cv2.imshow('img', img) cv2.imshow('mask', mask) cv2.imshow('result', mask)
(试图只保留头发,眼睛额,懒得调了)
8.找出图片轮廓
img = cv2.imread('picture1.jpeg') imgContour = img.copy() img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #检测轮廓不需要用到颜色 canny = cv2.Canny(img, 150, 200) #检测图片的边缘 contours, hierarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) #检测轮廓 第一个参数是待检测图像,第二个参数是设定要检测内或外轮廓或内外轮廓都要, #di一个值为轮廓,第二个值为阶层(这里用不到) #第三个为近似方法(压缩轮廓点,这里不压缩) for cnt in contours: cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 5) #第一个参数是需要画轮廓的图,第二个参数是轮廓,第三个参数是要画几个轮廓(这里-1表示全画),第四个参数是颜色,第五个是粗度 print(cv2.contourArea(cnt)) #计算图形面积 print(cv2.arcLength(cnt, True)) #输出轮廓点,第二个参数的意思是是否闭合
peri = cv2.arcLength(cnt, True) vertices = cv2.approxPolyDP(cnt, peri * 0.02, True)#第一个参数 近似轮廓,第二个参数 近似值,近似值越大边越多(可以自己调整),第三个参数 是否闭合 print(len(vertices)) #打印出顶点的个数 x , y , w , h= cv2.boundingRect(vertices) #返回值是边界值顶点的x,y坐标和整个轮廓的宽和长 cv2.rectangle(imgContour, (x, y), (x + w, y + h), (0, 255, 0), 4) #设置框住图形的方形框 if len(vertices) == 3: cv2.putText(imgContour, 'Triangle', (x, y-5),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) if len(vertices) == 4: cv2.putText(imgContour, 'Rectangle', (x, y-5),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) if len(vertices) == 5: cv2.putText(imgContour, 'Pentagon', (x, y-5),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) if len(vertices) >= 5: cv2.putText(imgContour, 'GG', (x, y-5),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) cv2.imshow('img', img) cv2.imshow('canny', canny) cv2.imshow('imgContour', imgContour) cv2.waitKey(0)
由于素材找的不是很好,所以呈现出来就比较糟糕
9.人脸识别
#人脸识别 #此处需要在opencv.github处搜索模型并在pycharm中创建模型文件复制粘贴代码。 选择data 这里用的是这个,还有很多模型可以下载,眼睛识别啊,身体识别啊什么的 这些全部复制到剪贴板 再新建文件 全部复制粘贴即可 img = cv2.imread('face.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #人脸识别不用彩图,所以这里采用灰度图 faceCasecade = cv2.CascadeClassifier('face_detect.xml') #载入模型 faceRect = faceCasecade.detectMultiScale(gray, 1.1, 15) #用这个函数辨识人脸。第一个参数是待辨识的图片,第二个参数是每次图片缩小的倍数,第三个参数是相邻的方框的个数 #辨识人脸的原理:该函数生成一个方框,从图片的左上角开始遍历,从左到右,一行一行扫过,如果第一遍没有扫到人脸,则将原图缩小n倍(第二个参数) #扫到了则函数内部计数器+1,但是不会停止遍历,依旧遍历完整张图行再缩小,直到缩小的图形会小于方框为止,或者计数器会等于第三个参数 #即第三个参数的意思是人脸被扫描的次数,大于这个数的图像将会被框出来 #第三个参数越大则越严谨,越小精度就比较低,第二三个参数需要根据实际情况调整,传回的值是人脸的方框 print(len(faceRect)) for (x,y,w,h) in faceRect: cv2.rectangle(img, (x,y), (x+w,h+y), (0, 255, 0), 4) cv2.imshow('face', img) cv2.waitKey(0)q
效果如图,那两个参数得多调调,调到合适为止
9制作电子笔,直接上代码
import cv2 import numpy as np cap = cv2.VideoCapture(0) penColorHSV = [[100, 164, 105, 120, 214, 255], [53, 78, 53, 82, 214, 255], [19, 134, 111, 47, 250, 252]]#蓝绿黄 penColorBGR = [[255, 0, 0], [0, 255, 0], [0, 255, 255]] #x y ColorId drawPoints = [] def findpen(img): hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) for i in range(len(penColorHSV)): lower = np.array(penColorHSV[i][:3]) #橘色 upper = np.array(penColorHSV[i][3:6]) mask = cv2.inRange(hsv, lower, upper) result = cv2.bitwise_and(img, img, mask=mask) penx,peny = findContour(mask) cv2.circle(imgContour, (penx, peny), 5, penColorBGR[i], cv2.FILLED) if peny != -1 : drawPoints.append([penx, peny, i]) # cv2.imshow('result', result) def findContour(img): contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # 检测轮廓 第一个参数是待检测图像,第二个参数是设定要检测内或外轮廓或内外轮廓都要, # di一个值为轮廓,第二个值为阶层(这里用不到) #第三个为近似方法(压缩轮廓点,这里不压缩) x, y, w, h = -1, -1, -1, -1 for cnt in contours: cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 5) # 第一个参数是需要画轮廓的图,第二个参数是轮廓,第三个参数是要画几个轮廓(这里-1 # 表示全画),第四个参数是颜色,第五个是粗度 area = cv2.contourArea(cnt) if area > 500: peri = cv2.arcLength(cnt, True) vertices = cv2.approxPolyDP(cnt, peri * 0.02, True) # 第一个参数 近似轮廓,第二个参数 近似值,近似值越大边越多(可以自己调整),第三个参数 是否闭合 x, y, w, h = cv2.boundingRect(vertices) # 返回值是边界值顶点的x,y坐标和整个轮廓的宽和长 return x+w // 2, y def draw(drawPoints): for point in drawPoints: cv2.circle(imgContour, (point[0], point[1]), 10, penColorBGR[point[2]], cv2.FILLED) while True: ret,frame = cap.read() if ret: imgContour = frame.copy() cv2.imshow('cap', frame) findpen(frame) draw(drawPoints) cv2.imshow('Contour', imgContour) else: break if cv2.waitKey(1) == ord('q'): break
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。