Advertisement

山东大学数字图像处理实验(二) 计算机学院

阅读量:
本实验为计算机科学与技术学院计算机专业大四上限选课,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();
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-17/PbqUDoIK2zm3xg8VGCSl5aTYns4e.png)

全部评论 (0)

还没有任何评论哟~