Spaces:
Sleeping
Sleeping
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 | |