Упрощение компьютерного зрения с помощью Monk, инструмента глубокого обучения с низким кодом и унифицированной оболочки для компьютерного зрения

Оглавление

  1. Масштабирование
  2. Перевод
  3. Вращение
  4. Аффинное преобразование
  5. Преобразование перспективы

Масштабирование

  • Масштабирование изображения относится к изменению размера цифрового изображения.
  • Увеличение цифрового материала называется апскейлингом.
  • Уменьшение размера известно как уменьшение масштаба.

  • Идеальный сценарий - трансформация без потерь.
  • Разрешение изображения - высота (в пикселях), * ширина (в пикселях)

Изменение размера изображения с помощью 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 с открытым исходным кодом.

Вы также можете увидеть другие мои работы по адресу: