本实验为计算机科学与技术学院计算机专业大四上限选课,2023-2024-1年度课程实验,较以往实验内容发生较大变化
本实验使用vs2019,c++语言,需要提前安装opencv,具体方法请自行搜索。
实验2:几何变换与变形
•
将一幅输入图像变换为任意一个指定的四边形形状(给定四边形
4
个顶点)。
–
提示:根据
4
个顶点的对应估计一个透视变换
H
,再用
H
对原图像进行形变(
OpenCV
相关函数:
getPerspectiveTransform
,
warpPerspective
等)
设计一个交互程序,可以编辑四边形顶点,并且顶点位置改变时图像形变的结果可以实时更新
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat Image, dstImg;//原图像、透视图像
Point2f srcPoint[4], dstPoint[4];//原图和透视图像的四个顶点
int back;
int newPoint;
void drawLine(Mat tmp)
{
line(tmp, dstPoint[0], dstPoint[1], Scalar(1, 230, 171), 5, 8);
line(tmp, dstPoint[1], dstPoint[2], Scalar(246, 1, 171), 5, 8);
line(tmp, dstPoint[2], dstPoint[3], Scalar(246, 230, 1), 5, 8);
line(tmp, dstPoint[3], dstPoint[0], Scalar(1, 230, 1), 5, 8);
}
void mouseHander(int event, int x, int y, int flags, void* p)
{
if (event == EVENT_LBUTTONDOWN)//左键按下
{
for (int i = 0; i < 4; i++)
{
if (abs(x - dstPoint[i].x) <= back/2 && abs(y - dstPoint[i].y) <= back/2)//判断有没有按倒某个顶点
{
newPoint = i;
break;
}
}
}
else if (event == EVENT_MOUSEMOVE && newPoint >= 0)//左键拖拽
{
dstPoint[newPoint].x = x ;
dstPoint[newPoint].y = y;
Mat tmp = dstImg.clone();
//绘制直线,以便知道拖拽后是什么样子
drawLine(tmp);
imshow("透视变换后", tmp);
}
else if (event == EVENT_LBUTTONUP && newPoint >= 0)//左键松开
{
Mat Trans = getPerspectiveTransform(srcPoint, dstPoint);
warpPerspective(Image, dstImg, Trans, Size(dstImg.cols, dstImg.rows));
imshow("透视变换后", dstImg);
newPoint = -1;
}
}
void Img()
{
srcPoint[0] = Point2f(0, 0);
srcPoint[1] = Point2f(Image.cols, 0);
srcPoint[2] = Point2f(Image.cols, Image.rows);
srcPoint[3] = Point2f(0, Image.rows);//原图四顶点
dstPoint[0] = Point2f(50, 50);
dstPoint[1] = Point2f(50 + Image.cols, 50);
dstPoint[2] = Point2f(50 + Image.cols, 50 + Image.rows);
dstPoint[3] = Point2f(50, 50 + Image.rows);//新图四顶点,先画出一个除了位置和原图一样的,防止更改原图,直接在新图操作
}
void main()
{
Image = imread("C:/Users/13441/Desktop/数字图像/back.png");
back = 20;
newPoint = -1;
Img();
dstImg = Mat::zeros(Size(150 + Image.cols, 150 + Image.rows), Image.type());
Mat Trans = getPerspectiveTransform(srcPoint, dstPoint);
Mat dst_perspective;
warpPerspective(Image, dstImg, Trans, Size(dstImg.cols, dstImg.rows));
imshow("原图像", Image);
imshow("透视变换后", dstImg);
setMouseCallback("透视变换后", mouseHander);//鼠标控制对新图改
waitKey();
}