在計算機視覺和圖形學(xué)應(yīng)用中,準確測量圖像上的點之間距離是一項常見且重要的任務(wù)。本篇技術(shù)博客將詳細介紹如何利用Python編程語言和OpenCV庫構(gòu)建一個交互式的圖像距離測量工具。我們將通過編寫一個名為ImageProcessor的類,讓用戶能夠在圖像上點擊選取點,并實時顯示兩點間的實際距離(以毫米為單位)。下面讓我們一起深入探討代碼實現(xiàn)及其核心功能。
一、代碼結(jié)構(gòu)概覽
首先,我們來看看整個程序的主要組成部分:
import cv2
import numpy as np
class ImageProcessor:
def __init__(self, image_path, pixel_to_mm=0.3):
self.image_path = image_path
self.pixel_to_mm = pixel_to_mm
self.image = None
self.points = []
self.distances = []
self.load_image()
def load_image(self):
try:
self.image = cv2.imread(self.image_path)
except FileNotFoundError:
print("Image file not found.")
exit()
def calculate_distance(self, point1, point2):
pixel_distance = np.sqrt((point2[0] - point1[0]) ** 2 + (point2[1] - point1[1]) ** 2)
actual_distance = pixel_distance * self.pixel_to_mm
return pixel_distance, actual_distance
def draw_on_image(self):
img_copy = self.image.copy()
for i in range(len(self.points)):
cv2.circle(img_copy, self.points[i], 3, (0, 0, 255), -1) # Display Point
if i % 2 == 1:
cv2.line(img_copy, self.points[i - 1], self.points[i], (255, 0, 0), 2) # Draw line between points
pixel_distance, actual_distance = self.calculate_distance(self.points[i - 1], self.points[i])
self.distances.append(actual_distance)
text = "AD: {:.2f} mm".format(actual_distance)
cv2.putText(img_copy, text, (
(self.points[i - 1][0] + self.points[i][0]) // 2, (self.points[i - 1][1] + self.points[i][1]) // 2),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
return img_copy
def mouse_event(self, event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
self.points.append((x, y))
def process(self):
cv2.namedWindow('Image')
cv2.setMouseCallback('Image', self.mouse_event)
while True:
img_copy = self.draw_on_image()
cv2.imshow('Image', img_copy)
key = cv2.waitKey(1) & 0xFF
if key == 27: # Press 'Esc' to exit
break
cv2.destroyAllWindows()
if __name__ == "__main__":
processor = ImageProcessor('mask/img.png', pixel_to_mm=0.3)
processor.process()
該程序主要由以下幾部分組成:
-
標題引入必要的庫:cv2(OpenCV庫)用于圖像處理和顯示,numpy(NumPy庫)用于數(shù)值計算。
-
定義ImageProcessor類:封裝圖像加載、點選、距離計算、結(jié)果顯示等邏輯。
-
主程序入口:創(chuàng)建ImageProcessor實例,傳入圖像路徑和像素與毫米的比例,默認為0.3,然后調(diào)用process方法啟動交互過程。
接下來,我們將逐一解析ImageProcessor類中的關(guān)鍵方法。
二、ImageProcessor類詳解
- __init__方法
def __init__(self, image_path, pixel_to_mm=0.3):
self.image_path = image_path
self.pixel_to_mm = pixel_to_mm
self.image = None
self.points = []
self.distances = []
self.load_image()
__init__方法是類的構(gòu)造器,負責(zé)初始化對象屬性。這里定義了以下幾個屬性:
image_path: 存儲待處理圖像的路徑。
pixel_to_mm: 像素與毫米之間的比例,默認值為0.3,表示每個像素代表0.3毫米。
image: 用于存放加載的圖像數(shù)據(jù)。
points: 存儲用戶點擊的點坐標,按點擊順序排列。
distances: 存儲已計算的實際距離值。
最后,load_image方法被調(diào)用,用于加載指定路徑下的圖像
- load_image方法
def load_image(self):
try:
self.image = cv2.imread(self.image_path)
except FileNotFoundError:
print("Image file not found.")
exit()
load_image方法負責(zé)從指定路徑加載圖像。它使用cv2.imread函數(shù)嘗試讀取圖像,如果文件不存在,則捕獲FileNotFoundError異常,打印錯誤消息并退出程序,確保程序在遇到無效文件時能優(yōu)雅終止。
- calculate_distance方法
def calculate_distance(self, point1, point2):
pixel_distance = np.sqrt((point2[0] - point1[0]) ** 2 + (point2[1] - point1[1]) ** 2)
actual_distance = pixel_distance * self.pixel_to_mm
return pixel_distance, actual_distance
calculate_distance方法接收兩個點坐標作為參數(shù),計算它們之間的像素距離(歐氏距離)并轉(zhuǎn)換為實際距離(毫米)。結(jié)果以元組形式返回,包含像素距離和實際距離。
- draw_on_image方法
def draw_on_image(self):
img_copy = self.image.copy()
for i in range(len(self.points)):
cv2.circle(img_copy, self.points[i], 3, (0, 0, 255), -1) # Display Point
if i % 2 == 1:
cv2.line(img_copy, self.points[i - 1], self.points[i], (255, 0, 0), 2) # Draw line between points
pixel_distance, actual_distance = self.calculate_distance(self.points[i - 1], self.points[i])
self.distances.append(actual_distance)
text = "AD: {:.2f} mm".format(actual_distance)
cv2.putText(img_copy, text, (
(self.points[i - 1][0] + self.points[i][0]) // 2, (self.points[i - 1][1] + self.points[i][1]) // 2),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
return img_copy
draw_on_image方法負責(zé)在圖像副本上繪制用戶選擇的點、連線及距離文字。具體步驟如下:文章來源:http://www.zghlxwxcb.cn/news/detail-850869.html
- 創(chuàng)建圖像副本,防止直接修改原始圖像。
- 遍歷points列表,繪制每個點為紅色圓圈。
- 當(dāng)索引i為奇數(shù)時,表示當(dāng)前點與前一個點構(gòu)成一對,于是:
繪制連接這兩個點的線。
調(diào)用calculate_distance計算它們之間的實際距離,并將結(jié)果添加到distances列表。
在兩點之間合適的位置繪制包含實際距離的文字。
最后返回處理過的圖像副本。
- mouse_event
def mouse_event(self, event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
self.points.append((x, y))
mouse_event方法作為鼠標回調(diào)函數(shù),響應(yīng)用戶的鼠標操作。當(dāng)用戶按下左鍵(cv2.EVENT_LBUTTONDOWN)時,將當(dāng)前鼠標位置((x, y))添加到points列表中。文章來源地址http://www.zghlxwxcb.cn/news/detail-850869.html
到了這里,關(guān)于OpenCV構(gòu)建交互式圖像距離測量工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!