Увеличение изображения - это метод создания изображения и его использования для создания новых. Это полезно для таких вещей, как обучение беспилотному вождению автомобиля.
Представьте себе человека за рулем машины в солнечный день. Если начнется дождь, поначалу им может быть трудно управлять автомобилем в дождь. Но постепенно они к этому привыкают.
Искусственная нейронная сеть также находит затруднительным вождение в новой среде, если она не видела это раньше. Это различные техники увеличения, такие как переворачивание, перевод, добавление шума или изменение цветового канала.
В этой статье я расскажу о погоде. Я использовал библиотеку OpenCV для обработки изображений. Через некоторое время я обнаружил, что это довольно легко, и смог добавить в изображение различные погодные сценарии.
Я выпустил полностью реализованный Jupyter Notebook, с которым вы можете поиграть на GitHub.
Давайте посмотрим.
Сначала я покажу вам исходное тестовое изображение, а затем дополню его.
Санни и Шейди
После добавления случайного солнечного и теневого эффекта яркость изображения изменится. Это простое и быстрое преобразование.
def add_brightness(image): image_HLS = cv2.cvtColor(image,cv2.COLOR_RGB2HLS) ## Conversion to HLS image_HLS = np.array(image_HLS, dtype = np.float64) random_brightness_coefficient = np.random.uniform()+0.5 ## generates value between 0.5 and 1.5 image_HLS[:,:,1] = image_HLS[:,:,1]*random_brightness_coefficient ## scale pixel values up or down for channel 1(Lightness) image_HLS[:,:,1][image_HLS[:,:,1]>255] = 255 ##Sets all values above 255 to 255 image_HLS = np.array(image_HLS, dtype = np.uint8) image_RGB = cv2.cvtColor(image_HLS,cv2.COLOR_HLS2RGB) ## Conversion to RGB return image_RGB
Яркость изображения можно изменить, изменив значения пикселей «Яркость» - канал 1 изображения в цветовом пространстве HLS. Преобразование изображения обратно в RGB дает то же изображение с усиленным или подавленным освещением.
Тени
Для автомобиля тень - это не что иное, как темные участки изображения, которые иногда могут быть яркими. Таким образом, беспилотный автомобиль всегда должен учиться водить с тенями или без них. Случайно меняющаяся яркость на холмах или в лесу часто сбивает с толку восприятие автомобиля, если его не обучить должным образом. Это еще более распространено в солнечные дни и в зданиях разной высоты в городе, через которые проникают лучи света.
Яркость хороша для восприятия, но неравномерная, резкая или слишком большая яркость создает проблемы с восприятием. Давайте создадим несколько искусственных теней.
def generate_shadow_coordinates(imshape, no_of_shadows=1): vertices_list=[] for index in range(no_of_shadows): vertex=[] for dimensions in range(np.random.randint(3,15)): ## Dimensionality of the shadow polygon vertex.append(( imshape[1]*np.random.uniform(),imshape[0]//3+imshape[0]*np.random.uniform())) vertices = np.array([vertex], dtype=np.int32) ## single shadow vertices vertices_list.append(vertices) return vertices_list ## List of shadow vertices def add_shadow(image,no_of_shadows=1): image_HLS = cv2.cvtColor(image,cv2.COLOR_RGB2HLS) ## Conversion to HLS mask = np.zeros_like(image) imshape = image.shape vertices_list= generate_shadow_coordinates(imshape, no_of_shadows) #3 getting list of shadow vertices for vertices in vertices_list: cv2.fillPoly(mask, vertices, 255) ## adding all shadow polygons on empty mask, single 255 denotes only red channel image_HLS[:,:,1][mask[:,:,0]==255] = image_HLS[:,:,1][mask[:,:,0]==255]*0.5 ## if red channel is hot, image's "Lightness" channel's brightness is lowered image_RGB = cv2.cvtColor(image_HLS,cv2.COLOR_HLS2RGB) ## Conversion to RGB return image_RGB
В этом случае очень удобна функция fillPoly()
OpenCV. Давайте создадим несколько случайных вершин и наложим многоугольник на пустую маску с помощью fillPoly()
. После этого остается только проверить маску на наличие горячих пикселей и уменьшить «яркость» в HLS-изображении, где бы эти горячие пиксели ни были обнаружены.
Снег
Ну это что-то новенькое. Мы часто задаемся вопросом, как бы наш автомобиль вёл себя на заснеженной дороге. Один из способов проверить это - сделать снимки заснеженных дорог или сделать что-нибудь с изображениями, чтобы получить аналогичный эффект. Этот эффект не является полной альтернативой заснеженным дорогам, но его стоит попробовать.
def add_snow(image): image_HLS = cv2.cvtColor(image,cv2.COLOR_RGB2HLS) ## Conversion to HLS image_HLS = np.array(image_HLS, dtype = np.float64) brightness_coefficient = 2.5 snow_point=140 ## increase this for more snow image_HLS[:,:,1][image_HLS[:,:,1]<snow_point] = image_HLS[:,:,1][image_HLS[:,:,1]<snow_point]*brightness_coefficient ## scale pixel values up for channel 1(Lightness) image_HLS[:,:,1][image_HLS[:,:,1]>255] = 255 ##Sets all values above 255 to 255 image_HLS = np.array(image_HLS, dtype = np.uint8) image_RGB = cv2.cvtColor(image_HLS,cv2.COLOR_HLS2RGB) ## Conversion to RGB return image_RGB
Ага! Вот и все. Этот код обычно отбеливает самые темные части изображения, которые в основном представляют собой дороги, деревья, горы и другие элементы ландшафта, используя тот же метод увеличения HLS «Яркость», который использовался в других подходах, описанных выше. Этот метод не подходит для темных изображений, но вы можете изменить его для этого. Вот что вы получите:
Вы можете настроить некоторые параметры в коде для большего или меньшего количества снега, чем это. Я тестировал это и на других изображениях, и этот метод вызывает у меня мурашки по коже.
Дождь
Да, вы не ослышались. Почему не дождь? Когда люди испытывают трудности с вождением под дождем, почему следует избегать этого в транспортных средствах? На самом деле, это одна из ситуаций, для которой я больше всего хочу, чтобы мой беспилотный автомобиль был обучен. Скользкие дороги и расплывчатые представления - дело рискованное, и автомобили должны знать, как с ними справляться.
def generate_random_lines(imshape,slant,drop_length): drops=[] for i in range(1500): ## If You want heavy rain, try increasing this if slant<0: x= np.random.randint(slant,imshape[1]) else: x= np.random.randint(0,imshape[1]-slant) y= np.random.randint(0,imshape[0]-drop_length) drops.append((x,y)) return drops def add_rain(image): imshape = image.shape slant_extreme=10 slant= np.random.randint(-slant_extreme,slant_extreme) drop_length=20 drop_width=2 drop_color=(200,200,200) ## a shade of gray rain_drops= generate_random_lines(imshape,slant,drop_length) for rain_drop in rain_drops: cv2.line(image,(rain_drop[0],rain_drop[1]),(rain_drop[0]+slant,rain_drop[1]+drop_length),drop_color,drop_width) image= cv2.blur(image,(7,7)) ## rainy view are blurry brightness_coefficient = 0.7 ## rainy days are usually shady image_HLS = cv2.cvtColor(image,cv2.COLOR_RGB2HLS) ## Conversion to HLS image_HLS[:,:,1] = image_HLS[:,:,1]*brightness_coefficient ## scale pixel values down for channel 1(Lightness) image_RGB = cv2.cvtColor(image_HLS,cv2.COLOR_HLS2RGB) ## Conversion to RGB return image_RGB
Что я здесь сделал, так это то, что я снова сгенерировал случайные точки по всему изображению, а затем использовал функцию OpenCV line()
для создания небольших линий по всему изображению. Я также использовал случайный наклон капель дождя, чтобы почувствовать настоящий дождь. Я также уменьшил яркость изображения, потому что дождливые дни обычно тенистые, а также размытые из-за дождя. Вы можете изменить размер фильтра размытия и количество капель дождя для достижения желаемого эффекта.
Вот результат:
Туман
Это еще один сценарий, который сильно мешает представлению о беспилотном автомобиле. Размытые белые ворсинки на изображении затрудняют просмотр за пределами определенного участка и снижают резкость изображения.
Интенсивность тумана - важный параметр, который помогает приучить машину работать с дроссельной заслонкой. Для кодирования такой функции вы можете брать случайные участки со всего изображения и увеличивать яркость изображения внутри этих участков. С помощью простого размытия получается приятный эффект тумана.
def add_blur(image, x,y,hw): image[y:y+hw, x:x+hw,1] = image[y:y+hw, x:x+hw,1]+1 image[:,:,1][image[:,:,1]>255] = 255 ##Sets all values above 255 to 255 image[y:y+hw, x:x+hw,1] = cv2.blur(image[y:y+hw, x:x+hw,1] ,(10,10)) return image def generate_random_blur_coordinates(imshape,hw): blur_points=[] midx= imshape[1]//2-hw-100 midy= imshape[0]//2-hw-100 index=1 while(midx>-100 or midy>-100): ## radially generating coordinates for i in range(250*index): x= np.random.randint(midx,imshape[1]-midx-hw) y= np.random.randint(midy,imshape[0]-midy-hw) blur_points.append((x,y)) midx-=250*imshape[1]//sum(imshape) midy-=250*imshape[0]//sum(imshape) index+=1 return blur_points def add_fog(image): image_HLS = cv2.cvtColor(image,cv2.COLOR_RGB2HLS) ## Conversion to HLS mask = np.zeros_like(image) imshape = image.shape hw=100 image_HLS[:,:,1]=image_HLS[:,:,1]*0.8 haze_list= generate_random_blur_coordinates(imshape,hw) for haze_points in haze_list: image_HLS[:,:,1][image_HLS[:,:,1]>255] = 255 ##Sets all values above 255 to 255 image_HLS= add_blur(image_HLS, haze_points[0],haze_points[1], hw) ## adding all shadow polygons on empty mask, single 255 denotes only red channel image_RGB = cv2.cvtColor(image_HLS,cv2.COLOR_HLS2RGB) ## Conversion to RGB return image_RGB
Кодирование этой функции было самой сложной из всех вышеперечисленных функций. Я пробовал здесь радиальный подход для создания патчей. Поскольку в туманный день обычно большая часть тумана находится в дальнем конце дороги, и когда мы приближаемся к нам, зрение продолжает проясняться.
Для машины - действительно сложная задача - обнаруживать близлежащие автомобили и полосы движения в таком тумане, и это хороший способ потренироваться и проверить надежность модели вождения.
Проливной дождь
Я подумал о том, чтобы сделать часть дождя немного лучше, объединив туман и дождь. Ведь во время дождя всегда бывает дымка, и машину для этого тоже полезно приучить. Для этого не требуется никакой новой функции. Мы можем добиться эффекта, последовательно вызывая оба.
Автомобиль справа на этом изображении почти не виден, и это реальный сценарий. В сильный дождь на дороге почти ничего не разглядеть.
Надеюсь, эта статья поможет вам обучить модель в различных погодных условиях. Полный код вы можете найти в моем профиле GitHub. И я написал много других статей, которые вы можете прочитать на Medium и на моем сайте WordPress.
Наслаждаться!