作者:Akula Hemanth Kumar
deephub翻译组:孟翔杰
**
**
目录
1.缩放
2.平移
3.旋转
4.仿射变换
5.透视变换
缩放
图像缩放是指调整图像的大小
magnification称为放大
downsizing称为缩小
理想目标-图片无损转换
图像分辨率-高度(以像素为单位)*宽度(以像素为单位)
使用 numpy 模块调整图像大小
import numpy as npimport cv2from matplotlib import pyplot as pltimg = 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 widthresized_img_width = np.zeros((height, width//2, channels), dtype=np.int32)for r in range(height):forcin 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):forcin 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 rowupsclaled_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_imgplt.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 npimport cv2from matplotlib import pyplot as pltimg = cv2.imread("imgs/chapter4/tessellate.jpg", -1)height, width, channels = img.shape
# create blank image of half the widthresized_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 widthupscaled_img = cv2.resize(resized_img, (width, height));print("Upscaled image shape - {}".format(upscaled_img.shape))upscaled_img_opencv = upscaled_imgplt.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()
使用Pillow模块调整图像大小
将图像的高度和宽度均缩小到原来的一半```
import numpy as npfrom PIL import Imagefrom matplotlib import pyplot as pltimg_p = Image.open("imgs/chapter4/tessellate.jpg")width, height = img_p.size
# create blank image of half the widthresized_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 widthupscaled_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缩放的图片和使用Pillow缩放的图片
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个像素进行加权平均,以得出其最终插值。
双三次插值
LancZos插值
- 高阶插值。
- 因为在高阶中操作所以难以可视化。
- 是一种更高维度的过滤和特征提取方法。
应该用哪种插值方法呢?
- 默认情况下使用cv2.INTER_LINEAR。
- cv2.INTER_AREA用于缩小。
- cv2.INTER_CUBIC也是用于缩小,效果更好但速度较慢。
- cv.INTER_LINEAR用于图片缩放缩放。
- 当不考虑计算速度时可以运用其他方法。
OpenCV的算法
import numpy as npimport cv2from matplotlib import pyplot as pltimg = cv2.imread("imgs/chapter4/tessellate.jpg", -1)h, w, c = img.shape
# Downscaling and upscaling using nearest neighbor interpolationimg_n = cv2.resize(img, (w//2, h//2), interpolation = cv2.INTER_NEAREST)img_n = cv2.resize(img_n, (w, h), interpolation = cv2.INTER_NEAREST)
# Downscaling and upscaling using Bilinear interpolationimg_b = cv2.resize(img, (w//2, h//2), interpolation = cv2.INTER_LINEAR)img_b = cv2.resize(img_b, (w, h), interpolation = cv2.INTER_LINEAR)
# Downscaling and upscaling using matrix area interpolationimg_a = cv2.resize(img, (w//2, h//2), interpolation = cv2.INTER_AREA)img_a = cv2.resize(img_a, (w, h), interpolation = cv2.INTER_AREA)
# Downscaling and upscaling using cubic interpolationimg_c = cv2.resize(img, (w//2, h//2), interpolation = cv2.INTER_CUBIC)img_c = cv2.resize(img_c, (w, h), interpolation = cv2.INTER_CUBIC)
# Downscaling and upscaling using lanczos interpolationimg_l = cv2.resize(img, (w//2, h//2), interpolation = cv2.INTER_LANCZOS4)img_l = cv2.resize(img_l, (w, h), interpolation = cv2.INTER_LANCZOS4)f = plt.figure(figsize=(15,15))f.add_subplot(3, 2, 1).set_title('Original Image')plt.imshow(img[:, :, ::-1])f.add_subplot(3, 2, 2).set_title('Nearest neighbour Interpolation')plt.imshow(img_n[:, :, ::-1])f.add_subplot(3, 2, 3).set_title('Bilinear Interpolation')plt.imshow(img_b[:, :, ::-1])f.add_subplot(3, 2, 4).set_title('Area matrix Interpolation')plt.imshow(img_a[:, :, ::-1])f.add_subplot(3, 2, 5).set_title('Cubic Interpolation')plt.imshow(img_c[:, :, ::-1])f.add_subplot(3, 2, 6).set_title('Lanczos Interpolation')plt.imshow(img_l[:, :, ::-1])plt.show()
Pillow的算法
import PILimport numpy as npfrom PIL import Imagefrom matplotlib import pyplot as pltimg_p = Image.open("imgs/chapter4/tessellate.jpg")width, height = img_p.size
# Downscaling and upscaling using nearest neighbor interpolationimg_n = img_p.resize((width//2, height//2), resample=PIL.Image.NEAREST)img_n = img_n.resize((width, height), resample=PIL.Image.NEAREST)
# Downscaling and upscaling using nearest box filteringimg_f = img_p.resize((width//2, height//2), resample=PIL.Image.BOX) img_f = img_f.resize((width, height), resample=PIL.Image.BOX)
# Downscaling and upscaling using nearest Bilinear interpolationimg_b = img_p.resize((width//2, height//2), resample=PIL.Image.BILINEAR)img_b = img_b.resize((width, height), resample=PIL.Image.BILINEAR)
# Downscaling and upscaling using nearest Hamming interpolationimg_h = img_p.resize((width//2, height//2), resample=PIL.Image.HAMMING)img_h = img_h.resize((width, height), resample=PIL.Image.HAMMING)# Downscaling and upscaling using nearest Bicubic interpolationimg_c = img_p.resize((width//2, height//2), resample=PIL.Image.BICUBIC); img_c = img_c.resize((width, height), resample=PIL.Image.BICUBIC)
# Downscaling and upscaling using nearest Lanczos interpolationimg_l = img_p.resize((width//2, height//2), resample=PIL.Image.LANCZOS)img_l = img_l.resize((width, height), resample=PIL.Image.LANCZOS)
f = plt.figure(figsize=(15,20))f.add_subplot(4, 2, 1).set_title('Original Image')plt.imshow(img_p)f.add_subplot(4, 2, 2).set_title('Nearest neighbour Interpolation')plt.imshow(img_n)f.add_subplot(4, 2, 3).set_title('Box Interpolation')plt.imshow(img_f)f.add_subplot(4, 2, 4).set_title('Bilinear Interpolation')plt.imshow(img_b)f.add_subplot(4, 2, 5).set_title('Hamming Interpolation')plt.imshow(img_h)f.add_subplot(4, 2, 6).set_title('Bi-Cubic Interpolation')plt.imshow(img_c)f.add_subplot(4, 2, 7).set_title('Lanczos Interpolation')plt.imshow(img_l)plt.show()
平移
- 在四个方向中的任何一个方向上将图像移动一定像素。
为什么要这么做?
- 用于数据增强
使用numpy进行图像平移
import numpy as npimport cv2from matplotlib import pyplot as pltimg = 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.shapeimg_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[:h-50, :, :] = img[50:, :, :]plt.imshow(img_new[:,:,::-1])plt.show()
旋转
使用PIL模块旋转图像
import numpy as npfrom PIL import Imagefrom matplotlib import pyplot as pltimg_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 npimport cv2from matplotlib import pyplot as pltimg = 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, ypts1 = 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()
将一个点作为铰链进行变换
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 + shrinkingpts2 = 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 npimport cv2from matplotlib import pyplot as pltimg = 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 wisepts1 = np.float32([[130,130],[390,75],[360,320],[140, 390]])pts2 = np.float32([[0,0],[0, 200],[200,200],[200,0]])
# uncomment each and seecv2.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()
DeepHub
微信号 : deephub-imba
每日大数据和人工智能的重磅干货
大厂职位内推信息
长按识别二维码关注 ->
好看就点在看!********** **********