改变图像中特定区域的颜色

背景与原理

再训练施工即系模型中,发现大量施工机械都是黄色的,我需要把它们换成蓝色的,以增强模型使用可靠性。

目前没有尝试深度学习算法,只是简单的进行了处理。

核心目的:通过人工标注与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都是黄色的。

实现效果

效果如下图所示,我让机械的“黄色”变成了旁边农用车的“蓝色”:
在这里插入图片描述

实现方法

  1. 辅助函数:

# 在区域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')

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值