当前位置:   article > 正文

2023年亚太杯A题:果园采摘机器人的图像识别,一二题(题目代码及结果)

2023年亚太杯A题:果园采摘机器人的图像识别,一二题(题目代码及结果)

问题一:基于附件1中提供的可收获苹果的图像数据集,提取图像特征,建立数学模型,计算每幅图像中的苹果的数量,并绘制附件1中所有苹果的分布直方图。

对于自动采摘机器人,首要的能力就是识别出苹果对象,因此如何从画面(图像)中准确的识别出苹果对象对于自动采摘机器人有重要影响。附件1给出了200张有苹果对象的图像,要计算出每个图像中苹果的数量,并分析附件1中苹果的数量分布。考虑从颜色空间(HSV,Hue Saturation Value),通过对不同色调、明度和饱和度的识别,结合轮廓检测对苹果与周围环境做出识别,并进行计数。

  1. import os
  2. import cv2
  3. import numpy as np
  4. # 图片文件夹路径
  5. folder_path = 'D:/math_model/2023yatai/Attachment/Attachment 1'
  6. image_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
  7. count = []
  8. for file in image_files:
  9. # 读取图片
  10. image_path = os.path.join(folder_path, file)
  11. img = cv2.imread(image_path)
  12. # 将图片变为灰度图片
  13. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  14. # 进行腐蚀膨胀操作
  15. kernel = np.ones((2, 2), np.uint8)
  16. erosion = cv2.erode(gray, kernel, iterations=5) # 腐蚀
  17. dilation = cv2.dilate(erosion, kernel, iterations=5) # 膨胀
  18. # 颜色阈值化提取红色区域
  19. lower_red = np.array([20, 0, 100])
  20. upper_red = np.array([80, 100, 255])
  21. mask = cv2.inRange(img, lower_red, upper_red)
  22. '''
  23. # 定义红色苹果的HSV范围
  24. lower_red = np.array([0, 50, 50])
  25. upper_red = np.array([10, 255, 255])
  26. mask_red = cv2.inRange(img, lower_red, upper_red)
  27. # 定义青色苹果的HSV范围
  28. lower_green = np.array([35, 50, 50])
  29. upper_green = np.array([85, 255, 255])
  30. mask_green = cv2.inRange(img, lower_green, upper_green)
  31. # 合并红色和青色苹果的掩码
  32. mask = cv2.bitwise_or(mask_red, mask_green)
  33. '''
  34. # 找出红色区域的轮廓
  35. contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  36. # 建立空数组,放减去最小面积的连通域
  37. contours_filtered = []
  38. # 设定面积阈值
  39. mianji = []
  40. for contour in contours:
  41. area = cv2.contourArea(contour)
  42. mianji.append(area)
  43. '''
  44. mianji = [x for i, x in enumerate(mianji) if x not in mianji[:i]] #去重
  45. #mianji = list(filter(lambda x: x != 0, mianji)) #删去0
  46. #mianji = [x for x in mianji if x >= 30]
  47. mianji = sorted(mianji)
  48. min_area = np.median(mianji)
  49. '''
  50. min_area = np.max(mianji)/80
  51. # 过滤面积太小的连通域
  52. for contour in contours:
  53. area = cv2.contourArea(contour)
  54. if area > min_area:
  55. contours_filtered.append(contour)
  56. # 绘制红色区域的轮廓并计数
  57. cv2.drawContours(img, contours_filtered, -1, (0, 0, 255), 1)
  58. apple_count = len(contours_filtered)
  59. if apple_count > 100:
  60. apple_count = apple_count*0.7
  61. count.append(apple_count)
  62. count_all = np.sum(count)
  63. import matplotlib.pyplot as plt
  64. plt.hist(count, bins=30, density=True, alpha=0.5,
  65. histtype='stepfilled', color='steelblue',
  66. edgecolor='none')
  67. plt.title('Histogram of apple count distribution')
  68. plt.xlabel('Number of apples')
  69. plt.ylabel('Frequency')
  70. # 显示数值(除了0)
  71. n, bins, patches = plt.hist(count, bins=30, color='skyblue', edgecolor='black', alpha=0.7)
  72. for i in range(len(patches)):
  73. if n[i] != 0:
  74. plt.text(patches[i].get_x() + patches[i].get_width() / 2, patches[i].get_height(),
  75. str(int(n[i])), ha='center', va='bottom')
  76. #plt.savefig('D:/math_model/2023yatai/图/Histogram of apple count distribution.png', dpi = 600) #保存图片
  77. plt.show()

