读书笔记-opencv-仿射变换

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/aaron1996123456/article/details/100768687

仿射变换

二维放射变换:
在这里插入图片描述

齐次坐标下:
在这里插入图片描述

平移变换:

在这里插入图片描述

绕原点放大和缩小:
在这里插入图片描述

绕点(x, y)放大和缩小(矩阵从右往左计算):

在这里插入图片描述

旋转变换:

在这里插入图片描述

顺时针公式推导:
在这里插入图片描述

扫描二维码关注公众号,回复: 7602071 查看本文章

逆时针公式推导:
在这里插入图片描述

计算仿射变换矩阵
方程法:
python
cv2.getAffineTransform(src, dst) //src代表的是原坐标,dst代表的是变换后的坐标,必须为浮点型

import cv2
import numpy as np
src = np.array([[0,0], [200,0], [0,200]], np.float32)			 #double  [], else error :"only 2 non-keyword arguments accepted"
dst = np.array([[0,0], [100,0], [0,100]], np.float32)            #after  import numpy as np, only use np,don't use numpy
A = cv2.getAffineTransform(src,dst)
print(A)

C++

Point2f src [] = {Point2f(0,0), Point2f(200,0), Point2f(0,200)};
Point2f dst [] = {Point2f(0,0), Point2f(100,0), Point2f(0,100)};
Mat A = getAffineTransform(src,dst);
//return data type CV_64 not CV_32

//method two
Mat src = (Mat_<float>(3,2) << 0,0,200,0,0,200);
Mat dst = (Mat_<float>(3,2) << 0,0,100,0,0,100);
Mat A = getAffineTransform(src, dst);

矩阵法

python

s = np.array([[0.5,0,0], [0,0.5,0], [0,0,1]]);			#Scaling matrix
t = np.array([[1,0,100], [0,1,200], [0,0,1]]);			#translation matrix
A = np.dot(t, s)										#matrix multiplication
print(A)

C++矩阵相乘

Mat s = (Mat_<float>(3,3) << 0.5,0,0,0,0.5,0,0,0,1);			//Scaling matrix
Mat t  =(Mat_<float>(3,3) << 1,0,100,0,1,200,0,0,1);			//translation matrix
Mat A;
gemm(s, t,1.0, Mat(), 0, A, 0);								//matrix multiplication

类似的,以(x0, y0)为中心进行缩放,然后逆时针旋转α,仿射变换矩阵为
在这里插入图片描述
如果是等比例缩放,即sx = sy俩个变换矩阵是相等的,opencv提供函数
cv2.getRotationMatrix2D(center, angle, scale)
center变换中心点坐标
angle等比例缩放系数
scale逆时针旋转角度;负数代表正时针旋转,以角度为单位,不是以弧度为单位

以(40,50)为旋转中心,逆时针旋转30°变换矩阵

A =cv2.getRotationMatrix2D((40,50), 30, 0.5)
print(A.dtype)

返回的是CV_64的数据类型

  1. 插值算法
    在这里插入图片描述
    在这里插入图片描述
    使用最邻近插值算法,图像会出现锯齿状,对图像放大效果会更明显;若x,y不为整数,选取离f(x,y)最近点的坐标值。

    双线性插值
    在这里插入图片描述
    在这里插入图片描述
    python实现

cv2.warpAffine(src, M, dsize, dst = None,flag = None, borderMode = None, borderValue = None)

src输入图像矩阵;M2行3列仿射变换矩阵,dsize二元元组(宽高),输出图像大小;flags插值法:INTE_NEAREST、INTE_LINEAR(默认)等;borderMode填充模式:BORDER_CONSTRANT等,borderValue当borderMode = BORDER_CONSTRANT的填充值

import cv2
import numpy as np 
import sys
import math 


#main function
if __name__ == "__main__":
	image_path = "C:\\Users\\Pictures\\Saved Pictures\\1.jpg"
	#"C:\\Users\\Pictures\\Saved Pictures\\1.jpg"
	#"C:/Users/Pictures/Saved Pictures/1.jpg"
	#R("C:\Users\Pictures\Saved Pictures\1.jpg")
	image = cv2.imread(image_path);
	image1 = cv2.imread(image_path, cv2.COLOR_GRAY2RGB)
	
	#Init image height, width
	h,w = image.shape[:2]
	#The affine transformation matrix shrinks by 2
	#125 s
	scalingMatrix = np.array([[0.5,0,0],[0,0.5,0]], np.float32)
	scalingMat = cv2.warpAffine(image, scalingMatrix, (w,h), borderValue = 125)

	#shrins by 2, translation
	scalingMatrix1 = np.array([[0.5,0,w/4],[0,0.5,h/4]],np.float32)
	scalingMat1 = cv2.warpAffine(image, scalingMatrix1, (w,h), borderValue=125)

	#base scalingMatrix1,rotate 30°
	scalingMatrix3 = cv2.getRotationMatrix2D((w/2,h/2),30, 1);
	scalingMat2 = cv2.warpAffine(scalingMat1, scalingMatrix3, (w,h), borderValue=125)
	cv2.imshow("scalingMat", scalingMat);
	cv2.imshow("scalingMat1", scalingMat1);
	cv2.imshow("scalingMat2", scalingMat2);
	cv2.waitKey(0)
	cv2.destroyAllWindows()

在这里插入图片描述
C++实现
使用warpAffine()函数,先创建仿射矩阵,resize()函数对图像进行放缩
void resize(InputArray src, OutArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR)
src:输入图像矩阵; dst:输出图像矩阵;dsize二元元组(宽高),输出图像大小;fx:在水平方向上缩放比例,默认值为0;fy:在垂直方向上缩放比例,默认值为0;flags插值法:INTE_NEAREST、INTE_LINEAR(默认)等;

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<string>
using namespace cv;

int main()
{
	std::string image_path = "C:\\Users\\Pictures\\Saved Pictures\\1.jpg";
	Mat image = imread(image_path, 1);											//default = 1,color;gray set to 0

	if (!image.data)
	{
		return -1;
	}

	Mat AffineMatrix = (Mat_<float>(2, 3) << 0.5, 0, 0, 0, 0.5, 0);
	Mat AffineMat;

	//shrink 1/2
	// method one
	warpAffine(image, AffineMat, AffineMatrix, Size(image.cols / 2, image.rows / 2));

	//method two
	Mat resizeMat;
	resize(image, resizeMat, Size(image.cols / 2, image.rows / 2), 0.5, 0.5);

	//display
	imshow("image", image);
	imshow("warpAffine", AffineMat);
	imshow("resize", resizeMat);

	waitKey(0);
	return 0;

}

在这里插入图片描述
旋转函数

void rotate(InputArray src,  OutArray dst, int rotateCode)
//rotateCode: ROTATE_90_CLOCKWISE, ROTATE_180, ROTATE_90_COUNTERCLOCKWISE

顺时针旋转90°,180°,270°

	#rotate 90°
	rotateImage = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
	cv2.imshow("rotateImage",rotateImage)
	//c++ code
	Mat rotateImage;
	rotate(image, rotateImage, ROTATE_180);
	imshow("rotateImage",rotateImage);

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aaron1996123456/article/details/100768687