日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Python+OpenCV實(shí)現(xiàn)角度測(cè)量的示例代碼_python

作者:沒有水的海綿 ? 更新時(shí)間: 2022-05-05 編程語(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

欄目分類
最近更新