700cdc310067481f801372c8c932f2c3.png

  1. #%% 拼接几个图展示
  2. def imge_single(i):
  3. ii = str(i)
  4. img = cv2.imread(r'D:/math_model/2023yatai/Attachment/Attachment 1/' + ii +'.jpg', 1) # 读取图片
  5. # 将图片变为灰度图片
  6. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  7. # 进行腐蚀膨胀操作
  8. kernel = np.ones((2, 2), np.uint8)
  9. erosion = cv2.erode(gray, kernel, iterations=5) # 腐蚀
  10. dilation = cv2.dilate(erosion, kernel, iterations=5) # 膨胀
  11. lower_red = np.array([20, 0, 100])
  12. upper_red = np.array([80, 100, 255])
  13. mask = cv2.inRange(img, lower_red, upper_red)
  14. contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  15. contours_filtered = []
  16. mianji = []
  17. for contour in contours:
  18. area = cv2.contourArea(contour)
  19. mianji.append(area)
  20. min_area = np.max(mianji)/80
  21. cv2.contourArea
  22. for contour in contours:
  23. area = cv2.contourArea(contour)
  24. if area > min_area:
  25. contours_filtered.append(contour)
  26. # 绘制红色区域的轮廓并计数
  27. cv2.drawContours(img, contours_filtered, -1, (0, 0, 255), 1)
  28. apple_count = len(contours_filtered)
  29. # 在图像上显示苹果数量
  30. cv2.putText(img, f"Apple Count: {apple_count}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (225, 25, 25), 2)
  31. plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 将BGR图像转换为RGB格式
  32. plt.axis('off') # 不显示坐标轴
  33. plt.figure()
  34. plt.tight_layout()
  35. plt.subplots_adjust(left=None, bottom=None, right=None, top=None, \
  36. wspace=0.0005, hspace=0.1)
  37. plt.subplot(2,2,1)
  38. imge_single(55)
  39. plt.subplot(2,2,2)
  40. imge_single(2)
  41. plt.subplot(2,2,3)
  42. imge_single(7)
  43. plt.subplot(2,2,4)
  44. imge_single(11)
  45. #plt.savefig('D:/math_model/2023yatai/图/苹果拼图', dpi=500, bbox_inches='tight') # 保存为JPEG格式,设置dpi和bbox_inches参数
  46. plt.show()

52b8c599913c4f18be91c090dbebcb50.png

问题二:根据附件1中提供的可收获苹果的图像数据集,以图像的左下角为坐标原点,确定每个图像中苹果的位置,并绘制附件1中所有苹果的几何坐标的二维散点图。

对于前方的苹果,人类可以通过感觉精准分摘取,但机器人没有感官,它只能通过数字定位去获取苹果的位置。因此,识别图像中每个苹果的位置,并以图像左下角为原点,精准地给出苹果的坐标就很有必要。考虑在问题一的基础上,针对问题一已经找到的苹果,输出其中心点的位置坐标。苹果位置的分布规律在散点图中并不明显。从图中只可以看出四周的苹果分布会少一些,具体哪一个位置分布最广并不清晰。所以考虑使用热力图呈现图像中的苹果位置分布规律。

  1. import os
  2. import cv2
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. # 图片文件夹路径
  6. folder_path = 'D:/math_model/2023yatai/Attachment/Attachment 1'
  7. image_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
  8. all_apple_positions = []
  9. for file in image_files:
  10. # 读取图片
  11. image_path = os.path.join(folder_path, file)
  12. img = cv2.imread(image_path)
  13. # 将图片变为灰度图片
  14. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  15. # 进行腐蚀膨胀操作
  16. kernel = np.ones((2, 2), np.uint8)
  17. erosion = cv2.erode(gray, kernel, iterations=5) # 腐蚀
  18. dilation = cv2.dilate(erosion, kernel, iterations=5) # 膨胀
  19. # 颜色阈值化提取红色区域
  20. lower_red = np.array([20, 0, 100])
  21. upper_red = np.array([80, 100, 255])
  22. mask = cv2.inRange(img, lower_red, upper_red)
  23. # 找出红色区域的轮廓
  24. contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  25. # 建立空数组,放减去最小面积的连通域
  26. contours_filtered = []
  27. # 设定面积阈值
  28. mianji = []
  29. for contour in contours:
  30. area = cv2.contourArea(contour)
  31. mianji.append(area)
  32. '''
  33. mianji = [x for i, x in enumerate(mianji) if x not in mianji[:i]] # 去重
  34. mianji = list(filter(lambda x: x != 0, mianji)) # 删去0
  35. mianji = sorted(mianji)
  36. min_area = np.median(mianji)
  37. '''
  38. min_area = np.max(mianji)/80
  39. # 过滤面积太小的连通域,并绘制红色区域的轮廓
  40. for contour in contours:
  41. area = cv2.contourArea(contour)
  42. if area > min_area:
  43. contours_filtered.append(contour)
  44. # 计算中心点位置
  45. M = cv2.moments(contour)
  46. if M["m00"] != 0:
  47. center_x = int(M["m10"] / M["m00"])
  48. center_y = int(M["m01"] / M["m00"])
  49. all_apple_positions.append((center_x, center_y))
  50. # 绘制所有苹果位置的二维散点图
  51. x_coords, y_coords = zip(*all_apple_positions)
  52. plt.scatter(x_coords, y_coords)
  53. plt.xlabel('Horizontal position')
  54. plt.ylabel('Vertical position')
  55. plt.title('Apple location scatterplot')
  56. #plt.savefig('D:/math_model/2023yatai/图/散点图(不建模-备用).png', dpi = 600)
  57. plt.show()
  58. import seaborn as sns
  59. # 绘制散点图热力图
  60. plt.figure(figsize=(10, 6))
  61. sns.kdeplot(x=x_coords, y=y_coords, cmap="Reds", fill=True, bw_adjust=0.5)
  62. plt.title('Heat map of the geometric coordinates of all apples', fontsize = 16)
  63. plt.xlabel('Horizontal position', fontsize = 14)
  64. plt.ylabel('Vertical position', fontsize = 14)
  65. plt.gca().invert_yaxis()
  66. #plt.savefig('D:/math_model/2023yatai/图/散点热力图.png', dpi = 600)
  67. plt.show()

a39cc1ff8d8d465e93e4ab8dec490807.png8eec7e4a78214fcbb94bde947124a136.png

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号