当前位置:   article > 正文

Robocom预选赛使用opencv实现颜色主色调识别(源码python+解析)_robocom编程

robocom编程

1.前言:

要求:编程实现对图片中具体内容的颜色识别。编程语言:C++或python。判断图片的主色调是红色还是蓝色。 基础数据:组委会提供200张以上的图片作为识别训练集,比赛的200 张图片另外提供。 比赛要求:编写代码,从200张图片中随机读取20张图片,在终端中以 文字形式输出以上20张图片的主色调是红色还是蓝色。

 

2.源代码

  1. import numpy as np
  2. import cv2 as cv
  3. import math
  4. import random
  5. from PIL import Image, ImageDraw, ImageFont
  6. colors = {'黑色': [0, 180, 0, 255, 0, 46],
  7. '灰色': [0, 180, 0, 43, 46, 220],
  8. '白色': [0, 180, 0, 30, 221, 255],
  9. '红色': [0, 10, 35, 255, 46, 255],
  10. '橙色': [11, 25, 43, 255, 46, 255],
  11. '黄色': [26, 34, 43, 255, 46, 255],
  12. '绿色': [35, 77, 43, 255, 46, 255],
  13. '青色': [78, 99, 43, 255, 46, 255],
  14. '蓝色': [100, 124, 43, 255, 46, 255],
  15. '紫色': [125, 155, 43, 255, 46, 255]
  16. }
  17. color = ['黑色', '灰色', '白色', '红色', '橙色', '黄色', '绿色', '青色', '蓝色', '紫色']
  18. def cv2ImgAddText(img, text, left, top, textColor=(0, 0, 0), textSize=0):
  19. if (isinstance(img, np.ndarray)): # 判断是否OpenCV图片类型
  20. img = Image.fromarray(cv.cvtColor(img, cv.COLOR_BGR2RGB))
  21. draw = ImageDraw.Draw(img)
  22. return cv.cvtColor(np.asarray(img), cv.COLOR_RGB2BGR)
  23. # RGB颜色空间转HSV颜色空间
  24. def simple_rgb2hsv(r, g, b):
  25. r, g, b = r / 255.0, g / 255.0, b / 255.0
  26. mx = max(r, g, b)
  27. mn = min(r, g, b)
  28. df = mx - mn
  29. if mx == mn:
  30. h = 0
  31. elif mx == r:
  32. h = (60/360) * (((g - b) / df) % 6)
  33. elif mx == g:
  34. h = (60/360) * ((b - r) / df + 2)
  35. elif mx == b:
  36. h = (60/360) * ((r - g) / df+4)
  37. if mx == 0:
  38. s = 0
  39. else:
  40. s = df / mx
  41. v = mx
  42. h, s, v = math.ceil(h*180), math.ceil(s*255), math.ceil(v*255)
  43. print(f'h:{h}, s:{s}, v:{v}')
  44. i = 0
  45. for value in colors.values():
  46. if ((h >= 156) & (h <= 180)) & ((s >= 43) & (s <= 255)) & ((v >= 46) & (v <= 255)):
  47. return "红色"
  48. elif ((h >= value[0]) & (h <= value[1])) & ((s >= value[2]) & (s <= value[3])) & ((v >= value[4]) & (v <= value[5])):
  49. return color[i]
  50. i += 1
  51. # 构建图像数据
  52. # K-means 只能处理向量形状的数据,不能处理矩阵型数据,
  53. # 这里 reshape(-1, 3) 代表图片的所有像素点,而每个像素点有三个特征(即三个通道)
  54. def k_means(image):
  55. data = image.reshape((-1, 3))
  56. data = np.float32(data)
  57. # K-means 算法停止条件
  58. # 一个元组,传入 cv.kmeans(),( type, max_iter, epsilon ) type 见下面链接,max_iter 是最大迭代次数,epsilon 要达到的精度
  59. # https://docs.opencv.org/master/d1/d5c/tutorial_py_kmeans_opencv.html
  60. criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
  61. num_clusters = 2 # 聚类的数量
  62. ret, label, center = cv.kmeans(data, num_clusters, None, criteria, 10, cv.KMEANS_RANDOM_CENTERS)
  63. # 求取所聚类的最大概率的值
  64. clusters = np.zeros([num_clusters], dtype=np.int32)
  65. for i in range(len(label)):
  66. clusters[label[i][0]] += 1 # 计算每个类别共有多少个
  67. clusters = np.float32(clusters) / float(h * w) # 计算概率
  68. print(clusters)
  69. max_data = max(clusters)
  70. print(max_data)
  71. max_num = clusters.tolist().index(max_data)
  72. print(max_num)
  73. # center = np.int32(center) # 因为像素值是 0-255 故对其聚类中心进行强制类型转换
  74. center = np.uint8(center) # 因为像素值是 0-255 故对其聚类中心进行强制类型转换
  75. print('this is center', center)
  76. # sorted(clusters) # 这里对主色按比例从大到小排序 [::-1] 代表首尾反转 如[1,2,3] -> [3, 2, 1]
  77. b = center[max_num][0] # 这一类对应的中心,即 RGB 三个通道的值
  78. g = center[max_num][1]
  79. r = center[max_num][2]
  80. print(f'r:{r}, g:{g}, b:{b}')
  81. main_color = simple_rgb2hsv(r, g, b)
  82. print(main_color + '\n')
  83. return main_color
  84. if __name__ == '__main__':
  85. for i in range(20):
  86. num = random.randint(1, 200)
  87. if num < 10:
  88. num_data = '00' + str(num)
  89. elif num < 100 and num >= 10:
  90. num_data = '0' + str(num)
  91. else:
  92. num_data = str(num)
  93. print(f'第{num_data}张图')
  94. # num_data = '190'
  95. image = cv.imdecode(np.fromfile(f'mydata/平安城市测试集/颜色识别任务1/{num_data}.jpg', dtype=np.uint8), -1)
  96. # image = cv.resize(image,None,fx=1,fy=1,interpolation=cv.INTER_LINEAR)
  97. image = cv.resize(image,(600,600))
  98. h, w, ch = image.shape # 读取图像的高、宽、通道数
  99. print(f'图像的高、宽、通道数:{image.shape}')
  100. image = cv2ImgAddText(image, k_means(image), 0, 0, (0, 255, 0), 50)
  101. cv.imshow(f'{i}', image)
  102. cv.waitKey(0)
  103. cv.destroyAllWindows()

3.总结

以上就是我所运用的代码,感谢大家观看,希望有帮助到大家。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/617075
推荐阅读
相关标签
  

闽ICP备14008679号