import cv2 import numpy as np def is_retina_image(image_path, min_circles=1, debug=False): """ 简单视网膜图片检测: 1. 检查是否存在大致圆形(眼底)结构 2. 检查颜色分布是否偏向红/黄/棕色 """ img = cv2.imread(image_path) if img is None: return False gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.medianBlur(gray, 5) rows = gray.shape[0] # 霍夫圆检测 circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.2, minDist=rows/8, param1=50, param2=30, minRadius=int(rows*0.3), maxRadius=int(rows*0.48)) has_circle = circles is not None and len(circles[0]) >= min_circles # 颜色分布检测 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 视网膜常见色调范围(红/橙/黄/棕) mask1 = cv2.inRange(hsv, (5, 30, 30), (25, 255, 255)) # 橙黄 mask2 = cv2.inRange(hsv, (0, 30, 30), (10, 255, 255)) # 红 mask = cv2.bitwise_or(mask1, mask2) color_ratio = np.sum(mask > 0) / (img.shape[0] * img.shape[1]) if debug: print(f"has_circle: {has_circle}, color_ratio: {color_ratio:.2f}") # 经验阈值:有圆且色块比例>0.2 return has_circle and color_ratio > 0.2 def is_retina_image_fast(img_array, min_circles=1): """ 快速视网膜检测版本,直接使用numpy数组,避免重复读取文件 """ if img_array is None: return False # 转换为灰度图 if len(img_array.shape) == 3: gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY) else: gray = img_array gray = cv2.medianBlur(gray, 5) rows = gray.shape[0] # 霍夫圆检测 - 使用更宽松的参数以加快检测 circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.5, minDist=rows/6, param1=40, param2=25, minRadius=int(rows*0.25), maxRadius=int(rows*0.55)) has_circle = circles is not None and len(circles[0]) >= min_circles # 快速颜色检测 - 只检查红色通道 if len(img_array.shape) == 3: # 转换为HSV进行颜色检测 hsv = cv2.cvtColor(img_array, cv2.COLOR_RGB2HSV) # 视网膜常见色调范围(红/橙/黄/棕) mask1 = cv2.inRange(hsv, (5, 20, 20), (25, 255, 255)) # 橙黄 mask2 = cv2.inRange(hsv, (0, 20, 20), (10, 255, 255)) # 红 mask = cv2.bitwise_or(mask1, mask2) color_ratio = np.sum(mask > 0) / (img_array.shape[0] * img_array.shape[1]) else: color_ratio = 0.5 # 灰度图默认通过颜色检测 # 经验阈值:有圆且色块比例>0.15(稍微降低阈值以加快检测) return has_circle and color_ratio > 0.15