共计 14299 个字符,预计需要花费 36 分钟才能阅读完成。
@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
正文完
发表至: opencv-python
2020-11-21