medical_balloon/Dimensional_Inspection/size_0625_test.py
leo890808 a1fb25c89f UP
2024-07-30 16:18:26 +08:00

147 lines
6.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
import numpy as np
class ImageProcessor:
def __init__(self, image_path):
# 讀取圖像
self.original_image = cv2.imread(image_path)
self.process_image()
def process_image(self):
# 複製原始圖像
img = self.original_image.copy()
o_img_black = img.copy()
o_img_black[:, :, :] = 0
# 將圖像轉換為灰度圖
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用 Canny 邊緣檢測
edges = cv2.Canny(gray_image, 250, 250)
cv2.imshow('Canny Edges', edges) # 顯示 Canny 邊緣檢測結果
cv2.imwrite('canny_edges.jpg', edges) # 保存 Canny 邊緣檢測結果
# 檢測直線
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, threshold=100, minLineLength=100, maxLineGap=200)
# 初始化黑色圖像
black_img = gray_image.copy()
black_img[:, :] = 0
hough_lines_image = black_img.copy() # 用於顯示HoughLinesP檢測結果的圖像
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(black_img, (x1, y1), (x2, y2), (255, 255, 0), 2)
cv2.line(hough_lines_image, (x1, y1), (x2, y2), (255, 255, 0), 2)
cv2.imshow('Hough Lines', hough_lines_image) # 顯示 HoughLinesP 檢測結果
cv2.imwrite('hough_lines.jpg', hough_lines_image) # 保存 HoughLinesP 檢測結果
# 繪製紅色的兩條線
cv2.line(o_img_black, (300, 0), (300, len(o_img_black)), (0, 0, 255), 2)
cv2.line(o_img_black, (len(o_img_black[0]) - 300, 0), (len(o_img_black[0]) - 300, len(o_img_black)), (0, 0, 255), 2)
# 找到黑色圖像中白色255的像素
y_list, x_list = np.where(black_img == 255)
# 像素大小5.5um
pixel_size_um = 5.5
# 計算直徑
diameter1, point1_top, point1_bottom = self.calculate_diameter(300, x_list, y_list, pixel_size_um)
diameter2, point2_top, point2_bottom = self.calculate_diameter(o_img_black.shape[1] - 300, x_list, y_list, pixel_size_um)
# 計算角度並找到負角度的最小值和正角度的最大值
angle_sum = self.calculate_angles(lines)
# 標記相交點
self.mark_intersection_points(o_img_black, x_list, y_list, 300, o_img_black.shape[1] - 300)
# 繪製點和垂直線
self.draw_points_and_lines(diameter1, diameter2, point1_top, point1_bottom, point2_top, point2_bottom)
# 顯示結果
self.display_image(o_img_black, diameter1, diameter2, angle_sum)
def calculate_diameter(self, x_value, x_list, y_list, pixel_size_um):
indices = np.where(x_list == x_value)[0]
y_values = y_list[indices]
max_y = np.max(y_values)
min_y = np.min(y_values)
diff = max_y - min_y
diameter = diff * pixel_size_um / 1000
print(f"直徑: Ø{diameter:.3f} mm")
return diameter, (x_value, min_y), (x_value, max_y)
def calculate_angles(self, lines):
min_negative_angle = float('inf')
max_positive_angle = float('-inf')
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line[0]
angle = np.arctan2(y2 - y1, x2 - x1) * 180.0 / np.pi
if angle < 0:
min_negative_angle = min(min_negative_angle, angle)
elif angle > 0:
max_positive_angle = max(max_positive_angle, angle)
if min_negative_angle != float('inf') and max_positive_angle != float('-inf'):
min_negative_angle_abs = abs(min_negative_angle)
angle_sum = min_negative_angle_abs + max_positive_angle
print(f"角度為: {angle_sum:.2f} °")
return angle_sum
return None
def mark_intersection_points(self, img, x_list, y_list, x_value1, x_value2):
indices_1 = np.where(x_list == x_value1)[0]
indices_2 = np.where(x_list == x_value2)[0]
intersection_points_1 = [(x_value1, y_list[i]) for i in indices_1]
intersection_points_2 = [(x_value2, y_list[i]) for i in indices_2]
intersection_points = intersection_points_1 + intersection_points_2
for point in intersection_points:
cv2.circle(img, point, 10, (183, 143, 58), -1)
for i in range(len(x_list)):
point = (x_list[i], y_list[i])
cv2.circle(img, point, 1, (183, 143, 58), -1)
def draw_points_and_lines(self, diameter1, diameter2, point1_top, point1_bottom, point2_top, point2_bottom):
# 在原圖上添加測量點和連接線
cv2.line(self.original_image, point1_top, point1_bottom, (121, 180, 177), 2)
cv2.circle(self.original_image, point1_top, 10, (183, 143, 58), -1)
cv2.circle(self.original_image, point1_bottom, 10, (183, 143, 58), -1)
cv2.line(self.original_image, point2_top, point2_bottom, (121, 180, 177), 2)
cv2.circle(self.original_image, point2_top, 10, (183, 143, 58), -1)
cv2.circle(self.original_image, point2_bottom, 10, (183, 143, 58), -1)
def display_image(self, img, diameter1, diameter2, angle_sum):
# Resize and display original image
original_resized = cv2.resize(self.original_image, (1280, 1280))
# Add status bar information on the original image
cv2.putText(original_resized, f"Diameter1: {diameter1:.3f} mm", (25, 80), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2) #300
cv2.putText(original_resized, f"Diameter2: {diameter2:.3f} mm", (25, 130), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2) #350
# cv2.putText(original_resized, f"Diameter1: {diameter1:.3f} mm", (25, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
# cv2.putText(original_resized, f"Diameter2: {diameter2:.3f} mm", (25, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
if angle_sum is not None:
cv2.putText(original_resized, f"Angle: {angle_sum:.2f} degrees", (25, 180), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2) #400
# Resize and display processed image
processed_resized = cv2.resize(img, (1280, 1280))
# Show the images
cv2.imshow('Original Image', original_resized)
cv2.imwrite('Original_Image.jpg', original_resized) # 保存 original 邊緣檢測結果
cv2.imshow('Processed Image', processed_resized)
cv2.imwrite('Processed_Image.jpg', processed_resized) # 保存 Processed 邊緣檢測結果
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
image_path = r'D:\Code\Project\Medeologix\Python\Size\01_10fps_0.041ms_0db_1092\10.bmp'
processor = ImageProcessor(image_path)