颜色直方图概念
颜色直方图是在许多图像检索系统中被广泛采用的颜色特征。它所描述的是不同色彩在整幅图像中所占的比例,而并不关心每种色彩所处的空间位置,即无法描述图像中的对象或物体。颜色直方图特别适于描述那些难以进行自动分割的图像。
环境
下面的代码涉及两个库scipy、matplotlib,我当前的环境是树莓派4b-python2.7
1、pip2 install scipy 如果有问题,可以试试sudo apt-get install python-scipy
2、安装matplotlib耗时较长,注意版本pip2 install matplotlib==2.0.2
3、若出现TypeError: Couldn’t find foreign struct converter for ‘cairo.Context’,且图标不正常,则缺少依赖 sudo apt-get install python-gi-cairo
import cv2
import numpy as np
from scipy.misc import imresize
from matplotlib import pyplot as plt
img=cv2.imread('test5.jpg',0)
img=imresize(img,(240,320))
#直方图计算函数, 通道0,没有使用掩膜
/**
imaes:输入的图像
chanels:
用于计算直方图的通道,使用灰度图计算直方图,所以就直接使用第一个
通道;对于彩色可以通过[0],[1],[2]分别计算蓝色、绿色或红色通道的直方图
mask:
如果计算完整图像的直方图,它将设为None。但是如果想找到图像特定区域的直
方图,则必须为它创建一个蒙版图像作为蒙版。
histSize:
表示这个直方图分成多少份(即多少个直方柱)。对于满量程,设置为[256]
ranges:
表示直方图中各个像素的值,通常设为[0,256]
返回值:
hist是一个shape为(256,1)的数组,表示0-255每个像素值对应的像素个
数,下标即为相应的像素值
*/
hist=cv2.calcHist([img],[0],None,[256],[0,256])
//取最大值的下标
hist_max=np.where(hist==np.max(hist))
print(hist_max[0])
cv2.imshow('image',img)
plt.plot(hist)
plt.xlim([0,256])
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
这里通道为0 展示的是图像颜色出现的频数
看一下不同颜色分布的情况
import cv2
import numpy as np
from scipy.misc import imresize
from matplotlib import pyplot as plt
img = cv2.imread('test5.jpg')
color = ['b', 'g', 'r']
for i, col in enumerate(color):
histr = cv2.calcHist([img], [i], None, [256], [1, 256])
plt.plot(histr, color=col, label=col)
plt.legend()
plt.show()
好了,玩到这已经能知道一幅图上颜色的大体分布了,如果想知道图上某个位置具体的颜色则学习下面的代码
具体位置识别颜色
H: 0 — 180 色调
S: 0 — 255 饱和度
V: 0 — 255 亮度
根据表格数据,我们只需要获取某个位置H (色调)就能判断出具体颜色了
import cv2
import numpy as np
from matplotlib import pyplot as plt
def color_hist(img):
//按img的大小240,320 创建遮罩
mask=np.zeros(img.shape[:2],dtype=np.uint8)
mask[70:170,100:220]=255
//色彩空间转换
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
//色调H在蒙版中的频数,按照遮罩范围去计算,这里H取值范围0~180
hist_mask=cv2.calcHist([hsv],[0],mask,[180],[0,180])
//取最大下标
object_H=np.where(hist_mask==np.max(hist_mask))
print(object_H[0])
return object_H[0]
//plt.plot(hist_mask)
//plt.xlim([0,180])
//plt.imshow(hist_mask,interplation='nearest')
//plt.show()
def color_distinguish(object_H):
try:
if object_H>26 and object_H<34: color='yellow'
elif object_H>156 and object_H<180 : color='red'
elif object_H>100 and object_H<124: color ='blue'
elif object_H>35 and object_H<77 : color ='green'
elif object_H>78 and object_H<99:color ='cyan-blue'
elif object_H>6 and object_H<15: color ='orange'
else: color='None'
print(color)
return color
except:pass
if __name__=='__main__':
//全为1的数组,创建图片,大小为240高,320宽,3为通道 *255为白色
img=np.ones((240,320,3),dtype=np.uint8)*255
//(y1=60,y2=180)(x1=80,x2=240)=(y,x) 两点之间赋值为黄色
img[60:180,80:240]=[0,255,255]
//提取色调值
object_H=color_hist(img)
//色调取来后....
color_distinguish(object_H)
cv2.imshow('image',img)
cv2.waitKey(0)