帮我在保留处理图像功能的基础上,简化这个程序
时间: 2024-11-25 10:08:33 浏览: 11
为了简化程序同时保留处理图像的核心功能,我们可以删除一些不必要的组件和逻辑,专注于核心的图像加载、预处理、轮廓检测和结果显示。以下是简化后的代码:
```python
import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
class AggregateAnalyzer:
def __init__(self, root):
self.root = root
self.root.title("沥青混合料颗粒分析器")
self.image_path = ""
self.image = None
self.processed_image = None
self.contours = []
self.min_contour_area = 50
self.create_widgets()
def create_widgets(self):
self.load_button = tk.Button(self.root, text="加载图像", command=self.load_image)
self.load_button.pack(pady=5)
self.analyze_button = tk.Button(self.root, text="分析图像", command=self.analyze_image, state="disabled")
self.analyze_button.pack(pady=5)
self.status_label = tk.Label(self.root, text="准备就绪")
self.status_label.pack(pady=5)
self.file_path_label = tk.Label(self.root, text="未选择文件")
self.file_path_label.pack(pady=5)
self.canvas = tk.Canvas(self.root, bg='white')
self.canvas.pack(pady=10)
def load_image(self):
self.image_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.jpg;*.png;*.bmp")])
if not self.image_path:
self.status_label.config(text="未选择文件。")
return
self.image = cv2.imread(self.image_path)
if self.image is None:
self.show_error("无法读取图像。文件可能已损坏或格式不支持。")
return
self.update_display_image(self.image)
self.analyze_button.config(state="normal")
self.status_label.config(text="图像已加载")
def update_display_image(self, image):
self.canvas.delete("all")
if image is not None:
photo = self.scale_and_convert(image)
self.canvas.create_image(0, 0, image=photo, anchor="nw")
self.photo = photo
self.canvas.config(scrollregion=self.canvas.bbox("all"))
self.canvas.config(width=photo.width(), height=photo.height())
def show_error(self, message):
messagebox.showerror("错误", message)
def scale_and_convert(self, image):
try:
height, width = image.shape[:2]
max_dim = max(height, width)
canvas_width = self.canvas.winfo_reqwidth() if self.canvas.winfo_exists() else width
scale_factor = min(1, canvas_width / max_dim)
new_size = (int(width * scale_factor), int(height * scale_factor))
image = cv2.resize(image, new_size, interpolation=cv2.INTER_LANCZOS4)
image = Image.fromarray(image)
return ImageTk.PhotoImage(image)
except Exception as e:
self.show_error(f"在缩放和转换图像时发生错误:{str(e)}")
return None
def preprocess_image(self, image):
if image is None:
raise ValueError("输入图像为空")
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_img = cv2.equalizeHist(gray_img)
median_img = cv2.medianBlur(gray_img, ksize=5)
_, binary_img = cv2.threshold(median_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
return closing
def find_material_contour(self, image):
if image is None:
raise ValueError("输入图像为空")
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_img = cv2.equalizeHist(gray_image)
_, binary_img = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
material_contour = max(contours, key=cv2.contourArea) if contours else None
if material_contour is None or cv2.contourArea(material_contour) < self.min_contour_area:
raise ValueError("未检测到符合条件的材料轮廓")
return material_contour
def find_grain_contours(self, image, material_contour):
if image is None or material_contour is None:
raise ValueError("输入图像或材料轮廓为空")
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_img = cv2.equalizeHist(gray_img)
_, binary_img = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
filtered_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > self.min_contour_area]
return filtered_contours
def analyze_image(self):
if self.image is None:
self.show_error("未加载图像。")
return
try:
self.status_label.config(text="正在预处理图像...")
processed_image = self.preprocess_image(self.image)
self.status_label.config(text="正在识别材料轮廓...")
material_contour = self.find_material_contour(processed_image)
self.status_label.config(text="正在识别颗粒轮廓...")
grain_contours = self.find_grain_contours(processed_image, material_contour)
self.status_label.config(text="正在绘制轮廓...")
output_image = processed_image.copy()
cv2.drawContours(output_image, [material_contour], -1, (0, 0, 255), 2)
cv2.drawContours(output_image, grain_contours, -1, (0, 255, 0), 2)
self.update_display_image(output_image)
self.status_label.config(text="轮廓已检测")
except Exception as e:
self.show_error(f"分析图像时发生错误:{str(e)}")
if __name__ == "__main__":
root = tk.Tk()
root.title("沥青混合料颗粒分析器")
root.minsize(800, 600)
app = AggregateAnalyzer(root)
root.mainloop()
```
### 主要改动:
1. **去掉了不必要的组件**:删除了最小粒径输入框、截面类型选择、显示二值图像按钮等。
2. **简化了图像加载和显示逻辑**:减少了冗余代码,优化了图像加载和显示的流程。
3. **保留了核心功能**:保留了图像加载、预处理、轮廓检测和结果显示的主要步骤。
4. **去掉了错误日志记录**:简化了错误处理,仅保留基本的错误弹窗提示。
这样,程序变得更加简洁,但仍保留了关键的功能。
阅读全文