@TOC
准备工作
python配置numpy和openCv库
读取图像和视频
- 图像
- cv2.imread(路径)
- cv2.imshow(窗口名称,输出对象)
- cv2.waitkey(等待时间)
import cv2
img = cv2.imread("./Resources/3-1P316104441.jpg")//当前项目目录下
cv2.imshow("output", img)
cv2.waitKey(0)
- 视频
- cv2.VideoCapture(路径或数字)
- set()
(1) set(3,数字)设置显示区域宽
(2) set(4,数字)设置显示区域高
(3) set(10,数字)设置亮度
- read()
- cv2.imshow
import cv2
cap = cv2.VideoCapture("./Resources/Ninja Track.mp4")
while True:
#success是bool值,用于判断是否读取成功
success, img = cap.read()
cv2.imshow("video", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
基础功能
- 图像
- cv2.cvtColor(对象,cv2.COLOR_BGR2GRAY) 转换为灰度图像
- cv2.GaussianBlur(对象,(奇数,奇数),0)设置模糊,值越大,模糊程度越大
- cv2.Canny(对象,数字,数字)设置Canny边缘检测器,数字越大,显示的越少
- cv2.dilate(边缘对象,矩阵,iteration=数字) 图像膨胀,即:增加图像边缘厚度
- cv2.erode(对象,矩阵而过,iteration=数字)图像腐蚀,即:减少图像边缘厚度
裁剪图像
- 改变图像大小
- 对象.shape用于显示图片大小
print(img.shape)#先显示高度,再显示宽度
- cv2.resize(对象,(宽度,高度))改变图片大小
imgResize = cv2.resize(img, (200,300))#先定义宽度,在定义高度
- 裁剪图像
对象[数字:数字,数字:数字]先高度后宽度
imgCropped = img[0:100,200:300]#先高度后宽度
绘制图形和文本
- 创建简单图像
numpy.zeros((512,512)) 建立矩阵,0表示黑色
- 为图像添加颜色通道
numpy.zeros((数字,数字,3),numpy.unint8)添加颜色三个颜色通道,颜色值为0~255
- 为图像上色
对象[数字:数字,数字:数字]=rgb值
img[200:300,:]=255,0,0
- 绘制线条
cv2.line(对象,(起点坐标),(终点坐标),(rgb颜色值),厚度)
cv2.line(img,(0,0),(300,300),(0,255,0),3)
- 绘制矩形
cv2.rectangle(对象,(起点坐标),(终点坐标),(rgb颜色值),厚度)
cv2.rectangle(img,(0,0),(100,100),(0,0,255),3)
cv2.rectangle(img,(0,0),(100,100),(0,0,255),cv2.FILLED)填充图形
- 绘制圆
cv2.circle(对象,(圆心坐标),半径,(rgb颜色值),厚度)
cv2.circle(img,(100,100),30,(255,255,0),2)
- 显示文字
cv2.putText(对象,“文本内容",(起始坐标),字体样式,缩放比例,(rgb颜色值),厚度)
cv2.putText(img,"good",(200,200),cv2.FONT_HERSHEY_COMPLEX,1,(0,150,0),1)
视角转换
- 设置待转换坐标
numpy.float32([[坐标1],[坐标2],[坐标3],[坐标4]])
pts1 = np.float32([[111,219],[287,188],[154,482],[352,440]])
- 设置转换后坐标
numpy,float32([[0,0],[width,0],[0,height],[width,height]])
- 透视图转换
cv2.getPrespectiveTransform(待转换坐标,转换后坐标)
- 转换后图像
cv2.warpPerspective(对象,透视图转换,(width,height))
img = cv2.imread("Resources/puke_zhipai-003.jpg")
width,height=250,250
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)#透视图转换,将世界坐标系变为屏幕坐标系
imgoutput = cv2.warpPerspective(img,matrix,(width,height))
cv2.imshow("card",imgoutput)
cv2.waitKey(0)
图像拼接
- 无法调整图像大小
- 水平拼接
numpy.hstack((对象,对象))
hor = np.hstack((img, img))
- 垂直拼接
numpy.vstack((img,img))
ver = np.vstack((img,img))
- 能够调整图像大小
- 编写stackImages函数
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
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)
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)
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
- stackImages(缩放比例,水平拼接,垂直拼接)
stackImages(0.5,([img,img,img]))
stackImages(0.5,([img,img,img],[img,img,img]))
颜色检测
- 转换为HSV空间
cv2.cvtColor(对象,cv2.COLOR_BGR2HSV)
- 设置颜色调节器
- 定义一个窗口
cv2.namedWindow("窗口名")
- 设置窗口大小
cv2.resizeWindow("对应窗口名",宽度,高度)
- 创建滑动控制器
def empty():
pass
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars", 640, 240)
cv2.createTrackbar("Hue Min", "TrackBars", 0, 179, empty)
cv2.createTrackbar("Hue Max", "TrackBars", 179, 179, empty)
cv2.createTrackbar("Sat Min", "TrackBars", 0, 255, empty)
cv2.createTrackbar("Sat Max", "TrackBars", 255, 255, empty)
cv2.createTrackbar("Val Min", "TrackBars", 0, 255, empty)
cv2.createTrackbar("Val Max", "TrackBars", 255, 255, empty)
- 将颜色调节器和HSV图像进行关联
- 获取控制器值
cv2.getTrackbarPos("控制器名","相应窗口名")
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")
- 设置过滤图像
(1)最低阀值
numpy.array([h_min, s_min, v_min])
lower = np.array([h_min, s_min, v_min])
(2)最高阀值
numpy.array([h_max, s_max, v_max])
upper = np.array([h_max, s_max, v_max])
(3)阀值限制图像
cv2.inRange(HSV图像对象,最低阀值,最高阀值)
mask = cv2.inRange(imgHSV, lower, upper)
- 获取检测颜色范围
- 将所有颜色调节器的最低值设置好
- 进行按位操作合成新图像
cv2.bitwise_and(原图像对象,原图像对象,mask=阀值限制图像)
imgResult = cv2.bitwise_and(img, img, mask=mask)
- 图像拼接显示
import cv2
import numpy as np
img = cv2.imread("Resources/3.png")
#图像拼接函数
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
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)
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)
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
#定义检测颜色的范围
#设置颜色调节器
def empty():
pass
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars", 640, 240)
cv2.createTrackbar("Hue Min", "TrackBars", 0, 179, empty)
cv2.createTrackbar("Hue Max", "TrackBars", 19, 179, empty)
cv2.createTrackbar("Sat Min", "TrackBars", 110, 255, empty)
cv2.createTrackbar("Sat Max", "TrackBars", 240, 255, empty)
cv2.createTrackbar("Val Min", "TrackBars", 153, 255, empty)
cv2.createTrackbar("Val Max", "TrackBars", 255, 255, empty)
#关联颜色调节器和HSV图片
while True:
#转换为HSV空间
imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
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")
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(imgHSV, lower, upper)
imgResult = cv2.bitwise_and(img, img, mask=mask)
# cv2.imshow("windows", img)
# cv2.imshow("imgHSV", imgHSV)
# cv2.imshow("imgMask", mask)
# cv2.imshow("imgResult", imgResult)
imgStack = stackImages(0.6, ([img, imgHSV], [mask, imgResult]))
cv2.imshow("Stacked", imgStack)
cv2.waitKey(1)
轮廓检测
- 转为灰度图像
cv2.cvtColor(对象,cv2.COLOR_BGR2GRAY)
- 对灰度图像进行模糊处理
cv2.GaussianBlur(灰度图像对象,(7,7),1)
- 边缘检测
cv2.Canny(模糊图像对象,50,50)
- 定义空白图像
numpy.zeros_link(对象)
- 定义轮廓处理函数
- 检索轮廓
cv2.findContours(对象,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
- 遍历轮廓
for cnt in contours
- 定位区域
cv2.contourArea(cnt)
- 检索最小区域
if area > 500
- 绘制轮廓区域
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
- 计算曲线长度
cv2.arcLength(cnt, True)
- 计算拐角点
cv2.approxPolyDP(cnt,0.02*peri,True)
- 创建对象点
objCor=len(approx)
- 获取边界框边界
cv2.boundingRect(approx)
- 将对象进行分类
if objCor == 3 : objectType = "Tri"
else: objectType="None"
- 绘制矩形边界框
cv2.rectangle(imgContour, (x, y), (x+w, y+h), (0, 255, 0), 3)
- 贴上分类标签
cv2.putText(imgContour, objectType, (x+(w//2)-10, y+(h//2)-10), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 0), 2)
#轮廓处理函数
def getContours(img):
#检索轮廓
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
#定位区域
area = cv2.contourArea(cnt)
print(area)
#检索最小区域
if area > 500:
# 绘制轮廓区域
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
#计算曲线长度
peri = cv2.arcLength(cnt, True)
#print(peri)
#计算拐角点
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
print(len(approx))
#创建对象角
objCor = len(approx)
#获取边界框边界
x, y, w, h = cv2.boundingRect(approx)
# 将对象进行分类
if objCor == 3 : objectType = "Tri"
elif objCor == 4:
aspRatio = w/float(h)
if aspRatio > 0.95 and aspRatio< 1.05: objectType = "Square"
else: objectType = "Rectangle"
elif objCor > 4: objectType = "Circles"
else: objectType="None"
#绘制矩形边界框
cv2.rectangle(imgContour, (x, y), (x+w, y+h), (0, 255, 0), 3)
cv2.putText(imgContour, objectType, (x+(w//2)-10, y+(h//2)-10), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 0), 2)
import cv2
import numpy as np
#图像拼接函数
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
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)
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)
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
#轮廓处理函数
def getContours(img):
#检索轮廓
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
#定位区域
area = cv2.contourArea(cnt)
print(area)
#检索最小区域
if area > 500:
# 绘制轮廓区域
cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)
#计算曲线长度
peri = cv2.arcLength(cnt, True)
#print(peri)
#计算拐角点
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
print(len(approx))
#创建对象角
objCor = len(approx)
#获取边界框边界
x, y, w, h = cv2.boundingRect(approx)
# 将对象进行分类
if objCor == 3 : objectType = "Tri"
elif objCor == 4:
aspRatio = w/float(h)
if aspRatio > 0.95 and aspRatio< 1.05: objectType = "Square"
else: objectType = "Rectangle"
elif objCor > 4: objectType = "Circles"
else: objectType="None"
#绘制矩形边界框
cv2.rectangle(imgContour, (x, y), (x+w, y+h), (0, 255, 0), 3)
cv2.putText(imgContour, objectType, (x+(w//2)-10, y+(h//2)-10), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 0), 2)
img = cv2.imread("Resources/3s.png")
imgContour = img.copy()
#转换为灰度图像
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#模糊图像
imgBlur = cv2.GaussianBlur(imgGray, (7, 7), 1)
#边缘检测
imgCanny = cv2.Canny(imgBlur, 50, 50)
getContours(imgCanny)
#定义空白图像
imgBlank = np.zeros_like(img)
imgStack = stackImages(0.6, ([img, imgGray, imgBlur], [imgCanny, imgContour, imgBlank]))
cv2.imshow("imgStack", imgStack)
cv2.waitKey(0)
颜色追踪
- 引入摄像头监控
import cv2
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10, 150)
while True:
success, img = cap.read()
cv2.imshow("Result", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
- 获取检测颜色值
import cv2
import numpy as np
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10,150)
def empty(a):
pass
cv2.namedWindow("HSV")
cv2.resizeWindow("HSV",640,240)
cv2.createTrackbar("HUE Min","HSV",0,179,empty)
cv2.createTrackbar("SAT Min","HSV",0,255,empty)
cv2.createTrackbar("VALUE Min","HSV",0,255,empty)
cv2.createTrackbar("HUE Max","HSV",179,179,empty)
cv2.createTrackbar("SAT Max","HSV",255,255,empty)
cv2.createTrackbar("VALUE Max","HSV",255,255,empty)
while True:
_, img = cap.read()
imgHsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("HUE Min","HSV")
h_max = cv2.getTrackbarPos("HUE Max", "HSV")
s_min = cv2.getTrackbarPos("SAT Min", "HSV")
s_max = cv2.getTrackbarPos("SAT Max", "HSV")
v_min = cv2.getTrackbarPos("VALUE Min", "HSV")
v_max = cv2.getTrackbarPos("VALUE Max", "HSV")
print(h_min)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHsv,lower,upper)
result = cv2.bitwise_and(img,img, mask = mask)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
hStack = np.hstack([img,mask,result])
cv2.imshow('Horizontal Stacking', hStack)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
- 颜色检测函数
myColors = [[0, 118, 140, 179, 188, 255],
[133, 56, 0, 159, 156, 255],
[57, 56, 0, 100, 255, 255]]
def findColor(img, myColors):
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
for color in myColors:
lower = np.array(color[0:3])
upper = np.array(color[3:6])
mask = cv2.inRange(imgHSV, lower, upper)
cv2.imshow("img", mask)
- 将颜色检测和摄像头监控结合
success, img = cap.read()
findColor(img, myColors)
- 获取检测对象轮廓
def getContours(img):
contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
x, y, w, h = 0, 0, 0, 0
for cnt in contours:
area = cv2.contourArea(cnt)
if area>500:
cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
x, y, w, h = cv2.boundingRect(approx)
return x+w//2, y
- 绘制物体运动轨迹
def drawOnCanvas(myPoints, myColorValues):
for point in myPoints:
cv2.circle(imgResult, (point[0], point[1]), 10, myColorValues[point[2]], cv2.FILLED)
import cv2
import numpy as np
frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
cap.set(10, 150)
myColors = [[0, 118, 140, 179, 188, 255],
[133, 56, 0, 159, 156, 255],
[57, 56, 0, 100, 255, 255]]
myColorValues = [[51, 51, 255], ##BGR
[255, 0, 255],
[0, 255, 0]]
myPoints = [] ##[x, y, colorId]
def findColor(img, myColors, myColorValues):
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
count = 0
newPoints = []
for color in myColors:
lower = np.array(color[0:3])
upper = np.array(color[3:6])
mask = cv2.inRange(imgHSV, lower, upper)
x, y = getContours(mask)
cv2.circle(imgResult, (x, y), 10, myColorValues[count], cv2.FILLED)
if x!= 0 and y!= 0:
newPoints.append([x, y, count])
count += 1
# cv2.imshow(str(color[0]), mask)
return newPoints
def drawOnCanvas(myPoints, myColorValues):
for point in myPoints:
cv2.circle(imgResult, (point[0], point[1]), 10, myColorValues[point[2]], cv2.FILLED)
def getContours(img):
contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
x, y, w, h = 0, 0, 0, 0
for cnt in contours:
area = cv2.contourArea(cnt)
if area>500:
cv2.drawContours(imgResult, cnt, -1, (255, 0, 0), 3)
peri = cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
x, y, w, h = cv2.boundingRect(approx)
return x+w//2, y
while True:
success, img = cap.read()
imgResult = img.copy()
newPoints = findColor(img, myColors, myColorValues)
if len(newPoints) != 0:
for newP in newPoints:
myPoints.append(newP)
for i in myPoints:
print("myPoints"+str(i))
if len(myPoints) !=0:
drawOnCanvas(myPoints, myColorValues)
cv2.imshow("Result", imgResult)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。