根据hsv分量模型,各种颜色范围分布如下:
红色的范围是:[0, 43, 46]~[10,255,255]∪[156, 43, 46]~[180,255,255]。
红色比较特殊,覆盖了多个范围,处理起来增加了不少难度,以下介绍两种方法去获取红色。
方法1:
import cv2
import numpy as np
def extract_red(pic):
''''method1:使用inRange方法,拼接mask0,mask1'''
img = cv2.imdecode(np.fromfile(pic, dtype=np.uint8), -1)
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
rows, cols, channels = img.shape
# 区间1
lower_red = np.array([0, 43, 46])
upper_red = np.array([10, 255, 255])
mask0 = cv2.inRange(img_hsv,lower_red,upper_red)
# 区间2
lower_red = np.array([156, 43, 46])
upper_red = np.array([180, 255, 255])
mask1 = cv2.inRange(img_hsv,lower_red,upper_red)
# 拼接两个区间
mask = mask0 + mask1
# 保存图片
cv2.imencode('.png', mask )[1].tofile(pic)
方法2:
from PIL import Image
def rgb2hsv(r, g, b):
'''rgb转hsv'''
r, g, b = r/255.0, g/255.0, b/255.0
mx = max(r, g, b)
mn = min(r, g, b)
df = mx-mn
if mx == mn:
h = 0
elif mx == r:
h = (60 * ((g-b)/df) + 360) % 360
elif mx == g:
h = (60 * ((b-r)/df) + 120) % 360
elif mx == b:
h = (60 * ((r-g)/df) + 240) % 360
if mx == 0:
s = 0
else:
s = df/mx
v = mx
H = h / 2
S = s * 255.0
V = v * 255.0
return H, S, V
def extract_red(fname):
'''method2:遍历图片像素,把像素转化成hsv,根据hsv筛选出红色'''
im = Image.open(fname)
## 懒加载模式
pix = im.load()
width = im.size[0]
height = im.size[1]
for x in range(width):
for y in range(height):
r, g, b = pix[x, y]
h,s,v = rgb2hsv(r,g,b)
if 0 < h < 10 or 156 < h < 180:
pix[x, y] = 0,0,0
else:
pix[x, y] = 255,255,255
im.save(fname)