Learning Opencv-in-3h
chapter1
图像的read和show,视频文件的读取,摄像头的调用
import cv2
# img = cv2.imread("Resources/lena.png")
#
# cv2.imshow('Output', img)
# cv2.waitKey(0)
# cap = cv2.VideoCapture("./Resources/test_video.mp4")
cap = cv2.VideoCapture(0)
cap.set(3, 640) # width id 3
cap.set(4, 480) # height id 4
cap.set(10, 150) # 亮度 id 10
while True:
ret, img = cap.read()
cv2.imshow("video", img)
# & 0xFF的按位与操作只取cv2.waitKey(1)返回值最后八位,
# 因为有些系统cv2.waitKey(1)的返回值不止八位 ord(‘q’)表示q的ASCII值
if cv2.waitKey(1) & 0xFF == ord('q'):
break
chapter2
简单入门体验
灰度图 高斯模糊 canny边缘检测 膨胀 腐蚀 操作
import cv2
import numpy as np
img = cv2.imread("Resources/lena.png")
kernel = np.ones((5,5), dtype=np.uint8)
# 灰度图
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊
imgBlur = cv2.GaussianBlur(imgGray, (7,7), 0) # kernal 必须为奇数3*3 5*5 7*7
# canny边缘检测
imgCanny = cv2.Canny(img, 150, 200)
# 膨胀
imgDialation = cv2.dilate(imgCanny, kernel, iterations=1) # 迭代次数决定了厚度
# 腐蚀
imgEroded = cv2.erode(imgDialation, kernel, iterations=1)
chapter3
图像的resize 和 crop
img = cv2.imread("Resources/lambo.PNG")
# print(img.shape)
imgResize = cv2.resize(img, (300,200))
# print(imgResize.shape)
imgCropped = img[0:200, 200:500]
chapter4
在图像上绘制形状 画线 矩形 圆 ,并且在图像上放置文本
# 画出直线
# cv2.line(img, (0,0), (480,480), (0,255,0), 3)
cv2.line(img, (0,0), (img.shape[1],img.shape[0]), (0,255,0), 3) # numpy先高后宽,cv2中先宽后高
# 画出矩形
cv2.rectangle(img, (0,0), (100,100), (0,0,255), 2)
# 画出圆形
cv2.circle(img, (400,50), 30, (255,0,0), 5)
# 放置文本
cv2.putText(img, "opencv", (300,200), cv2.FONT_HERSHEY_COMPLEX, 1.5, (0,150,0),1)
chapter5
空间变换,斜放图像的正面显示
import cv2
import numpy as np
# 空间变换
img = cv2.imread("Resources/cards.jpg")
width, height = 250, 350 # 纸牌比例是2.5:3.5
pts1 = np.float32([[111, 219], [287, 188], [154, 482], [352, 440]])
pts2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
matrix = cv2.getPerspectiveTransform(pts1,pts2) # 使用getPerspectiveTransform()得到转换矩阵
imgOutput = cv2.warpPerspective(img, matrix, (width, height)) #使用warpPerspective()进行透视变换
cv2.imshow("Img", img)
cv2.imshow("Output", imgOutput)
cv2.waitKey(0)
chapter6
图片的堆叠,合并
# 这样不能改变图片大小,也不能将通道数不同的img合并
# imgHor = np.hstack((img, img)) # 水平合并
# imgVer = np.vstack((img, img)) # 竖直合并
其中的stackImages(scale, imgArray)函数
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
# & 输出一个 rows * cols 的矩阵(imgArray)
print(rows,cols)
# & 判断imgArray[0] 是不是一个list
rowsAvailable = isinstance(imgArray[0], list)
# & imgArray[][] 是什么意思呢?
# & imgArray[0][0]就是指[0,0]的那个图片(我们把图片集分为二维矩阵,第一行、第一列的那个就是第一个图片)
# & 而shape[1]就是width,shape[0]是height,shape[2]是
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
# & 例如,我们可以展示一下是什么含义
# cv2.imshow("img", imgArray[0][1])
if rowsAvailable:
for x in range (0, rows):
for y in range(0, cols):
# & 判断图像与后面那个图像的形状是否一致,若一致则进行等比例放缩;否则,先resize为一致,后进行放缩
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
# & 如果是灰度图,则变成RGB图像(为了弄成一样的图像)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
# & 设置零矩阵
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
# & 如果不是一组照片,则仅仅进行放缩 or 灰度转化为RGB
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
chapter7
# 颜色检测
# 使用mask得到lambo.png中橙色部分,利用trackbar获取显示橙色部分时hsv值,
# 使用mask与原图按位与操作获得橙色部分
TrackBars的使用方法:
cv2.namedWindow("TrackBars") # 新建一个窗口
cv2.resizeWindow("TrackBars", 640, 240) # resize窗口大小
cv2.createTrackbar("Hue Min", "TrackBars", 0, 179, empty) # empty 给程序一个调用函数
cv2.createTrackbar("Hue Max", "TrackBars", 43, 179, empty) # TrackBars的名字, 窗口名字, 初始值, 可调动的数量,一个调用函数 可以为一个空函数
cv2.createTrackbar("Sat Min", "TrackBars", 84, 255, empty)
cv2.createTrackbar("Sat Max", "TrackBars", 255, 255, empty)
cv2.createTrackbar("Val Min", "TrackBars", 93, 255, empty)
cv2.createTrackbar("Val Max", "TrackBars", 255, 255, empty)
# 获取滑动条的数值
h_min = cv2.getTrackbarPos("Hue Min", "TrackBars")
h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
chapter8
# 检测出物体轮廓,并将其分类,
# 使用gray灰度图,高斯模糊,canny边缘检测,获得contour, 拐角点,按角点分类
用一个最小的多边形包围物体
cv2.approxPolyDP() 的参数1是源图像的某个轮廓;参数2(epsilon)是一个距离值,表示多边形的轮廓接近实际轮廓的程度,值越小,越精确;参数3表示是否闭合。
chapter9
检测面部,使用viola and jones提出的,最早的实时对象检测方法之一
opencv自带的检测人脸的联级文件cascade