• c++视觉处理---仿射变换和二维旋转变换矩阵的函数


    仿射变换cv::warpAffine

    cv::warpAffineOpenCV中用于执行仿射变换的函数。仿射变换是一种线性变换,可用于执行平移、旋转、缩放和剪切等操作。下面是 cv::warpAffine 函数的基本用法:

    cv::warpAffine(src, dst, M, dsize, flags, borderMode, borderValue);
    
    • 1
    • src: 输入图像。
    • dst: 输出图像,用于存储仿射变换后的结果。
    • M: 2x3仿射变换矩阵,包含变换的参数。
    • dsize: 输出图像的尺寸。
    • flags: 插值方法,通常使用
      • cv::INTER_LINEAR 进行双线性插值。
      • cv::INTER_NEAREST 最近邻插值
      • cv::INTER_AREA 区域插值
      • cv::INTER_CUBIC 三次样条插值
      • cv::INTER_LANCZOS4 Lanczos插值
      • cv::CV_WARP_FILL_OUTLIERS 填充所有输出图像的象素。如果部分象素落在输入图像的边界 外,那么它们的值设定为 fillval
      • cv::CV_WARP_INVERSE_MAP 表示 M为输出图像到输入图像的反变换。因此可以直接用来做 象素插值。否则,warpAffine函数从M矩阵得到反变换
    • borderMode: 边界模式,可选参数,定义当像素越出图像边界时的处理方式,通常使用 cv::BORDER_CONSTANTcv::BORDER_REPLICATE
    • borderValue: 当 borderModecv::BORDER_CONSTANT 时使用,用于指定图像边界外的像素值。

    通过提供仿射变换矩阵 M,您可以指定图像的变换方式,包括平移、旋转、缩放和剪切等。然后,cv::warpAffine 函数会根据给定的变换参数将输入图像进行变换,输出结果保存在 dst 中。

    以下是一个简单的示例,演示如何使用 cv::warpAffine 进行图像的平移操作:

    #include 
    
    int main() {
        cv::Mat image = cv::imread("1.jpg", cv::IMREAD_COLOR);
    
        if (image.empty()) {
            std::cerr << "无法加载图像" << std::endl;
            return -1;
        }
    
        // 定义仿射变换矩阵(平移操作)
        cv::Mat warpMatrix = (cv::Mat_<double>(2, 3) << 1, 0, 50, 0, 1, 30);
    
        cv::Mat result;
        // 应用仿射变换
        cv::warpAffine(image, result, warpMatrix, image.size());
    
        cv::imshow("原始图像", image);
        cv::imshow("仿射变换后的图像", result);
        cv::waitKey(0);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这个示例中,我们定义了一个仿射变换矩阵 warpMatrix,该矩阵包含平移操作的参数。然后,我们使用 cv::warpAffine 函数将变换应用于原始图像,生成了变换后的结果。您可以根据需要修改 warpMatrix 中的值以实现不同的仿射变换效果。
    在这里插入图片描述

    二维旋转变换矩阵的函数:cv::getRotationMatrix2D

    cv::getRotationMatrix2D 是OpenCV中用于获取二维旋转变换矩阵的函数。这个函数用于构造一个仿射变换矩阵,该矩阵用于执行二维图像的旋转操作。下面是 cv::getRotationMatrix2D 函数的基本用法:

    cv::Mat cv::getRotationMatrix2D(cv::Point2f center, double angle, double scale);
    
    • 1
    • center: 旋转中心的坐标,通常是旋转图像的中心点。
    • angle: 旋转的角度(以度为单位)。
    • scale: 缩放因子,通常设置为1.0。

    函数返回一个2x3的仿射变换矩阵,该矩阵包含了旋转和缩放的参数。

    以下是一个示例,演示如何使用 cv::getRotationMatrix2D 函数构造旋转变换矩阵,然后应用该变换矩阵来旋转图像:

    #include 
    
    int main() {
        cv::Mat image = cv::imread("1.jpg", cv::IMREAD_COLOR);
    
        if (image.empty()) {
            std::cerr << "无法加载图像" << std::endl;
            return -1;
        }
    
        // 旋转中心坐标
        cv::Point2f center(image.cols / 2.0, image.rows / 2.0);
    
        // 旋转角度(以度为单位)
        double angle = 30;
    
        // 缩放因子
        double scale = 1.0;
    
        // 获取旋转变换矩阵
        cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, scale);
    
        cv::Mat result;
        // 应用仿射变换
        cv::warpAffine(image, result, rotationMatrix, image.size());
    
        cv::imshow("原始图像", image);
        cv::imshow("旋转后的图像", result);
        cv::waitKey(0);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这个示例中,我们使用 cv::getRotationMatrix2D 函数获取旋转变换矩阵,然后将该变换矩阵应用于原始图像,以实现旋转效果。您可以根据需要调整 centeranglescale 参数来执行不同的旋转和缩放操作。

    在这里插入图片描述

    综合案例

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    using namespace cv;
    #include 
    #include 
    using namespace cv; //包含cv命名空间
    #include 
    #define WINDOW_NAME1 " 【原始图窗口】 " //为窗口标题定义的宏
    #define WINDOW_NAME2 " 【经过 Warp后的图像】 " //为窗口标题定义的宏
    #define WINDOW_NAME3 " 【经过 Warp和 Rotate后的图像】 " //为窗口标题定
    static void ShowHelpText();
    /// 【main()函数】-------------------------- -
    // 描述: 控制台应用程序的入口函数, 我们的程序从这里开始执行
    int main()
    {
    	//【0】改变 console字体颜色
    	system("color 1A");
    	//【0】显示欢迎和帮助文字
    	ShowHelpText();
    	//【1】参数准备
    	//定义两组点, 代表两个三角形
    	Point2f srcTriangle[3];
    	Point2f dstTriangle[3];
    	//定义一些 Mat变量
    	Mat rotMat(2, 3, CV_32FC1);
    	Mat warpMat(2, 3, CV_32FC1);
    	Mat srcImage, dstImage_warp, dstImage_warp_rotate;
    	//【2】加载源图像并作一些初始化
    	srcImage = imread("1.jpg", 1);
    	if (!srcImage.data) { printf("读取图片错误, 请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    	// 设置目标图像的大小和类型与源图像一致
    	dstImage_warp = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());
    	//【3】设置源图像和目标图像上的三组点以计算仿射变换
    	srcTriangle[0] = Point2f(0, 0);
    	srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0);
    	srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1));
    	dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols * 0.0), static_cast<float>(srcImage.rows * 0.33));
    	dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols * 0.65), static_cast<float>(srcImage.rows * 0.35));
    	dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols * 0.15), static_cast<float>(srcImage.rows * 0.6));
    	//【4】求得仿射变换
    	warpMat = getAffineTransform(srcTriangle, dstTriangle);
    	//【5】对源图像应用刚刚求得的仿射变换
    	warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());
    	//【6】对图像进行缩放后再旋转
    	// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵
    	Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);
    	double angle = -30.0;
    	double scale = 0.8;
    	// 通过上面的旋转细节信息求得旋转矩阵
    	rotMat = getRotationMatrix2D(center, angle, scale);
    	// 旋转已缩放后的图像
    	warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());
    	//【7】显示结果
    	imshow(WINDOW_NAME1, srcImage);
    	imshow(WINDOW_NAME2, dstImage_warp);
    	imshow(WINDOW_NAME3, dstImage_warp_rotate);
    	// 等待用户按任意按键退出程序
    	waitKey(0);
    	return 0;
    }
    //一 【ShowHelpText()函数】---------------------- -
    // 描述: 输出一些帮助信息
    static void ShowHelpText()
    {
    	//输出一些帮助信息
    	printf("\n\n\n\t欢迎来到【仿射变换】示例程序~ \n\n");
    	//printf("\t当前使用的OpenCV版本为 OpenCV "CV_VERSION); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    在这里插入图片描述

  • 相关阅读:
    CentOS下安装及配置MySQL
    热门好用的API分享,含免费次数
    C语言实现希尔排序
    Jarvis OJ Webshell分析
    tomcat10.1.0源码分析
    SoftwareTest8 - 怎样测试一个系统的性能 ?
    TFT-LCD屏幕显示ASCII字符和字符串
    c++隐式类型转换存在的陷阱
    解决虚拟机联网问题
    内网渗透-内网环境下的横向移动总结
  • 原文地址:https://blog.csdn.net/qq_46107892/article/details/133764257