您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Python+OpenCV如何實(shí)現(xiàn)角度測(cè)量”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Python+OpenCV如何實(shí)現(xiàn)角度測(cè)量”這篇文章吧。
最終實(shí)現(xiàn)效果:在圖片上用鼠標(biāo)確認(rèn)三點(diǎn),程序?qū)?huì)顯示由此三點(diǎn)確定的角度,如下圖所示。
1、鼠標(biāo)選點(diǎn)
# -*- coding: utf-8 -*- import cv2 path = "picture_mqa\\angle_measure.bmp" img = cv2.imread(path) pointsList = [] def mousePoints(event,x,y,flags,params): if event == cv2.EVENT_LBUTTONDOWN: cv2.circle(img,(x,y),5,(0,0,255),cv2.FILLED) print(x,y) while True: cv2.imshow('Image', img) cv2.setMouseCallback('Image',mousePoints) key_scan = cv2.waitKey(1) & 0xff if key_scan == ord("q"): pointsList = [] img = cv2.imread(path) elif key_scan == ord("s"): break cv2.destroyAllWindows()
while循環(huán)內(nèi)cv2.setMouseCallback('Image',mousePoints)為鼠標(biāo)中斷觸發(fā)事件的開啟函數(shù),作用是當(dāng)在Image圖片上鼠標(biāo)觸發(fā)中斷事件時(shí),程序跳轉(zhuǎn)到mousePoints()中斷服務(wù)函數(shù)內(nèi),并給mousePoints()的五個(gè)入口參數(shù)event,x,y,flags,params賦值。其中, event是cv2_EVENT_* (MouseEventTypes)類型的變量,為鼠標(biāo)觸發(fā)中斷事件的類型;x和y為鼠標(biāo)觸發(fā)中斷事件時(shí)在image圖像的橫縱坐標(biāo);flags是cv2_EVENT_FLAG_* (MouseEventFlags)類型的變量,為特殊中斷事件的標(biāo)志位;param是用戶自定義的參數(shù)。本文的程序中使用 EVENT_LBUTTONDOW#左鍵點(diǎn)擊觸發(fā)事件,當(dāng)鼠標(biāo)左鍵點(diǎn)擊時(shí),標(biāo)注該點(diǎn)并記錄其坐標(biāo)。
event的賦值:
EVENT_MOUSEMOVE #滑動(dòng)
EVENT_LBUTTONDOWN #左鍵點(diǎn)擊
EVENT_RBUTTONDOWN #右鍵點(diǎn)擊
EVENT_MBUTTONDOWN #中鍵點(diǎn)擊
EVENT_LBUTTONUP #左鍵放開
EVENT_RBUTTONUP #右鍵放開
EVENT_MBUTTONUP #中鍵放開
EVENT_LBUTTONDBLCLK #左鍵雙擊
EVENT_RBUTTONDBLCLK #右鍵雙擊
EVENT_MBUTTONDBLCLK #中鍵雙擊
2、角度計(jì)算
由1可以得到鼠標(biāo)點(diǎn)擊位置處的坐標(biāo),我們將其放入pointList列表內(nèi)。當(dāng)列表內(nèi)的坐標(biāo)數(shù)目為3的倍數(shù)時(shí)調(diào)用getAngle()函數(shù),計(jì)算出三點(diǎn)確定的兩條直線的夾角。
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 = abs(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_COMPLEX, 1.5,(0,0,255))
由直線的兩點(diǎn)式方程可得直線的傾斜角為angle = arctan(y2-y1,x2-x1),則兩條直線的夾角為angle0 =angle1-angle2 = arctan(y2-y1,x2-x1) - arctan(y2-y3,x2-x3)。以上函數(shù)便可根據(jù)三點(diǎn)的坐標(biāo)值求其形成夾角的角度。
3、完整程序
# -*- coding: utf-8 -*- ''' 測(cè)量鼠標(biāo)點(diǎn)擊過(guò)的三點(diǎn)形成的角度 ''' import cv2 import math path = "picture_mqa\\angle_measure.bmp" #圖片路徑 img = cv2.imread(path) pointsList = [] #鼠標(biāo)中斷觸發(fā)函數(shù),將鼠標(biāo)觸發(fā)事件位置處描點(diǎn)并將該點(diǎn)的坐標(biāo)值紀(jì)錄入pointList列表內(nèi) #連接相鄰三點(diǎn)使其形成一個(gè)夾角 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,255)) cv2.circle(img,(x,y),5,(0,0,255),cv2.FILLED) pointsList.append([x,y]) #由兩點(diǎn)的坐標(biāo)值計(jì)算兩點(diǎn)所在直線的斜率 def gradient(pt1,pt2): return ((pt2[1]-pt1[1])/(pt2[0]-pt1[0])) #根據(jù)相鄰的三點(diǎn)計(jì)算出其形成夾角的角度值 def getAngle(pointsList): pt1,pt2,pt3 = pointsList[-3:] m1 = gradient(pt1, pt2) m2 = gradient(pt1, pt3) angR = abs(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_COMPLEX, 1.5,(0,0,255)) while True: cv2.imshow('Image', img) #圖片顯示 cv2.setMouseCallback('Image',mousePoints) #鼠標(biāo)觸發(fā)事件開啟 if len(pointsList) % 3 ==0 and len(pointsList)!=0: #鼠標(biāo)每觸發(fā)中斷3次計(jì)算一次其形式夾角的角度值 getAngle(pointsList) key_scan = cv2.waitKey(1) & 0xff #鍵盤掃描 if key_scan == ord("q"): #輸入'q'時(shí)圖片刷新 pointsList = [] img = cv2.imread(path) elif key_scan == ord("s"): #輸入's'時(shí)退出程序 break cv2.destroyAllWindows()
以上是“Python+OpenCV如何實(shí)現(xiàn)角度測(cè)量”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。