網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
本文介紹如何使用python語(yǔ)言實(shí)現(xiàn)角度測(cè)量,程序包括鼠標(biāo)選點(diǎn)、直線斜率計(jì)算、角度計(jì)算三個(gè)子程序和一個(gè)主程序。最終實(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)擊過的三點(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()
原文鏈接:https://blog.csdn.net/qq_42242399/article/details/123259393
相關(guān)推薦
- 2023-06-05 python文件編譯為pyc后運(yùn)行的實(shí)現(xiàn)步驟_python
- 2022-02-09 Qt5連接并操作PostgreSQL數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例_C 語(yǔ)言
- 2023-07-10 String.format()格式化輸出
- 2022-09-24 詳解K8S?apiVersion對(duì)照表_云其它
- 2023-03-02 docker-compose安裝RabbitMQ及插件操作步驟_docker
- 2023-02-14 使用PowerShell獲取Trustedinstaller權(quán)限的問題_PowerShell
- 2022-11-03 C語(yǔ)言編寫掃雷小程序_C 語(yǔ)言
- 2022-11-20 Go語(yǔ)言操作Excel利器之excelize類庫(kù)詳解_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支