首页 > 分享 > 基于OpenCV进行图片主要颜色识别

基于OpenCV进行图片主要颜色识别

0、前言

        对于一张非纯色的图片,如果想要识别其颜色,可能没法直接识别。本文提供了一种利用颜色直方图来识别主要颜色的方法。

1、基础知识

        本文采用的方法适用于对象主体颜色占总区域面积比例较大的情况,不适合哪些颜色较为分散、杂乱的情况。

        基本步骤步骤如下:

图像crop, 降低周围背景的影响;统计H、S、V三个分量的直方图;分别取H、S、V的主要成分,判断落在哪种颜色区间内;

        本文主要参考的颜色区间见表:

黑灰白红橙黄绿青蓝紫hmin000015611263578100125hmax180180180101802534;7799124155smin00043434343434343smax2554330255255255255255255255vmin04622146464646464646vmax46220255255255255255255255255

2、实现代码

        颜色识别分类器代码如下:

import cv2

import numpy as np

class ColorClassify(object):

def __init__(self, debug=True):

self.debug = debug

self.hsv_color = {

"Black": [(0, 180), (0, 255), (0, 46)],

"Gray": [(0, 180), (0, 43), (46, 150)],

"White": [(0, 180), (0, 30), (151, 255)],

"Red": [[(0, 10), (156, 180)], (43, 255), (46, 255)],

"Orange": [(11, 25), (43, 255), (46, 255)],

"Yellow": [(26, 34), (43, 255), (46, 255)],

"Green": [(35, 77), (43, 255), (46, 255)],

"CyanBlue": [(78, 99), (43, 255), (46, 255)],

"Blue": [(100, 124), (43, 255), (46, 255)],

"Purple": [(125, 155), (43, 255), (46, 255)],

}

def get_hsv_hist(self, img_hsv):

h, s, v = img_hsv[:, :, 0], img_hsv[:, :, 1], img_hsv[:, :, 2]

h_bins = [0, 11, 26, 35, 78, 100, 125, 156, 180]

h_hist = np.histogram(h, h_bins)

s_bins = [0, 30, 43, 255]

s_hist = np.histogram(s, s_bins)

v_bins = [0, 46, 151, 255]

v_hist = np.histogram(v, v_bins)

return [h_hist, s_hist, v_hist]

def get_hsv_info(self, h_hist, s_hist, v_hist):

infos = {

"h": {

"hist": h_hist,

"argsort": None,

"sort_normal": None,

"arg_values": [],

},

"s": {

"hist": s_hist,

"argsort": None,

"sort_normal": None,

"arg_values": [],

},

"v": {

"hist": v_hist,

"argsort": None,

"sort_normal": None,

"arg_values": [],

}

}

for k in infos:

hist = infos[k]['hist']

argsort = np.argsort(hist[0])[::-1][:2]

infos[k]['argsort'] = argsort

infos[k]['sort_normal'] = hist[0][argsort] / (sum(hist[0]) * 3)

for idx in argsort:

value_mean = round(np.mean([hist[1][idx], hist[1][idx + 1]]))

infos[k]['arg_values'].append(value_mean)

return infos

def get_hsv_main_info(self, h_hist, s_hist, v_hist):

h_main_idx = np.argmax(h_hist[0])

h_main = [h_hist[1][h_main_idx], h_hist[1][h_main_idx + 1]]

s_weights = np.array([1, 1, 1])

s_array = s_hist[0] * s_weights

s_main_idx = np.argmax(s_array)

s_main = [s_hist[1][s_main_idx], s_hist[1][s_main_idx + 1]]

v_weights = np.array([1, 1, 1])

v_array = v_hist[0] * v_weights

v_main_idx = np.argmax(v_array)

v_main = [v_hist[1][v_main_idx], v_hist[1][v_main_idx + 1]]

if self.debug:

print("h_hist: {}ns_hist: {}nv_hist: {}".format(h_hist, s_hist, v_hist))

print("h_main: {}, s_main: {}, v_main: {}".format(h_main, s_main, v_main))

return np.mean(h_main), np.mean(s_main), np.mean(v_main)

def hsv2color(self, infos):

h_info = infos['h']

s_info = infos['s']

v_info = infos['v']

result = {}

for snh, avh in zip(h_info['sort_normal'], h_info['arg_values']):

for sns, avs in zip(s_info['sort_normal'], s_info['arg_values']):

for snv, avv in zip(v_info['sort_normal'], v_info['arg_values']):

cls = self.hsv2color_one(avh, avs, avv)

if cls is None:

print(avh, avs, avv)

continue

score = snh + sns + snv

if cls in result.keys():

result[cls] = max(score, result[cls])

else:

result[cls] = score

print(result)

return sorted(result.items(), key=lambda kv: (kv[1], kv[0]))[::-1]

def hsv2color_one(self, h_mean, s_mean, v_mean):

for cls, value in self.hsv_color.items():

if isinstance(value[0], list):

h_flag = value[0][0][0] <= h_mean <= value[0][0][1] or value[0][1][0] <= h_mean <= value[0][1][1]

else:

h_flag = value[0][0] <= h_mean <= value[0][1]

s_flag = value[1][0] <= s_mean <= value[1][1]

v_flag = value[2][0] <= v_mean <= value[2][1]

if h_flag and s_flag and v_flag:

return cls

return None

def classify(self, img):

img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

h_hist, s_hist, v_hist = self.get_hsv_hist(img_hsv)

infos = self.get_hsv_info(h_hist, s_hist, v_hist)

return self.hsv2color(infos)

用法也很简单,先实例化一个分类器,然后调用classify传入图片即可得到颜色类别:

classifier = ColorClassify(debug=True)

img = cv2.imread(img_path)

result = classifier.classify(img)

cls, score = result[0]

参考:

HSV颜色模型_百度百科

HSV基本颜色分量范围 - 百度文库

色域值各个标准对照表 - 百度文库

相关知识

利用OpenCV根据图片识别环境的亮度
深入浅出:利用OpenCV实现手写数字识别之旅
基于OpenCV的鲜花的图像分类系统详细设计与具体代码实现
基于深度学习YOLOv8\YOLOv5的花卉识别鲜花识别检测分类系统设计
基于机器视觉的昆虫种类及计数检测研究
基于机器视觉的害虫种类及计数检测研究
python 手写字识别
基于Python机器视觉的远程害虫种类识别和数量检测系统 报告+项目源码及数据
opencv深度学习昆虫识别系统图像识别 python
基于深度学习的yolov7植物病虫害识别及防治系统

网址: 基于OpenCV进行图片主要颜色识别 https://m.huajiangbk.com/newsview1094011.html

所属分类:花卉
上一篇: python+opencv实现文
下一篇: openMV