背景与原理
再训练施工即系模型中,发现大量施工机械都是黄色的,我需要把它们换成蓝色的,以增强模型使用可靠性。
目前没有尝试深度学习算法,只是简单的进行了处理。
核心目的:通过人工标注与opencv的结合,来把”“黄色吊车”变成“蓝色吊车”。
原理可以概括为以下内容:
1.我会先框选出图片中的区域A和区域B,
2.然后计算出A区域与B区域的平均RGB值的差异D,
3.然后将C区域中所有与A区域颜色相似的像素点,加上差异D,
4.C区域中的颜色A尽可能的变为颜色B
C可以是整个吊车的吊臂,A是C中一小块区域,我需要把C中与A相似的像素点都变成类似于B的颜色。B可以是其他颜色的施工机械上的一块油漆,主要是提供“蓝色”,A和C都是黄色的。
实现效果
效果如下图所示,我让机械的“黄色”变成了旁边农用车的“蓝色”:
实现方法
- 辅助函数:
# 在区域B中随机选择一些颜色
def randomly_select_pixel(top_pixels):
# 从出现次数最多的像素点中随机选择一个
selected_pixel = random.choice(top_pixels)[0]
return selected_pixel
# 计算某个区域的平均rgb值
def calculate_mean_rgb(image, region, num, top_n=10):
# 提取区域
sub_img = image[region[1]:region[3], region[0]:region[2]]
cv2.imwrite(r'C:\Users\28715\Desktop\tmp\{}.png'.format(num), sub_img)
# 计算区域的平均RGB值
mean_rgb = sub_img.mean(axis=(0, 1))
# 将区域展平并转换为元组形式
pixels = [tuple(pixel) for row in sub_img for pixel in row]
# 统计每个像素的出现次数
pixel_counts = Counter(pixels)
# 找出出现次数最多的top_n个像素
most_common_pixels = pixel_counts.most_common(top_n)
return mean_rgb, most_common_pixels
2.变化颜色的核心函数
# 主函数,将C区域中,与A区域中类似的颜色,换成B区域中的颜色
def adjust_color(image, region_c, mean_rgb_a, mean_rgb_b, common_rgb_b, threshold=50, noise_range=1):
diff = mean_rgb_b - mean_rgb_a
sub_img_c = image[region_c[1]:region_c[3], region_c[0]:region_c[2]]
# 计算区域C中每个像素与区域A平均颜色的差异
color_diff = np.linalg.norm(sub_img_c - mean_rgb_a, axis=-1)
# 找到差异小于阈值的像素
mask = color_diff < threshold
# 调整这些像素的颜色
sub_img_c[mask] = randomly_select_pixel(common_rgb_b)
# 确保颜色值在有效范围内 [0, 255]
sub_img_c = np.clip(sub_img_c, 0, 255)
# 替换区域C
image[region_c[1]:region_c[3], region_c[0]:region_c[2]] = sub_img_c
return image
3.使用。你可以想想,一个吊车分为车身,吊臂等部分。标注的时候,你可以把整条吊臂当做"C“,把吊臂上最有代表性的一小块区域"A"标出来,然后再标一下目标颜色的提供者“B”,就可以把整个吊臂都变成类似于B区域的颜色了。我标了三个,效果如开始部分的图片所示。
if __name__ == "__main__":
# 读取图像
image = cv2.imread(r'C:\Users\28715\Desktop\tmp\demo.png')
# 定义区域A, B, C (x1, y1, x2, y2),可以一次性多选几个区域,越细致效果越好。
region_a_list = [(844, 222, 862, 250), (1176, 466, 1196, 470), (645, 185, 650, 195), (1085, 462, 1094, 479)]
region_b = (125, 490, 180, 536)
region_c_list = [(699, 131, 960, 344), (1157, 435, 1283, 511), (570, 88, 700, 296), (1062, 458, 1139, 481)]
for i in range(len(region_a_list)):
# 计算区域A和B的平均RGB值
mean_rgb_a, _ = calculate_mean_rgb(image, region_a_list[i], 111)
mean_rgb_b, common_rgb_b = calculate_mean_rgb(image, region_b, 222)
# 调整区域C中的颜色
adjusted_image = adjust_color(image, region_c_list[i], mean_rgb_a, mean_rgb_b, common_rgb_b)
# 保存结果图像
cv2.imwrite(r'C:\Users\Desktop\tmp\demo_change_color.png', adjusted_image)
image = cv2.imread(r'C:\Users\Desktop\tmp\demo_change_color.png')