opencv实战从0到N (5)—— 图像变换(仿射,透视)

opencv实战从0到N (5)—— 图像变换(仿射,透视)

仿射变换与透视变换

1,仿射变换其实是两个矩阵的乘法运算后再加上一个向量矩阵,它将一个矩阵向量映射到另一个向量空间,正如在二维空间中的条直线,

通过线性运算可以将其旋转(线性变换)和平移,也可以看作是坐标轴的改变(空间变换)。

在opencv中首先需要得到一个映射矩阵,利用映射矩阵将原图进行变换。常使用的函数有:

(1), getAffineTransform( srcTri, dstTri ); //根据两组三个点得到映射矩阵

(2), getRotationMatrix2D( center, angle, scale ); //根据旋转的中心,角度与比例得到映射矩阵

(3), warpAffine( src, warp_dst, warp_mat, warp_dst.size() );/// 对源图像对某个映射矩阵求得仿射变换

2,透视变换在仿射变换的基础上好像多了一个维度,仿射变换只是对图像的一个旋转,缩放,平移,透视变换貌似将图像在z轴上进行了扭曲操作。

同样在使用时需要得到一个映射矩阵,利用映射矩阵对原图进行变换。使用函数:

(1), getPerspectiveTransform( InputArray src, InputArray dst );//根据两组四个点得到映射矩阵

(2),perspectiveTransform(InputArray src, OutputArray dst, InputArray m ); //进行透视变换

 

3,仿射变换测试:

Point2f srcTri[3];

Point2f dstTri[3];



Mat rot_mat(2, 3, CV_32FC1);

Mat warp_mat(2, 3, CV_32FC1);

Mat src, warp_dst, warp_rotate_dst;

src = imread("2.jpg");



/// 设置目标图像的大小和类型与源图像一致

warp_dst = Mat::zeros(src.rows, src.cols, src.type());



/// 设置源图像和目标图像上的三组点以计算仿射变换

srcTri[0] = Point2f(0, 0);

srcTri[1] = Point2f(src.cols - 1, 0);

srcTri[2] = Point2f(0, src.rows - 1);



dstTri[0] = Point2f(src.cols*0.0, src.rows*0.33);

dstTri[1] = Point2f(src.cols*0.85, src.rows*0.25);

dstTri[2] = Point2f(src.cols*0.15, src.rows*0.7);

/// 求得仿射变换

warp_mat = getAffineTransform(srcTri, dstTri);

/// 对源图像应用上面求得的仿射变换

warpAffine(src, warp_dst, warp_mat, warp_dst.size());

/** 对图像扭曲后再旋转 */

/// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵

Point center = Point(warp_dst.cols / 2, warp_dst.rows / 2);

double angle = -50.0;

double scale = 0.6;

/// 通过上面的旋转细节信息求得旋转矩阵

rot_mat = getRotationMatrix2D(center, angle, scale);

/// 旋转已扭曲图像

warpAffine(warp_dst, warp_rotate_dst, rot_mat, warp_dst.size());

/// 显示结果

imshow("src", src);

imshow("warp", warp_dst);

imshow("dst", warp_rotate_dst);

 

 

 

4,透视变换测试:

Point2f srcTri[4];

Point2f dstTri[4];



Mat rot_mat(2, 3, CV_32FC1);

Mat pers_mat(2, 3, CV_32FC1);

Mat src, pers_dst;

src = imread("2.jpg");

imshow("src", src);

int img_height = src.rows;

int img_width = src.cols;

/// 设置目标图像的大小和类型与源图像一致

//pers_dst = Mat::zeros(src.rows, src.cols, src.type());



/// 设置源图像和目标图像上的三组点以计算仿射变换

srcTri[0] = Point2f(0, 0);

srcTri[1] = Point2f(src.cols - 1, 0);

srcTri[2] = Point2f(0, src.rows - 1);

srcTri[3] = Point2f(src.cols - 1, src.rows - 1);



dstTri[0] = Point2f(src.cols*0.0, src.rows*0.33);

dstTri[1] = Point2f(src.cols*0.85, src.rows*0.25);

dstTri[2] = Point2f(src.cols*0.15, src.rows*0.7);

dstTri[3] = Point2f(src.cols*0.85, src.rows*0.7);

/// 求得仿射变换

pers_mat = getPerspectiveTransform(srcTri, dstTri);

vector<Point2f> ponits, points_trans;

for (int i = 0;i<img_height;i++) {

for (int j = 0;j<img_width;j++) {

ponits.push_back(Point2f(j, i));

}

}



perspectiveTransform(ponits, points_trans, pers_mat);

Mat img_trans = Mat::zeros(img_height, img_width, CV_8UC3);

int count = 0;

for (int i = 0;i<img_height;i++) {

uchar* p = src.ptr<uchar>(i);

for (int j = 0;j<img_width;j++) {

int y = points_trans[count].y;

int x = points_trans[count].x;

uchar* t = img_trans.ptr<uchar>(y);

t[x * 3] = p[j * 3];

t[x * 3 + 1] = p[j * 3 + 1];

t[x * 3 + 2] = p[j * 3 + 2];

count++;

}

}

/// 显示结果

imshow("img_trans", img_trans);

 

更多内容关注微信公众号:ML_Study

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arthur.AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值