Упрощение компьютерного зрения с помощью Monk, инструмента глубокого обучения с низким кодом и унифицированной оболочки для компьютерного зрения
Оглавление
- Масштабирование
- Перевод
- Вращение
- Аффинное преобразование
- Преобразование перспективы
Масштабирование
- Масштабирование изображения относится к изменению размера цифрового изображения.
- Увеличение цифрового материала называется апскейлингом.
- Уменьшение размера известно как уменьшение масштаба.
- Идеальный сценарий - трансформация без потерь.
- Разрешение изображения - высота (в пикселях), * ширина (в пикселях)
Изменение размера изображения с помощью numpy
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread("imgs/chapter4/tessellate.jpg", -1) print("Input image shape - {}".format(img.shape)) plt.imshow(img[:,:,::-1]) plt.show()
Выход
Input image shape - (240, 320, 3)
Ширина уменьшения
height, width, channels = img.shape # create blank image of half the width resized_img_width = np.zeros((height, width//2, channels), dtype=np.int32) for r in range(height): for c in range(width//2): resized_img_width[r][c] += (img[r][2*c]) print("Width resized image shape - {}".format(resized_img_width.shape)) plt.imshow(resized_img_width[:,:,::-1]) plt.show()
Выход
Width resized image shape - (240, 160, 3)
Уменьшение изображения до половины ширины и высоты
resized_img = np.zeros((height//2, width//2, channels), dtype=np.int32) for r in range(height//2): for c in range(width//2): resized_img[r][c] += (resized_img_width[r*2][c]) print("Complete resized image shape - {}".format(resized_img.shape)) plt.imshow(resized_img[:,:,::-1]) plt.show()
Выход
Complete resized image shape - (120, 160, 3)
Высота апскейлинга
half_upsclaled_img = np.zeros((height, width//2, channels), dtype=np.int32) half_upsclaled_img[0:height:2, :, :] = resized_img[:, :, :] half_upsclaled_img[1:height:2, :, :] = resized_img[:, :, :] print("Height upscaled image shape - {}".format(half_upsclaled_img.shape)) plt.imshow(half_upsclaled_img[:,:,::-1]) plt.show()
Выход
Height upscaled image shape - (240, 160, 3)
Ширина апскейлинга
upsclaled_img = np.zeros((height, width, channels), dtype=np.int32) # Expand rows by replicating every consecutive row upsclaled_img[:, 0:width:2, :] = half_upsclaled_img[:, :, :] upsclaled_img[:, 1:width:2, :] = half_upsclaled_img[:, :, :] print("Fully upscaled image shape - {}".format(upsclaled_img.shape)) upscaled_img_manual = upsclaled_img plt.imshow(upsclaled_img[:,:,::-1]) plt.show()
Выход
Fully upscaled image shape - (240, 320, 3)
Сравнение оригинала и масштабирования
f = plt.figure(figsize=(15,15)) f.add_subplot(1, 2, 1).set_title('Original Image') plt.imshow(img[:, :, ::-1]) f.add_subplot(1, 2, 2).set_title('Upscaled image post downscaling') plt.imshow(upsclaled_img[:, :, ::-1]) plt.show()
Примечание. При таком изменении размера изображения теряется много информации.
Изменение размера изображения с помощью OpenCV
- Уменьшение размера фигуры с помощью cv2.resize ().
- Масштабирование фигуры с помощью cv2.resize ().
Уменьшение изображения до половины ширины и высоты
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread("imgs/chapter4/tessellate.jpg", -1) height, width, channels = img.shape # create blank image of half the width resized_img = cv2.resize(img, (width//2, height//2)) print("Downscaled image shape - {}".format(resized_img.shape)) plt.imshow(resized_img[:,:,::-1]) plt.show()
Увеличение изображения до исходной ширины и высоты
height, width, channels = img.shape # create blank image of half the width upscaled_img = cv2.resize(resized_img, (width, height)); print("Upscaled image shape - {}".format(upscaled_img.shape)) upscaled_img_opencv = upscaled_img plt.imshow(upscaled_img[:,:,::-1]) plt.show()
Выход
Upscaled image shape - (240, 320, 3)
Сравнение оригинала, масштабирования вручную, масштабирования с использованием opencv
f = plt.figure(figsize=(15,15)) f.add_subplot(3, 1, 1).set_title('Original Image'); plt.imshow(img[:, :, ::-1]) f.add_subplot(3, 1, 2).set_title('Manually Upscaled post downscaling'); plt.imshow(upscaled_img_manual[:, :, ::-1]) f.add_subplot(3, 1, 3).set_title('Upscaled using opencv post downscaling'); plt.imshow(upscaled_img[:, :, ::-1]) plt.show()
Изменение размера изображения с помощью подушки
Уменьшение изображения до половины ширины и высоты
import numpy as np from PIL import Image from matplotlib import pyplot as plt img_p = Image.open("imgs/chapter4/tessellate.jpg") width, height = img_p.size # create blank image of half the width resized_img = img_p.resize((width//2, height//2)) print("Downscaled image shape - {}".format(resized_img.size)) plt.imshow(resized_img); plt.show()
Выход
Downscaled image shape - (160, 120)
Увеличение изображения до исходной ширины и высоты
width, height = img_p.size # create blank image of half the width upscaled_img = resized_img.resize((width, height)) print("Upscaled image shape - {}".format(upscaled_img.size)) plt.imshow(resized_img) plt.show()
Выход
Upscaled image shape - (320, 240)
Сравнение оригинала, масштабирования вручную, масштабирования с использованием opencv
f = plt.figure(figsize=(15,15)) f.add_subplot(2, 2, 1).set_title('Original Image') plt.imshow(img[:, :, ::-1]) f.add_subplot(2, 2, 2).set_title('Manually Upscaled post downscaling') plt.imshow(upscaled_img_manual[:, :, ::-1]) f.add_subplot(2, 2, 3).set_title('Upscaled using opencv post downscaling') plt.imshow(upscaled_img_opencv[:, :, ::-1]) f.add_subplot(2, 2, 4).set_title('Upscaled using PIL post downscaling') plt.imshow(upscaled_img) plt.show()
Алгоритмы масштабирования
Что такое интерполяция
- Интерполяция - это метод построения новых точек данных в диапазоне дискретного набора известных точек данных.
- Часто требуется интерполировать, то есть оценить значение этой функции для промежуточного значения независимой переменной.
- Это также называется подгонкой кривой. Приблизительные значения
Интерполяции OpenCV
интерполяция ближайшего соседа
- Присвойте значение, ближайшее к текущему пикселю.
- Ближайший сосед - самый простой.
- Он требует наименьшего времени обработки из всех алгоритмов интерполяции, поскольку учитывает только один пиксель - ближайший к интерполированной точке.
Билинейная интерполяция
- Билинейная интерполяция рассматривает ближайшую окрестность 2 * 2 известных значений пикселей, окружающую неизвестный пиксель.
- Затем требуется средневзвешенное значение этих 4 пикселей, чтобы получить окончательное интерполированное значение.
Бикубическая интерполяция
Интерполяция Ланцзоса
- Интерполяция высшего порядка.
- Работает в частотной области, поэтому трудно визуализировать.
- Методология фильтрации и извлечения признаков более высокого уровня.
Какую интерполяцию использовать?
- cv2.INTER_LINEAR используется по умолчанию.
- cv2.INTER_AREA для усадки.
- cv2.INTER_CUBIC снова для сжатия, лучше, но медленно.
- cv.INTER_LINEAR для увеличения.
- Другие сложные, когда не учитывается скорость вычислений.
Алгоритмы OpenCV
Алгоритмы подушки
Перевод
- Сдвиг изображения на определенные пиксели в любом из четырех направлений.
Зачем это нужно?
- Для увеличения данных.
Перевод изображений с использованием базового Numpy
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread("imgs/chapter4/dog.jpg",-1) plt.imshow(img[:,:,::-1]) plt.show()
Перевод вправо на 50 пикселей
h, w, c = img.shape; img_new = np.zeros((h, w, c), dtype=np.uint8); f = plt.figure(figsize=(15,15)) f.add_subplot(3, 1, 1).set_title('Original Image'); plt.imshow(img[:, :, ::-1]) f.add_subplot(3, 1, 2).set_title('New Blank Image'); plt.imshow(img_new[:, :, ::-1]) plt.show()
img_new[:, 50:, :] = img[:, :w-50, :] plt.imshow(img_new[:,:,::-1]) plt.show()
Перевод влево на 50 пикселей
h, w, c = img.shape img_new = np.zeros((h, w, c), dtype=np.uint8) img_new[:, :w-50, :] = img[:, 50:, :] plt.imshow(img_new[:,:,::-1]) plt.show()
Перевод вниз на 50 пикселей
h, w, c = img.shape img_new = np.zeros((h, w, c), dtype=np.uint8) img_new[50:, :, :] = img[:h-50, :, :] plt.imshow(img_new[:,:,::-1]) plt.show()
Перевод на 50 пикселей вверх
h, w, c = img.shape; img_new = np.zeros((h, w, c), dtype=np.uint8) img_new[:h-50, :, :] = img[50:, :, :] plt.imshow(img_new[:,:,::-1]) plt.show()
Вращение
Поворот изображения с использованием PIL
import numpy as np from PIL import Image from matplotlib import pyplot as plt img_p = Image.open("imgs/chapter4/triangle.jpg") plt.imshow(img_p) plt.show()
Вращение по часовой стрелке на 30 градусов с осью в центре
img_p_new = img_p.rotate(-30) plt.imshow(img_p_new) plt.show()
Вращение против часовой стрелки на 30 градусов с осью в центре
img_p_new = img_p.rotate(30) plt.imshow(img_p_new) plt.show()
Аффинное преобразование
- Преобразование с переводом и поворотом изображений.
- Но преобразование выполняется таким образом, что прямые линии на изображении никогда не изгибаются.
Аффинное преобразование с использованием OpenCV
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread("imgs/chapter4/tessellate.jpg", -1) plt.imshow(img[:,:,::-1]) plt.show()
Сохранение двух точек статичными и изменяющимися
img = cv2.imread("imgs/chapter4/tessellate.jpg", -1) rows,cols,ch = img.shape # Read as x, y pts1 = np.float32([[50,50],[200,50], [50,200]]) pts2 = np.float32([[80,50],[200,50], [50,200]]) cv2.circle(img,(int(pts1[0][0]),int(pts1[0][1])),5,(0,255,0),-1) cv2.circle(img,(int(pts1[1][0]),int(pts1[1][1])),5,(0,0,255),-1) cv2.circle(img,(int(pts1[2][0]),int(pts1[2][1])),5,(255,0,0), -1) M = cv2.getAffineTransform(pts1,pts2) dst = cv2.warpAffine(img,M,(cols,rows)) f = plt.figure(figsize=(15,15)) f.add_subplot(1, 2, 1).set_title('Input') plt.imshow(img[:, :, ::-1]) f.add_subplot(1, 2, 2).set_title('Transformed') plt.imshow(dst[:, :, ::-1]) plt.show()
Сохранение 1 точки как петли
img = cv2.imread("imgs/chapter4/tessellate.jpg", -1) rows,cols,ch = img.shape pts1 = np.float32([[50,50],[200,50], [50,200]]) #pts2 = np.float32([[60,50],[190,50], [50,200]]) # Works as translation + shrinking pts2 = np.float32([[60,50],[200,50], [50,175]]) cv2.circle(img,(int(pts1[0][0]), int(pts1[0][1])), 5, (0,255,0), -1) cv2.circle(img,(int(pts1[1][0]), int(pts1[1][1])), 5, (0,0,255), -1) cv2.circle(img,(int(pts1[2][0]), int(pts1[2][1])), 5, (255,0,0), -1) M = cv2.getAffineTransform(pts1,pts2) dst = cv2.warpAffine(img,M,(cols,rows)) f = plt.figure(figsize=(15,15)) f.add_subplot(1, 2, 1).set_title('Input') plt.imshow(img[:, :, ::-1]) f.add_subplot(1, 2, 2).set_title('Transformed') plt.imshow(dst[:, :, ::-1]) plt.show()
Перевод всех трех пунктов - ›перевод
img = cv2.imread("imgs/chapter4/tessellate.jpg", -1) rows,cols,ch = img.shape pts1 = np.float32([[50,50],[200,50], [50,200]]) pts2 = np.float32([[60,50],[210,50], [60,200]]) cv2.circle(img,(int(pts1[0][0]), int(pts1[0][1])), 5, (0,255,0), -1) cv2.circle(img,(int(pts1[1][0]), int(pts1[1][1])), 5, (0,0,255), -1) cv2.circle(img,(int(pts1[2][0]), int(pts1[2][1])), 5, (255,0,0), -1) M = cv2.getAffineTransform(pts1,pts2) dst = cv2.warpAffine(img,M,(cols,rows)) f = plt.figure(figsize=(15,15)) f.add_subplot(1, 2, 1).set_title('Input') plt.imshow(img[:, :, ::-1]) f.add_subplot(1, 2, 2).set_title('Transformed') plt.imshow(dst[:, :, ::-1]) plt.show()
Преобразование перспективы
Перспективное преобразование с использованием OpenCV
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread("imgs/chapter4/cube.png", 1) plt.imshow(img[:,:,::-1]) plt.show()
Увеличение из вида
img = cv2.imread("imgs/chapter4/cube.png", 1) img = cv2.resize(img, (400, 400)) rows,cols,ch = img.shape # Counter clock wise pts1 = np.float32([[130,130],[390,75],[360,320],[140, 390]]) pts2 = np.float32([[0,0],[0, 200],[200,200],[200,0]]) # uncomment each and see cv2.circle(img,(int(pts1[0][0]),int(pts1[0][1])),5,(255,255,255), -1) cv2.circle(img,(int(pts1[1][0]), int(pts1[1][1])), 5, (255,255,255), -1) cv2.circle(img,(int(pts1[2][0]), int(pts1[2][1])), 5, (255,255,255), -1) cv2.circle(img,(int(pts1[3][0]), int(pts1[3][1])), 5, (255,255,255), -1) M = cv2.getPerspectiveTransform(pts1,pts2) dst = cv2.warpPerspective(img,M,(cols,rows)) f = plt.figure(figsize=(15,15)) f.add_subplot(1, 2, 1).set_title('Input'); plt.imshow(img[:, :, ::-1]) f.add_subplot(1, 2, 2).set_title('Transformed'); plt.imshow(dst[:, :, ::-1]) plt.show()
Вы можете найти полный блокнот jupyter на Github.
Если у вас есть вопросы, вы можете связаться с Абхишек и Акаш. Не стесняйтесь обращаться к ним.
Я очень увлечен компьютерным зрением и глубоким обучением в целом. Я участник библиотек Monk с открытым исходным кодом.
Вы также можете увидеть другие мои работы по адресу: