本次实验要求将模拟飞行座舱图像中的HUD绿色字体去掉,并且用白色来替代,最终输出没有绿色字体的图片,用于下一步的某种图像算法的输入。
将一张图片中的某个颜色去除,现在主流的做法就是通过建立一个HSV空间范围φ
,在该范围内建立一个掩膜mask
,与原始图像进行对比,只要原始图像像素点范围满足该HSV空间范围的,则直接用白色rgb(255,255,255)
来替代。
这里有个问题是,如何确定整个HSV空间范围φ
,你可以自己直接赋值(能准确肉眼给出来的,都是神仙),一般人应该还是会通过某种“连续调节装置”首先来确定HSV取值范围,然后再进一步去做去除、替代操作。
import cv2
import numpy as np
import time
def color_cut(input_path, output_path, ymin, ymax, xmin, xmax, low_hsv, high_hsv):
img = cv2.imread(input_path, 1)
img_background = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
# # 背景图改成白色
# img_background_white = img_background
# img_background_white[0: img.shape[0]-1, 0: img.shape[1]-1] = 255
# ######################将绿色区域单独提取出来绘制在一张图上##################
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
roi = hsv_img[ymin:ymax, xmin:xmax]
mask = cv2.inRange(roi, low_hsv, high_hsv)
red = cv2.bitwise_and(roi, roi, mask=mask)
bgr_red = cv2.cvtColor(red, cv2.COLOR_HSV2BGR)
# 背景设置为白色
# black_pixels = np.where((bgr_red[:, :, 0] == 0) & (bgr_red[:, :, 1] == 0) & (bgr_red[:, :, 2] == 0))
# bgr_red[black_pixels] = [255, 255, 255]
# 将roi区域叠加至黑色背景中去
img_result = img_background
img_result[ymin:ymax, xmin:xmax] = bgr_red
cv2.imwrite(output_path, img_result)
# 原图resize
img2 = cv2.resize(img, (800, 600), interpolation=cv2.INTER_AREA)
# cv2.imshow('result', bgr_red)
# cv2.waitKey(0)
# #######################将原图的绿色区域替换成白色############################
img_cut = img[ymin:ymax, xmin:xmax]
img_cut[mask > 0] = (255, 255, 255)
img[ymin:ymax, xmin:xmax] = img_cut
cv2.imwrite(output_path, img)
cv2.imshow('result', img)
def nothing(x):
pass
def test_color_hsv_values(input_path):
cv2.namedWindow('image', cv2.WINDOW_AUTOSIZE)
blue = np.uint8([[[255, 0, 0]]])
hsv_blue = cv2.cvtColor(blue, cv2.COLOR_BGR2HSV)
print(hsv_blue)
cv2.createTrackbar('Hue min', 'image', 10, 179, nothing)
cv2.createTrackbar('Hue max', 'image', 10, 179, nothing)
cv2.createTrackbar('sat min', 'image', 10, 255, nothing)
cv2.createTrackbar('sat max', 'image', 10, 255, nothing)
cv2.createTrackbar('val min', 'image', 10, 255, nothing)
cv2.createTrackbar('val max', 'image', 10, 255, nothing)
img = cv2.imread(input_path)
# img = cv2.resize(src=img2, dsize=(400, 300), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)
while True:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos('Hue min', 'image')
h_max = cv2.getTrackbarPos('Hue max', 'image')
s_min = cv2.getTrackbarPos('sat min', 'image')
s_max = cv2.getTrackbarPos('sat max', 'image')
v_min = cv2.getTrackbarPos('val min', 'image')
v_max = cv2.getTrackbarPos('val max', 'image')
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
mask = cv2.inRange(hsv, lower, upper)
res = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow('img', img)
cv2.imshow('mask', mask)
cv2.imshow('res', res)
k = cv2.waitKey(5)
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
input_path = '4.jpg'
output_path = '4_result.jpg'
# 像素点坐标,图左上角为0,0, x往右增大, y向下增大
# 1.jpg 参数
# ymin, ymax, xmin, xmax = 200, 560, 800, 1150
# low_hsv = np.array([30, 0, 108])
# high_hsv = np.array([91, 255, 255])
# 2.png 参数
# ymin, ymax, xmin, xmax = 0, 1440, 0, 1724
# low_hsv = np.array([58, 85, 0])
# high_hsv = np.array([91, 255, 255])
# 3.png 参数
# ymin, ymax, xmin, xmax = 0, 1440, 0, 1442
# low_hsv = np.array([28, 52, 0])
# high_hsv = np.array([92, 255, 255])
# 4.png 参数
ymin, ymax, xmin, xmax = 200, 800, 700, 1200
low_hsv = np.array([28, 52, 178])
high_hsv = np.array([92, 255, 255])
color_cut(input_path, output_path, ymin, ymax, xmin, xmax, low_hsv, high_hsv)
# test_color_hsv_values(input_path)
这里有个test_color_hsv_values(input_path)
函数,其作用就在于修改输入的范围,实时动态观察图像颜色变化情况。
下面两张是演示效果,上面为提取“飞机”本身的图形,下面为提取“天空”的图形,通过移动Hue、Sat、Val
三组共六个进度条,确定三种变量的上下值,从而确定要选择的HSV范围。
通过test_color_hsv_values(input_path)
函数,确定了HSV数值后,重新调用 color_cut(input_path, output_path, ymin, ymax, xmin, xmax, low_hsv, high_hsv)
函数,生成result
图片。
本文是利用Opencv-python 进行的对图片颜色进行提取、抠图的一个脚本。