图像几何变换
图片变换的本质就是对图片的矩阵进行操作
图片位移
矩阵仿射变换,是一系列变换的基础
图片缩放
图片缩放就是将图片宽高信息进行改变
- 加载图片
- 修改大小
- 放大 缩小 等比例缩放
def resize(img,param):
height,width,_ = get_img_info(img)
dstHeight = int(height * param)
dstWidth = int(height * param)
dst = cv2.resize(img,(dstWidth,dstHeight))
return dst
def get_img_info(img):
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
mode = imgInfo[2]
return height, width, mode
img = cv2.imread('empire.jpeg',1)
dst = utils.resize(img,0.5)
cv2.imshow('resize img',dst)
cv2.waitKey(0)
在 opencv 中提供的有关缩放的方法
- 最近临域插值
对于缩放后像素位置 x y 如果是小数,可以按临近进行取整 - 双线性插值
当我们进行缩放后得到点的 x y 都是小数,这次在双线插值法不是取最近点,而是按比例进行从周围 4 个点进行取值。根据该点距离其周围 4 点的比例来将周围 4 点像素值作为目标点。 - 像素关系重采样
- 立方插值
def resize_nearby(img,scale):
height,width,_ = get_img_info(img)
dstHeight = int(height/scale)
dstWidth = int(height/scale)
# create empty
dstImage = np.zeros((dstHeight,dstWidth,3),np.uint8)
for i in range(0,dstHeight):# row
for j in range(0,dstWidth):#column
iNew = int(i*(height*1.0/dstHeight))
jNew = int(j*(width*1.0)/dstWidth)
dstImage[i,j] = img[iNew,jNew]
return dstImage
通过变换矩阵实现图片缩放
def resize_with_mat(img,scale):
height,width,_ = get_img_info(img)
# tranform array
matTransform = np.float32([[scale,0,0],[0,scale,0]]) # 2 * 3
dst = cv2.warpAffine(img,matTransform,(int(width*scale),int(height*scale)) )
return dst
图片剪切
其本质是对数据进行操作,x 表示列信息 y 表示行信息。
def img_crop(img,startX,startY,h,w):
height,width,_ = get_img_info(img)
print(startX,(startX+h),startY,startY + w)
dst = img[startX:(startX+w),startY:(startY + h)]
# dst = img[100:200,100:300]
return dst
图片镜像
def img_mirror_v(img):
height,width,deep = get_img_info(img)
dstInfo = (height*2,width,deep)
dst = np.zeros(dstInfo,np.uint8)
for i in range(0,height):
for j in range(0,width):
dst[i,j] = img[i,j]
# x y
dst[height*2-i-1,j] = img[i,j]
for i in range(0,width):
dst[height,i] = (0,0,255) #BGR
return dst
图片位移
了解 opencv 提供有关位移的 API,
这里 matTransform 就是偏移矩阵,由该矩阵来控制图片的位置
[1,0,100],[0,1,200] 对该矩阵进行拆分为[1,0],[0,1]和[100],[200]
xy 为 C 矩阵
AC + B = [[1x + 0y],[0x + 1*y]] + [[100],[200]] = [[x+100],[y+200]]
def img_transform(img):
height,width,_ = get_img_info(img)
# tranform array
matTransform = np.float32([[1,0,100],[0,1,200]]) # 2 * 3
dst = cv2.warpAffine(img,matTransform,(width,height))
return dst
仿射变换
所谓仿射变换就是线性变换将平移,通过矩阵来控制 2D 图像,
直线变换
- 变换前是直线的,变换后依然是直线
- 直线比例保持不变
- 变换前是原点的,变换后依然是原点
这里通过 左上角、左下角和右上角
def img_transform(img):
height,width,deep = get_img_info(img)
matSrc = np.float32([[0,0],[0,height-1],[width-1,0]])
matDst = np.float32([[50,50],[300,height-200],[width-300,100]])
# combination
matAffine = cv2.getAffineTransform(matSrc,matDst) # mat
dst = cv2.warpAffine(img,matAffine,(width,height))
return dst
图片旋转
有关图像旋转这里我们使用 opencv 提供 getRotationMatrix2D 来获得一个矩阵来控制旋转,getRotationMatrix2D 接受三个参数分别为,
- 旋转的中心点
- 旋转的角度
- 缩放的比例
def img_rotate(img):
height,width,deep = get_img_info(img)
# mat rotate 1 center 2 angle 3 src
matRotate = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.5)
dst = cv2.warpAffine(img,matRotate,(width,height))
return dst