你好啊
今天我来分享一个测量角度的小程序
首先你需要准备一个学习角度的练习题,应该是小学的那种课后习题作为图片即可。
这是我找的图片
第一步很简单,就是读出图片:
import cv2
import math
path = 'text.jpg'
img = cv2.imread(path)
cv2.imshow('Image',img),
cv2.waitKey(0)
我们要利用鼠标来定点,定三个点,这样就可以求角的大小了。那么我们利用函数setMouseCallback():
void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)
winname:窗口的名字
onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函
数的原型应该为void mousePoints(int event, int x, int y, int flags, void* param);
userdate:传给回调函数的参数
再来介绍MouseCallback mousePoints的函数原型:
void mousePoints(int event, int x, int y, int flags, void* param);
event是 CV_EVENT_*变量之一
x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)
flags是CV_EVENT_FLAG的组合, param是用户定义的传递到setMouseCallback函数调用的参数。
利用该函数我们可以得到的鼠标点击左键时候的坐标,常用的event自己用到可以去百度:
import cv2
import math
path = 'text.jpg'
img = cv2.imread(path)
def mousePoints(event,x,y,flags,params):
if event == cv2.EVENT_LBUTTONDOWN:
print(x,y)
cv2.imshow('Image',img)
cv2.setMouseCallback('Image',mousePoints)
cv2.waitKey(0)
坐标就可打印出来了。那么接下来我们开始存储三个点的坐标即可:
import cv2
import math
path = 'text.jpg'
img = cv2.imread(path)
pointsList = []
def mousePoints(event,x,y,flags,params):
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(img,(x,y),5,(0,255,125),cv2.FILLED)#对选择的点的位置进行标记
pointsList.append([x,y])#添加坐标
print(pointsList)
print(x,y)
while True:
cv2.imshow('Image',img)
cv2.setMouseCallback('Image',mousePoints)
if cv2.waitKey(1) & 0xFF == ord('q'):#当输入Q的时候,可以清除存储的坐标
pointsList = []
img = cv2.imread(path)
其中A,B为直线斜率,所以还要求两条直线的斜率:
def gradient(pt1,pt2):#求斜率
return (pt2[1]-pt1[1])/(pt2[0]-pt1[0])
def getAngle(pointsList):#求角度
pt1,pt2,pt3 = pointsList[-3:]
m1 = gradient(pt1,pt2)
m2 = gradient(pt1,pt3)
angR = math.atan((m2-m1)/(1+(m2*m1)))
angD = round(math.degrees(angR))#将弧度转化成角度,并且以整数输出
print(angD)
可能有点误差,因为直线的粗细,点的位置等等都有影响。
最后在完善一下程序,首先添加一个画线的动作,在加上度数的显示:
import cv2
import math
path = 'text.jpg'
img = cv2.imread(path)
pointsList = []
def mousePoints(event,x,y,flags,params):
if event == cv2.EVENT_LBUTTONDOWN:
#画出线
size = len(pointsList)
if size != 0 and size % 3 != 0:
cv2.line(img,tuple(pointsList[round((size-1)/3)*3]),(x,y),(0,0,225),2)
#画点
cv2.circle(img,(x,y),5,(0,255,125),cv2.FILLED)
pointsList.append([x,y])
#print(pointsList)
#print(x,y)
def gradient(pt1,pt2):
return (pt2[1]-pt1[1])/(pt2[0]-pt1[0])
def getAngle(pointsList):
pt1,pt2,pt3 = pointsList[-3:]
m1 = gradient(pt1,pt2)
m2 = gradient(pt1,pt3)
angR = math.atan((m2-m1)/(1+(m2*m1)))
angD = round(math.degrees(angR))#将弧度转化成角度,并且以整数输出
cv2.putText(img,str(angD),(pt1[0]-40,pt1[1]-20),cv2.FONT_HERSHEY_DUPLEX,2,(255,0,0),2)
while True:
if len(pointsList) % 3 == 0 and len(pointsList) != 0:
getAngle(pointsList)
cv2.imshow('Image',img)
cv2.setMouseCallback('Image',mousePoints)
if cv2.waitKey(1) & 0xFF == ord('q'):
pointsList = []
img = cv2.imread(path)
ok,下一个小项目再见吧。