水果(苹果/番石榴等)目标计数代码修复及通用实现需求
语法错误修复与多水果计数功能实现
一、语法错误修复
原代码存在3处语法问题,修复方案如下:
- 参数注释语法错误
原代码中p1 = 10:这类行混淆了赋值语法与注释,应改为纯注释形式:
# 参数说明 # p1 = 10: 用于计算图像权重的像素范围 # p2 = 10: 用于计算加权平均值 # p3 = 7: 亮度通道的滤镜强度 # p4 = 15: 颜色通道的滤镜强度
- 中文全角引号错误
cv2.imwrite(‘RGB_image.jpg’,rgb_image)和cv2.imwrite(‘H.jpg’,h)中的中文引号需替换为英文半角引号:
cv2.imwrite('RGB_image.jpg', rgb_image) # ... cv2.imwrite('H.jpg', h)
- 多余括号错误
new_image = (cv2.medianBlur(rgb_image,5)多了左括号,修正为:
new_image = cv2.medianBlur(rgb_image, 5)
二、多水果计数功能实现
针对苹果、番石榴、橙子、醋栗、柠檬、番茄,通过设置不同HSV颜色区间区分目标,修改后完整代码如下:
import numpy as np import imutils import cv2 # 定义各水果的HSV颜色区间(可根据样本微调) fruit_ranges = { "苹果": [(0, 100, 100), (10, 255, 255), (160, 100, 100), (180, 255, 255)], # 红色双区间 "番石榴": [(35, 40, 40), (85, 255, 255)], # 绿色区间 "橙子": [(10, 100, 100), (25, 255, 255)], # 橙色区间 "醋栗": [(25, 50, 50), (35, 255, 255)], # 黄绿色区间 "柠檬": [(50, 50, 50), (70, 255, 255)], # 黄色区间 "番茄": [(0, 120, 70), (10, 255, 255), (170, 120, 70), (180, 255, 255)] # 红色双区间 } def count_fruits(image_path, fruit_name): # 读取图像 image = cv2.imread(image_path) if image is None: print(f"无法读取图像: {image_path}") return # 去噪处理 dst = cv2.fastNlMeansDenoisingColored(image, None, 10, 10, 7, 15) # 转RGB并模糊 rgb_image = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB) new_image = cv2.medianBlur(rgb_image, 5) # 转HSV空间 hsv_image = cv2.cvtColor(new_image, cv2.COLOR_RGB2HSV) # 根据水果名称生成掩码 ranges = fruit_ranges[fruit_name] mask = np.zeros(hsv_image.shape[:2], dtype=np.uint8) for i in range(0, len(ranges), 2): lower = np.array(ranges[i], dtype=np.uint8) upper = np.array(ranges[i+1], dtype=np.uint8) temp_mask = cv2.inRange(hsv_image, lower, upper) mask = cv2.bitwise_or(mask, temp_mask) # 形态学优化掩码 kernel = np.ones((5,5), dtype="uint8") bilateral = cv2.bilateralFilter(mask, 9, 75, 75) erosion = cv2.erode(bilateral, kernel, iterations=2) dilation = cv2.dilate(erosion, kernel, iterations=2) # 查找有效轮廓并计数 cnts = cv2.findContours(dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) valid_cnts = [c for c in cnts if cv2.contourArea(c) > 100] # 过滤噪点轮廓 count = len(valid_cnts) # 标记结果并保存 for (i, c) in enumerate(valid_cnts): ((x, y), _) = cv2.minEnclosingCircle(c) cv2.putText(image, f"#{i+1}", (int(x)-10, int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2) cv2.drawContours(image, [c], -1, (0,255,0), 2) cv2.putText(image, f"{fruit_name} 数量: {count}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2) cv2.imwrite(f"{fruit_name}_count_result.jpg", image) cv2.imshow(f"{fruit_name} 计数结果", image) cv2.waitKey(0) cv2.destroyAllWindows() print(f"[INFO] {fruit_name} 数量: {count}") # 示例:处理苹果样本(替换路径和水果名可处理其他样本) count_fruits("49.jpg", "苹果") # 其他调用示例: # count_fruits("guava_sample.jpg", "番石榴") # count_fruits("orange_sample.jpg", "橙子")
关键说明
- HSV区间微调:不同光照、拍摄环境下水果颜色会有差异,可通过OpenCV的HSV调色工具调整区间值,提升掩码准确性。
- 轮廓过滤:通过面积阈值排除噪点干扰,可根据样本大小调整
100这个数值。 - 批量处理:可通过循环遍历你的1-6号苹果样本,或其他水果数据集,实现批量计数。
内容的提问来源于stack exchange,提问作者Manoj Prasad
相关产品推荐
相关产品推荐

