2022-06-14 Python OpenCV 常用工具类
2022-06-14 本文已影响0人
颈椎以上瘫痪
显示图像
cv.imshow()是显示图像的函数,需要2个参数,一个是需要显示的图像,还一个是显示图像窗口的标题,在一个进程中同样标题的窗口只能存在一个,比如你先显示一个标题1的图像,再显示一个标题1的图像,那么后显示的图像窗口就会将前面那个销毁掉。这个函数显示图像窗口是OpenCV的调试窗口,默认是不能缩放的,图像有多大,窗口就显示多大,但是在过程中我们往往会显示很多窗口,也需要手动缩放和拖动这些窗口,所以在定义这个窗口时需要执行一个cv.WINDOW_NORMAL属性,然后在这个窗口里面显示图像就可以缩放了。
# 显示图像
def show(title, image):
cv.namedWindow(title, cv.WINDOW_NORMAL)
cv.imshow(title, image)
绘制矩形
cv.rectangle()是在图像上绘制一个矩形的函数,需要的参数有一个图像,2个点(左上角和右下角),矩形框的颜色,矩形框的线宽。注意这里传入的坐标点的值不能是小数,如果你在计算过程中的数据精确到小数了,这里就需要采取一些手段来避免出错,比如这里对坐标值使用四舍五入。
def drawRectangle(canvas, p1, p2):
cv.rectangle(canvas, (round(p1[0]), round(p1[1])), (round(p2[0]), round(p2[1])), (0, 0, 255), 2)
三角形已知三个角和1条边,求另2条边
三角形已知3个角度值和1条边长,可以使用这个函数计算另2条边长,注意数据的顺序,边长按照顺序其对角的顺序。
def calSide(angles, a):
angleA = angles[0]
angleB = angles[1]
angleC = angles[2]
b = math.sin(angleB / 180 * math.pi) * a
c = math.cos(angleB / 180 * math.pi) * a
return b, c
获取图像中某区域附近红色和绿色像素分量
def getRedAndGreenCount(img, point, offset, canvas):
# 根据偏移量,在点附近绘制矩形
cv.rectangle(canvas, (round(point[0] - offset), round(point[1] - offset)),
(round(point[0] + offset), round(point[1] + offset)), (0, 0, 255), 1)
# 将这个矩形裁剪出来
status = img[round(point[1] - offset):round(point[1] + offset), round(point[0] - offset):round(point[0] + offset)]
if status is None:
return None
# show("RedAndGreen"+str(point),status)
try:
count = redAndGreen(status)
return count
except Exception:
return None
pass
判断图像中红色和绿色像素分量的数量
def redAndGreen(img):
# 先将图像转成HSV
hsvSrc = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# 找红色区间
lowerColorRed = np.array([0, 43, 46])
upperColorRed = np.array([10, 255, 255])
hsvRed = cv.inRange(hsvSrc, lowerColorRed, upperColorRed)
# 找绿色区间
lowerColorGreen = np.array([35, 43, 46])
upperColorGreen = np.array([77, 255, 255])
hsvGreen = cv.inRange(hsvSrc, lowerColorGreen, upperColorGreen)
# 找出各颜色图像中白色像素点的数量
redCount = 0
greenCount = 0
w, h, c = img.shape
for j in range(w):
for k in range(h):
if hsvRed[j, k] == (255.0):
redCount = redCount + 1
if hsvGreen[j, k] == (255.0):
greenCount = greenCount + 1
return greenCount + redCount
判断图像是红色还是绿色
def redOrGreen(img):
# 先将图像转成HSV
hsvSrc = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# 找红色区间
lowerColorRed = np.array([0, 43, 46])
upperColorRed = np.array([10, 255, 255])
hsvRed = cv.inRange(hsvSrc, lowerColorRed, upperColorRed)
# 找绿色区间
lowerColorGreen = np.array([35, 43, 46])
upperColorGreen = np.array([77, 255, 255])
hsvGreen = cv.inRange(hsvSrc, lowerColorGreen, upperColorGreen)
# 找出各颜色图像中白色像素点的数量
redCount = 0
greenCount = 0
w, h, c = img.shape
for j in range(w):
for k in range(h):
if hsvRed[j, k] == (255.0):
redCount = redCount + 1
if hsvGreen[j, k] == (255.0):
greenCount = greenCount + 1
if greenCount > redCount:
return 1
else:
return 0
计算线段中点1到点2的方向
def calAngleLine(line):
angle = 0
point1 = (line[0], line[1])
point2 = (line[2], line[3])
x1, y1 = point1
x2, y2 = point2
# 水平
if y1 == y2:
# 右
if x1 < x2:
angle = 0
# 左
elif x1 > x2:
angle = 180
# 同一个点
else:
angle = 0
# 向上
elif y1 > y2:
# 右上
if x1 < x2:
angle = 360 - calAngle(point1, point2, (x2, y1))[0]
# 左上
elif x1 > x2:
angle = 180 + calAngle(point1, point2, (x2, y1))[0]
# 上
else:
angle = 270
# 向下
else:
# 右下
if x1 < x2:
angle = calAngle(point1, point2, (x2, y1))[0]
# 左下
elif x1 > x2:
angle = 180 - calAngle(point1, point2, (x2, y1))[0]
# 下
else:
angle = 90
return angle
已知3个点求其三角形的角度
返回的数组中3个角度值,与传参进来的点的顺序是对应的。
def calAngle(p1, p2, p3):
angles = []
a = math.sqrt((p2[0] - p3[0]) * (p2[0] - p3[0]) + (p2[1] - p3[1]) * (p2[1] - p3[1]))
b = math.sqrt((p1[0] - p3[0]) * (p1[0] - p3[0]) + (p1[1] - p3[1]) * (p1[1] - p3[1]))
c = math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]))
A = math.degrees(math.acos((a * a - b * b - c * c) / (-2 * b * c)))
B = math.degrees(math.acos((b * b - a * a - c * c) / (-2 * a * c)))
C = math.degrees(math.acos((c * c - a * a - b * b) / (-2 * a * b)))
angles.append(A)
angles.append(B)
angles.append(C)
return angles
角度校正
在使用角度时我们往往只需要0-360的值,但是角度在经过计算后经常会超过边界,所以使用这个函数可以将超出边界的值换算到边界内。
def rectifyAngle(angle):
if angle >= 360:
angle = angle - 360
elif angle < 0:
angle = angle + 360
if angle < 0 | angle >= 360:
return rectifyAngle(angle)
return angle
计算点的偏移坐标
计算一个点的偏移坐标,需要一个点、一个角度、一个距离,计算出偏移后的点。
def calPoint4AngleDistance(center, angle, distance):
x, y = center
point = ()
if angle >= 360:
angle %= 360
# 右
if angle == 0:
point = (x + distance, y)
pass
# 下
elif angle == 90:
point = (x, y + distance)
pass
# 左
elif angle == 180:
point = (x - distance, y)
pass
# 上
elif angle == 270:
point = (x, y - distance)
pass
# 右下
elif angle > 0 and angle < 90:
angles = []
angles.append(90)
angles.append(angle)
angles.append(90 - angle)
b, c = calSide(angles, distance)
point = (x + c, y + b)
pass
# 左下
elif angle > 90 and angle < 180:
angles = []
angles.append(90)
angles.append(180 - angle)
angles.append(angle - 90)
b, c = calSide(angles, distance)
point = (x - c, y + b)
pass
# 左上
elif angle > 180 and angle < 270:
angles = []
angles.append(90)
angles.append(angle - 180)
angles.append(270 - angle)
b, c = calSide(angles, distance)
point = (x - c, y - b)
pass
# 右上
elif angle > 270 and angle < 360:
angles = []
angles.append(90)
angles.append(360 - angle)
angles.append(angle - 270)
b, c = calSide(angles, distance)
point = (x + c, y - b)
pass
return point
求两点间距离
def getDistance(p1, p2):
distance = math.pow((p1[0] - p1[0]), 2) + math.pow((p2[1] - p2[1]), 2)
distance = math.sqrt(distance)
return distance