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

本实验为计算机科学与技术学院计算机专业大四上限选课,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();
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值