online_proj / function.py
taoyingfan.316
update
9531097
Raw
History Blame Contribute Delete
14.1 kB
# 功能函数
import os
import cv2
import numpy as np
from PIL import Image, ImageFilter
from matplotlib import pyplot as plt
import collections
import colorsys
#定义字典存放颜色分量上下限
#例如:{颜色: [min分量, max分量]}
#{'red': [array([160, 43, 46]), array([179, 255, 255])]}
def getColorList():
dict = collections.defaultdict(list)
# 黑色
lower_black = np.array([0, 0, 0])
upper_black = np.array([180, 255, 46])
color_list = []
color_list.append(lower_black)
color_list.append(upper_black)
dict['black'] = color_list
#灰色
lower_gray = np.array([0, 0, 46])
upper_gray = np.array([180, 43, 220])
color_list = []
color_list.append(lower_gray)
color_list.append(upper_gray)
dict['gray']=color_list
# 白色
lower_white = np.array([0, 0, 221])
upper_white = np.array([180, 30, 255])
color_list = []
color_list.append(lower_white)
color_list.append(upper_white)
dict['white'] = color_list
# 红色1
lower_red = np.array([0, 43, 46])
upper_red = np.array([10, 255, 255])
color_list = []
color_list.append(lower_red)
color_list.append(upper_red)
dict['red'] = color_list
#红色2
lower_red = np.array([156, 43, 46])
upper_red = np.array([180, 255, 255])
color_list = []
color_list.append(lower_red)
color_list.append(upper_red)
dict['red2']=color_list
#橙色
lower_orange = np.array([11, 43, 46])
upper_orange = np.array([25, 255, 255])
color_list = []
color_list.append(lower_orange)
color_list.append(upper_orange)
dict['orange'] = color_list
#黄色
lower_yellow = np.array([26, 43, 46])
upper_yellow = np.array([34, 255, 255])
color_list = []
color_list.append(lower_yellow)
color_list.append(upper_yellow)
dict['yellow'] = color_list
#绿色
lower_green = np.array([35, 43, 46])
upper_green = np.array([77, 255, 255])
color_list = []
color_list.append(lower_green)
color_list.append(upper_green)
dict['green'] = color_list
#青色
lower_cyan = np.array([78, 43, 46])
upper_cyan = np.array([99, 255, 255])
color_list = []
color_list.append(lower_cyan)
color_list.append(upper_cyan)
dict['cyan'] = color_list
#蓝色
lower_blue = np.array([100, 43, 46])
upper_blue = np.array([124, 255, 255])
color_list = []
color_list.append(lower_blue)
color_list.append(upper_blue)
dict['blue'] = color_list
# 紫色
lower_purple = np.array([125, 43, 46])
upper_purple = np.array([155, 255, 255])
color_list = []
color_list.append(lower_purple)
color_list.append(upper_purple)
dict['purple'] = color_list
return dict
# 输入hsv图片得到颜色
def get_color_from_pos(x, y, hsv, color_dict):
assert x >= 0 and x < hsv.shape[1]
assert y >= 0 and y < hsv.shape[0]
point_hsv = hsv[int(y), int(x),:]
h, s, v = point_hsv[0], point_hsv[1], point_hsv[2]
for c in color_dict:
low_rnk, high_rnk = color_dict[c][0], color_dict[c][1]
if h >= low_rnk[0] and h <= high_rnk[0] and s >= low_rnk[1] and s <= high_rnk[1] and v >= low_rnk[2] and v <= high_rnk[2]:
return c, point_hsv
def get_color_from_image(hsv, color_dict):
h, w, _ = hsv.shape
center_hsv = hsv[int(h/2-1), int(w/2-1),:]
h, s, v = center_hsv[0], center_hsv[1], center_hsv[2]
print('source hsv', h, s, v)
for c in color_dict:
low_rnk, high_rnk = color_dict[c][0], color_dict[c][1]
if h >= low_rnk[0] and h <= high_rnk[0] and s >= low_rnk[1] and s <= high_rnk[1] and v >= low_rnk[2] and v <= high_rnk[2]:
return c, center_hsv
def get_color_from_image_2(hsv, color_dict):
hist, bins = np.histogram(hsv[:, :, 0], bins=180, range=(0,180))
hist[0] = 0
for i in range(len(hist)):
if hist[i] == hist.max():
idx = i
break
print(idx)
for c in color_dict:
low_rnk, high_rnk = color_dict[c][0], color_dict[c][1]
if idx >= low_rnk[0] and idx <= high_rnk[0]:
return c, idx
# 输入rgb值得到hsv值
def rgb2hsv(rgb, color_dict):
assert len(rgb) == 3
r, g, b = rgb[0], rgb[1], rgb[2]
hsv = colorsys.rgb_to_hsv(r/255, g/255, b/255)
hsv = np.array(hsv) * np.array([180, 255, 255])
h, s, v = int(hsv[0]), int(hsv[1]), int(hsv[2])
print('target hsv', h, s, v)
for c in color_dict:
low_rnk, high_rnk = color_dict[c][0], color_dict[c][1]
if h >= low_rnk[0] and h <= high_rnk[0] and s >= low_rnk[1] and s <= high_rnk[1] and v >= low_rnk[2] and v <= high_rnk[2]:
return c, hsv
# 判断颜色是否为彩色,黑白灰返回false
def judge_color(color):
if 'black' in color or 'gray' in color or 'white' in color:
return False
else:
return True
# 获得遮罩
def get_mask(color, hsv, color_dict):
if 'red' in color:
mask1 = cv2.inRange(hsv, color_dict['red'][0], color_dict['red'][1])
mask2 = cv2.inRange(hsv, color_dict['red2'][0], color_dict['red2'][1])
mask = mask1 + mask2
else:
mask = cv2.inRange(hsv, color_dict[color][0], color_dict[color][1])
return mask != 0
# 保存mask
def save_mask(path, mask, cnt):
mask[mask!=0] = 255
mask = Image.fromarray(mask).convert('1')
mask_name = os.path.join(path, str(cnt)+'.png')
mask.save(mask_name)
# 获得局部区域的属于color范围的遮罩
def get_region_mask(color, hsv, x1, y1, x, y, color_dict):
if 'red' in color:
mask1 = cv2.inRange(hsv, color_dict['red'][0], color_dict['red'][1])
mask2 = cv2.inRange(hsv, color_dict['red2'][0], color_dict['red2'][1])
mask = mask1 + mask2
else:
mask = cv2.inRange(hsv, color_dict[color][0], color_dict[color][1])
mask = mask != 0
tmp = np.zeros(mask.shape)
tmp[y1:y, x1:x] = mask[y1:y, x1:x]
return tmp != 0
def get_region_mask_rect(color, hsv, x1, y1, x, y, color_dict):
mask = cv2.inRange(hsv, color_dict[color][0], color_dict[color][1])
mask = mask == 0 # 除了这个颜色,其他的都置为True
tmp = np.zeros(mask.shape)
tmp[y1:y, x1:x] = mask[y1:y, x1:x]
return tmp != 0
def get_region_mask_circle(color, hsv, black_back, color_dict):
mask = cv2.inRange(hsv, color_dict[color][0], color_dict[color][1])
mask = mask == 0 # 除了这个颜色,其他的都置为True
black_back = black_back!=0
mask = mask & black_back # 不是这个颜色且在这个区域
return mask
def get_region_mask_remove(color, hsv, white_back, color_dict): # 去除涂抹区域中的目标颜色
white_back = white_back != 0 # 涂抹的区域
return white_back
# 加光照函数 输入rgb 输出rgb
def adding_light(img, light_conf):
rows, cols = img.shape[:2]
cX_list = [0, 0, 0, rows-1, rows-1, rows-1]
cY_list = [0, cols // 2, cols - 1, 0, cols // 2, cols - 1]
radius = min(rows, cols)
strength = light_conf['light_strength']
cX = cX_list[light_conf['light_type']]
cY = cY_list[light_conf['light_type']]
dist = np.zeros((rows, cols))
x = np.arange(0, rows)
dx = np.power((x - cX), 2)
for i in range(cols):
y = np.zeros(rows) + i
dy = np.power((y - cY), 2)
dist[:, i] = dx + dy
R, G, B = img[:, :, 0], img[:, :, 1], img[:, :, 2]
res = strength * (1.0 - np.sqrt(dist) / radius)
mape = dist < radius * radius
R = (R + res) * mape + R * (1 - mape)
G = (G + res) * mape + G * (1 - mape)
B = (B + res) * mape + B * (1 - mape)
R = np.clip(R, 0, 255)
G = np.clip(G, 0, 255)
B = np.clip(B, 0, 255)
res = np.uint8(np.dstack((R, G, B)))
return res
def Sort_map(result):
idx = 0
res = {}
for key in result.keys():
if "best" in key:
res[str(idx)+'.png'] = result[key]
idx += 1
for key in result.keys():
if "best" not in key:
res[str(idx)+'.png'] = result[key]
idx += 1
return res
def get_name(flag_h, flag_s, flag_v):
save_name = ""
if flag_h != None:
save_name += "h_"
save_name += str(int(flag_h[0]))
save_name += "_"
save_name += str(int(flag_h[1]))
save_name += "_"
if flag_s != None:
save_name += "s_"
save_name += str(int(flag_s[0]))
save_name += "_"
save_name += str(int(flag_s[1]))
save_name += "_"
if flag_v != None:
save_name += "v_"
save_name += str(int(flag_v[0]))
save_name += "_"
save_name += str(int(flag_v[1]))
save_name = save_name.strip('_')
return save_name + '.jpg'
def light_map(x, l_rnk, h_rnk):
if x <= l_rnk:
res = 0
elif x >= h_rnk:
res = 255
else:
k = 255 / (h_rnk - l_rnk)
b = -255 * l_rnk / (h_rnk - l_rnk)
res = k * x + b
return int(res)
def curve(hsv, mask, h_rnk, l_rnk):
mask = np.array(mask)
mask = mask > 10
v = hsv[:, :, 2]
v_ = v.copy()
vfunc = np.vectorize(light_map, excluded=['l_rnk', 'h_rnk'])
v_ = vfunc(v_, l_rnk=l_rnk, h_rnk=h_rnk)
hsv[:, :, 2] = v_ * mask + v * (~mask)
return hsv
# 保存结果
def save_result(hsv, alpha, mask_ori, pic_path, light_conf, curve_conf):
if curve_conf['if_curve'] == True:
hsv = curve(hsv=hsv, mask=mask_ori, h_rnk=curve_conf['h_rnk'], l_rnk=curve_conf['l_rnk'])
if alpha == None: # 三通道图片
tag_img = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
#
# tag_img= cv2.GaussianBlur(tag_img, (9, 9), 0)
if light_conf['if_light'] != False:
tag_img = adding_light(tag_img, light_conf)
res = Image.open(pic_path)
res.paste(Image.fromarray(tag_img), mask = mask_ori)
else:
tag_img = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
if light_conf['if_light'] != False:
tag_img = adding_light(tag_img, light_conf)
if mask_ori!= None:
res = Image.open(pic_path)
res.paste(Image.fromarray(tag_img), mask=mask_ori)
r, g, b, _ = res.split()
res = Image.merge('RGBA', (r, g, b, alpha))
else:
r, g, b = Image.fromarray(tag_img[:, :, 0]), Image.fromarray(tag_img[:, :, 1]), Image.fromarray(tag_img[:, :, 2])
res = Image.merge('RGBA', (r, g, b, alpha))
# res.save(save_name)
return res
def mapping(mape, a, l_flag, h_flag, pre_set):
if pre_set != None:
assert len(pre_set) == 2
l_flag = pre_set[0]
h_flag = pre_set[1]
mi = mape[a].min()
mx = mape[a].max()
# 相交
if (l_flag < mx and l_flag > mi) or (h_flag > mi and h_flag < mx):
if mx > h_flag:
if mi >= l_flag: # [mi, h_flag]
mape = (mape - mi) / (mx - mi) * (h_flag - mi) + mi
else: # [l_flag, h_flag]
mape = (mape - mi) / (mx - mi) * (h_flag - l_flag) + l_flag
else:
if mi < l_flag: # [l_flag, mx]
mape = (mape - mi) / (mx - mi) * (mx - l_flag) + l_flag
# 不相交
else:
delta = l_flag - mi
mape = mape + delta
mi = mape[a].min()
mx = mape[a].max()
mape = (mape - mi) / (mx - mi) * (h_flag - l_flag) + l_flag
return mape
def mapping_diff(mape, mask_yes, mask_no, a):
mask1 = a & mask_no # 车漆颜色 并且 不属于这个颜色
mask2 = a & mask_yes # 车漆颜色 并且 属于这个颜色
return
def get_median(mape, mask):
med = np.median(mape[mask])
mask_1_4 = (mape < med) & mask
mask_3_4 = (mape > med) & mask
med_1_4 = np.median(mape[mask_1_4])
med_3_4 = np.median(mape[mask_3_4])
return med_1_4, med_3_4, med
# 汽车转色
def convert_color(hsv, mask, src_hsv, tag_hsv, tag_color, alpha, color_dict, mask_ori, pic_path, flag_s, flag_v, flag_h, light_conf, v_contrast, curve_conf):
h, s, v = hsv[:, :, 0], hsv[:, :, 1], hsv[:, :, 2]
tag_h, tag_s, tag_v = int(tag_hsv[0]), int(tag_hsv[1]), int(tag_hsv[2])
a = mask
b = mask == 0
if 'white' in tag_color and flag_s == None:
flag_s = [0, min(10, tag_s+1)]
clahe = cv2.createCLAHE(clipLimit=v_contrast, tileGridSize=(8,8))
delta_h = tag_hsv[0] - src_hsv[0]
delta_s = tag_hsv[1] - src_hsv[1]
delta_v = tag_hsv[2] - src_hsv[2]
print(f'delta_h: {delta_h}, delta_s: {delta_s}, delta_v: {delta_v}')
h_ = h + delta_h
s_ = s + delta_s
v_ = v + delta_v
print('flag_s:{}, flag_v:{}'.format(flag_s, flag_v))
# 映射到指定的区间
h_ = mapping(h_, a, color_dict[tag_color][0][0], color_dict[tag_color][1][0], flag_h)
s_ = mapping(s_, a, color_dict[tag_color][0][1], color_dict[tag_color][1][1], flag_s)
v_ = mapping(v_, a, color_dict[tag_color][0][2], color_dict[tag_color][1][2], flag_v)
# 变彩色 色调选填
if judge_color(tag_color): # 只调色调, s, v通过设置参数来调整
if v_contrast != 0:
v_1= clahe.apply((v_ * a).astype(np.uint8))
hsv[:, :, 2] = v_1 * a + v * b
else:
hsv[:, :, 2] = v_ * a + v * b
hsv[:, :, 1] = s_ * a + s * b
hsv[:, :, 0] = h_ * a + h * b
res = save_result(hsv, alpha, mask_ori, pic_path, light_conf, curve_conf)
# 变黑白灰
else:
# 黑白灰色调[0,180]不用管
hsv[:, :, 0] = h_ * a + h * b
hsv[:, :, 1] = s_ * a + s * b
if v_contrast != 0:
v_= clahe.apply((v_ * a).astype(np.uint8))
hsv[:, :, 2] = v_ * a + v * b
res = save_result(hsv, alpha, mask_ori, pic_path, light_conf, curve_conf)
return res