习惯self

  1. class Person:
  2.     def __init__(self,name):
  3.         self.name=name
  4.     def sayHi(self):
  5.         print '''''my name is
  6.         :''',self.name
  7. p=Person("cgk")
  8. p.sayHi()
python用另外的一种形式诠释了类中方法的参数。
假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1, arg2)——这就是self的原理了。要学会习惯于这种方式,理解起来好像更加的透彻了一些。
import cv2 import numpy as np import pytesseract import tkinter as tk from tkinter import filedialog, messagebox, ttk from PIL import Image, ImageTk import imutils # --- 配置区(关键优化:中文识别核心配置)--- TESSERACT_PATH = r'C:\Program Files\Tesseract-OCR\tesseract.exe' pytesseract.pytesseract.tesseract_cmd = TESSERACT_PATH # 语言包路径必须用原始字符串,避免转义错误(双重保障) pytesseract.pytesseract_config = r'--tessdata-dir "C:\Program Files\Tesseract-OCR\tessdata"' # 车牌专用配置(确保汉字包含所有省份简称) PROVINCE_LIST = "京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼" CHAR_WHITELIST = PROVINCE_LIST + 'ABCDEFGHJKLMNPQRSTUVWXYZ0123456789' class LicensePlateRecognitionApp: def __init__(self, root): self.root = root self.root.title("智能车牌识别系统(支持汉字识别)") self.root.geometry("1600x1000") self.root.resizable(True, True) # 初始化变量 self.image_path = None self.original_image = None self.gray_image = None # 灰度图 self.blur_image = None # 高斯滤波图 self.edged_image = None # 边缘检测图 self.contour_image = None # 轮廓标记图 self.plate_image = None # 定位车牌图 self.recognition_result = "" # 创建界面 self._create_widgets() def _create_widgets(self): # 主框架 main_frame = ttk.Frame(self.root, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # 顶部控制区 control_frame = ttk.Frame(main_frame) control_frame.pack(fill=tk.X, pady=5) self.select_btn = ttk.Button(control_frame, text="选择图片", command=self.select_image) self.select_btn.pack(side=tk.LEFT, padx=5) self.recognize_btn = ttk.Button(control_frame, text="开始识别", command=self.start_recognition, state=tk.DISABLED) self.recognize_btn.pack(side=tk.LEFT, padx=5) self.clear_btn = ttk.Button(control_frame, text="清空", command=self.clear_all) self.clear_btn.pack(side=tk.LEFT, padx=5) # 2×3网格图像显示区 image_frame = ttk.Frame(main_frame) image_frame.pack(fill=tk.BOTH, expand=True, pady=10) self.step_titles = [ "原图", "灰度图", "高斯滤波", "边缘检测", "轮廓标记", "定位车牌" ] self.step_labels = [] for row in range(2): for col in range(3): step_frame = ttk.LabelFrame(image_frame, text=self.step_titles[row * 3 + col], padding="5") step_frame.grid(row=row, column=col, padx=5, pady=5, sticky=tk.NSEW) image_frame.grid_rowconfigure(row, weight=1) image_frame.grid_columnconfigure(col, weight=1) img_label = ttk.Label(step_frame) img_label.pack(fill=tk.BOTH, expand=True) self.step_labels.append(img_label) # 识别结果区 result_frame = ttk.LabelFrame(main_frame, text="识别结果(支持汉字)", padding="10") result_frame.pack(fill=tk.X, pady=10) self.result_var = tk.StringVar() self.result_entry = ttk.Entry(result_frame, textvariable=self.result_var, font=("微软雅黑", 22, "bold"), state='readonly') # 用微软雅黑支持汉字显示 self.result_entry.pack(fill=tk.X, expand=True, padx=20, pady=5) # 状态栏 self.status_var = tk.StringVar(value="请选择图片开始识别(确保Tesseract已安装中文语言包)") status_bar = ttk.Label(self.root, textvariable=self.status_var, anchor=tk.W) status_bar.pack(fill=tk.X) def select_image(self): """选择图片并显示原图""" path = filedialog.askopenfilename( filetypes=[("图片文件", "*.jpg;*.jpeg;*.png;*.bmp")], title="请选择车牌图片" ) if not path: return self.image_path = path self.original_image = cv2.imread(path) if self.original_image is None: messagebox.showerror("错误", "无法加载图片,请选择有效图片!") return self._display_image(self.original_image, self.step_labels[0]) for label in self.step_labels[1:]: label.config(image="") label.image = None self.status_var.set(f"已加载图片: {path.split('/')[-1]}") self.recognize_btn.config(state=tk.NORMAL) self.clear_all(keep_image=True) def start_recognition(self): """开始识别(核心优化:汉字识别相关)""" if self.original_image is None: messagebox.showerror("错误", "请先选择图片!") return self.status_var.set("正在处理图像...") self.root.update_idletasks() try: # 1. 图像预处理(强化汉字轮廓,关键优化!) img = self.original_image.copy() self.gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 优化1:自适应阈值二值化(比固定阈值更适合汉字识别,保留细节) self.blur_image = cv2.GaussianBlur(self.gray_image, (5, 5), 0) # 反相二值化:使汉字(前景)为白色,背景为黑色,符合OCR识别习惯 self.edged_image = cv2.adaptiveThreshold(self.blur_image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, blockSize=15, C=2) # 优化2:形态学操作(膨胀+腐蚀),强化汉字笔画连接,避免断裂 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) self.edged_image = cv2.morphologyEx(self.edged_image, cv2.MORPH_DILATE, kernel, iterations=1) self.edged_image = cv2.morphologyEx(self.edged_image, cv2.MORPH_ERODE, kernel, iterations=1) # 2. 轮廓查找与筛选 contours = cv2.findContours(self.edged_image.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = imutils.grab_contours(contours) contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] # 3. 寻找车牌轮廓(四边形+宽高比) plate_contour = None for c in contours: perimeter = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * perimeter, True) if len(approx) == 4: x, y, w, h = cv2.boundingRect(approx) ar = w / float(h) if 2.5 < ar < 5.0: # 车牌标准宽高比 plate_contour = approx break if plate_contour is None: raise ValueError("未找到符合条件的车牌轮廓,请选择清晰的车牌图片!") # 4. 生成轮廓标记图 self.contour_image = img.copy() cv2.drawContours(self.contour_image, [plate_contour], -1, (0, 255, 0), 3) # 5. 提取车牌区域(扩大边界,避免汉字被截断) mask = np.zeros(self.gray_image.shape, dtype="uint8") cv2.drawContours(mask, [plate_contour], -1, 255, -1) mask = cv2.bitwise_and(self.edged_image, self.edged_image, mask=mask) (x, y) = np.where(mask == 255) if len(x) == 0 or len(y) == 0: raise ValueError("车牌区域无有效特征,请重新选择图片!") (top_x, top_y) = (np.max([0, np.min(x) - 5]), np.max([0, np.min(y) - 5])) (bottom_x, bottom_y) = ( np.min([img.shape[0] - 1, np.max(x) + 5]), np.min([img.shape[1] - 1, np.max(y) + 5])) self.plate_image = img[top_x:bottom_x + 1, top_y:bottom_y + 1] # 6. OCR识别(汉字识别关键配置!) self.status_var.set("正在识别字符(含汉字)...") self.root.update_idletasks() # 优化3:车牌图像预处理(专门针对汉字) plate_gray = cv2.cvtColor(self.plate_image, cv2.COLOR_BGR2GRAY) # 中值滤波去噪(保留汉字边缘,比高斯滤波更适合文字) plate_gray = cv2.medianBlur(plate_gray, 3) # 再次二值化,确保汉字黑白对比强烈 _, plate_binary = cv2.threshold(plate_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 优化4:OCR参数(专为汉字优化) # --oem 1:LSTM引擎(对汉字识别效果远好于默认引擎) # --psm 8:单个词模式(车牌整体是一个词,适合汉字+字母+数字组合) # -l chi_sim:强制使用中文语言包 # tessedit_char_whitelist:只保留车牌可能的字符,减少干扰 custom_config = r'--oem 1 --psm 8 -l chi_sim -c tessedit_char_whitelist=' + CHAR_WHITELIST self.recognition_result = pytesseract.image_to_string(plate_binary, config=custom_config).strip() # 7. 结果后处理(过滤无效字符,确保汉字在前) self.recognition_result = self._optimize_chinese_result(self.recognition_result) # 8. 显示所有步骤和结果 self._display_all_steps() final_result = self.recognition_result if self.recognition_result else "识别失败" self.result_var.set(final_result) self.status_var.set("识别完成!" if self.recognition_result else "识别失败:未匹配到有效车牌") except Exception as e: messagebox.showerror("识别错误", f"错误详情:{str(e)}\n请检查:1.中文语言包是否安装 2.图片是否清晰") self.status_var.set("识别失败!") def _optimize_chinese_result(self, result): """优化汉字识别结果:过滤无效字符,确保省份汉字在前""" if not result: return "" # 仅保留白名单中的字符 filtered = [c for c in result if c in CHAR_WHITELIST] filtered_result = "".join(filtered) # 车牌规则:第一个字符必须是省份汉字,校验并调整 province_chars = "京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领" if filtered_result and filtered_result[0] not in province_chars: # 查找第一个省份汉字的位置并前移 for i, c in enumerate(filtered_result): if c in province_chars: filtered_result = filtered_result[i:] + filtered_result[:i] break return filtered_result def _display_all_steps(self): """显示图像处理的所有步骤(原始图/灰度图/二值化/轮廓图/车牌区域)""" # 示例:将各步骤图像转换为Tkinter可显示的格式(需结合UI组件实现) # 假设self有label组件用于显示各步骤:self.original_label, self.gray_label等 def cv2_to_tk(img): """OpenCV图像转Tkinter PhotoImage""" if len(img.shape) == 2: # 灰度图 img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) else: # BGR转RGB img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = Image.fromarray(img) # 缩放图像适配UI img = img.resize((200, 100), Image.Resampling.LANCZOS) return ImageTk.PhotoImage(img) # 显示各步骤图像 if hasattr(self, "original_label"): self.original_label.config(image=cv2_to_tk(self.original_image)) self.original_label.image = cv2_to_tk(self.original_image) if hasattr(self, "gray_label"): self.gray_label.config(image=cv2_to_tk(self.gray_image)) self.gray_label.image = cv2_to_tk(self.gray_image) if hasattr(self, "edged_label"): self.edged_label.config(image=cv2_to_tk(self.edged_image)) self.edged_label.image = cv2_to_tk(self.edged_image) if hasattr(self, "contour_label"): self.contour_label.config(image=cv2_to_tk(self.contour_image)) self.contour_label.image = cv2_to_tk(self.contour_image) if hasattr(self, "plate_label"): self.plate_label.config(image=cv2_to_tk(self.plate_image)) self.plate_label.image = cv2_to_tk(self.plate_image) def _display_all_steps(self): """显示所有步骤图像""" self._display_image(self.original_image, self.step_labels[0]) self._display_image(self.gray_image, self.step_labels[1], is_gray=True) self._display_image(self.blur_image, self.step_labels[2], is_gray=True) self._display_image(self.edged_image, self.step_labels[3], is_gray=True) self._display_image(self.contour_image, self.step_labels[4]) self._display_image(self.plate_image, self.step_labels[5]) def _display_image(self, img, label, is_gray=False): """图像显示函数(适配汉字显示)""" label_w = label.winfo_width() or 300 label_h = label.winfo_height() or 200 h, w = img.shape[:2] scale = min(label_w / w, label_h / h) new_w, new_h = int(w * scale), int(h * scale) img_resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA) if is_gray or len(img_resized.shape) == 2: img_rgb = cv2.cvtColor(img_resized, cv2.COLOR_GRAY2RGB) else: img_rgb = cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(img_rgb) tk_img = ImageTk.PhotoImage(pil_img) label.config(image=tk_img) label.image = tk_img def clear_all(self, keep_image=False): """清空所有结果""" self.result_var.set("") self.recognition_result = "" self.gray_image = None self.blur_image = None self.edged_image = None self.contour_image = None start_idx = 1 if keep_image else 0 for label in self.step_labels[start_idx:]: label.config(image="") label.image = None if not keep_image: self.image_path = None self.original_image = None self.plate_image = None self.status_var.set("请选择图片开始识别(确保Tesseract已安装中文语言包)") self.recognize_btn.config(state=tk.DISABLED) def main(): # 适配Windows高清屏 try: from ctypes import windll windll.shcore.SetProcessDpiAwareness(1) except: pass root = tk.Tk() app = LicensePlateRecognitionApp(root) root.mainloop() if __name__ == "__main__": main()
11-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值