【opencv学习之二十三】OpenCV图像几何变换

本文介绍了图像处理中常见的几何变换操作,包括图像的放缩、平移、旋转、置换和镜像以及重映射等,并提供了具体的实现代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图像的几何变换是基本但是也是常用到的一些操作,下面简单做一下总结:

1.放缩图像resize()函数:

   //图像缩放(resize函数)
    Mat srcImg = imread("D:/2.jpg");
    Mat dstImg;
    resize(srcImg,dstImg,Size(),0.5,0.5);//将原图像宽高缩放为0.5.
    //    resize(srcImg,dstImg,Size(srcImg.cols/2,srcImg.rows/2),0,0);//同样将图像缩小为0.5
    //dsize和fx、fy不能同时为0。fx、fy是沿x轴和y轴的缩放系数;
    //@param dsize output image size; if it equals zero, it is computed as:
    //\f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f]
    imshow("src", srcImg);
    imshow("dst", dstImg);
    // imwrite("D:/q1.jpg", dstImg); //保存图片
    waitKey(0);
效果如下:

2.图像平移,其中一种方法是将原图的像素点置换到对应保存图像的内点+x值图像

代码如下:

//图像平移
        Mat srcImg = imread("D:/2.jpg");
        int xOffset=100;
        int  yOffset=20;
        int rows = srcImg.rows; //
        int cols = srcImg.cols;//
        Mat dstImg = Mat::zeros(srcImg.size(), srcImg.type());  //创建全黑目标图像,同源图像一样大
        for (int i = 0; i < rows; i++)//遍历式平移
        {
            for (int j = 0; j < cols; j++)
            {
                int x = j + xOffset;
                int y = i +yOffset;
                if (x >= 0 && y >= 0 && x < cols && y < rows)//溢出保护
                {
                    dstImg.at<Vec3b>(y, x) = srcImg.at<Vec3b>(i, j);
                }
            }
        }
        imshow("src", srcImg);
        imshow("dst", dstImg);
        //imwrite("D:/q2.jpg", dstImg); //保存结果图片
        waitKey(0);
效果如下:


3.图像旋转,一要通过getRotationMatrix2D()获得旋转矩阵,然后通过warpAffine()仿射变换将图像移动到指定中心,也就是说warpAffine()也可平移图像,当然具体什么是仿射变换可以网上搜索了解更详细的;

下面是代码:

    //图像旋转(getRotationMatrix2D函数和warpAffine函数配合使用)
    //利用getRotationMatrix2D函数获得二维旋转矩阵,再用warpAffine设置目标图像大小完成旋转
    //仿射变换”就是:“线性变换”+“平移”
    Mat srcImg = imread("D:/2.jpg");
    //        Point2f center = Point2f(srcImg.cols/2, srcImg.rows/2); //定义旋转中心坐标
    Point2f center = Point2f(400, 100); //定义旋转中心坐标
    double angle = 30; //旋转角度
    double scale = 0.8; //缩放比例
    Mat roateM;
    roateM = getRotationMatrix2D(center, angle, scale); // 获得旋转矩阵
    Mat dstImg;
    warpAffine(srcImg, dstImg, roateM, Size(500, 500)); // 仿射变换
    imshow("src", srcImg);
    imshow("dst", dstImg);
    //        imwrite("D:/q3.jpg", dstImg); //保存结果图片
    waitKey(0);
效果:

4.置换和镜像操作flip()函数:

   //转置和镜像(转置用transpose函数,镜像用flip函数)
    Mat srcImg = imread("D:/2.jpg");
    Mat dstImg;
    //下两行结合可达到逆时针旋转90度的效果
    transpose(srcImg, dstImg); //转置(行列互换)
    flip(dstImg, dstImg, 0); //镜像,0代表沿X轴翻转;>0代表沿Y轴反转;<0代表沿中心翻转
    imshow("src", srcImg);
    imshow("dst", dstImg);
    waitKey(0);
效果:

5.重映射操作remap()函数,有点类似前面的平移操作,但是mat上存储并操作,函数帮助处理了一些溢出等操作;简单说就是遍历操作的数据存储在mat里,然后通过remap(),重新合成;类似平移放缩等操作均可以这样操作了;

代码如下:

   //重映射(remap函数)
    Mat srcImage = imread("D:/2.jpg");
    Mat dstImage,map_x,map_y;
    //创建和原始图像一样的效果图,x重映射图,y重映射图
    dstImage.create(srcImage.size(),srcImage.type());
    map_x.create(srcImage.size(),CV_32FC1); //    map_x=Mat::zeros(srcImage.size(), CV_32FC1);
    map_y.create(srcImage.size(),CV_32FC1);  //    map_y=Mat::zeros(srcImage.size(), CV_32FC1);
    //双层循环,遍历每一个像素点,改变map_x和map_y的值
    for (int i = 0; i < srcImage.rows; i++)
    {
        for (int j = 0; j <srcImage.cols; j++)
        {
            //1.Y坐标.波浪效果.
            map_x.at<float>(i, j) = j; //X坐标.保持列不变,
            map_y.at<float>(i, j) = i + 10 * sin(j/10.0);//Y坐标.波浪效果.          
            //            //2.水平对称
            //            map_x.at<float>(i,j) = j;
            //            map_y.at<float>(i,j) = srcImage.rows-i;//关于x轴对称的效果
            //            //3.垂直对称
            //            map_x.at<float>(i,j) =srcImage.cols- j;
            //            map_y.at<float>(i,j) = i;
            //            //4.上下左右对称
            //            map_x.at<float>(i,j) =srcImage.cols- j;
            //            map_y.at<float>(i,j) =srcImage.rows-i;
            //            //5.缩小图像
            //            if( i > srcImage.cols*0.25 && i < srcImage.cols*0.75 && j > srcImage.rows*0.25 && j <srcImage.rows*0.75 )
            //            {
            //                map_x.at<float>(j,i) = 2*( i - srcImage.cols*0.25 ) + 0.5 ;
            //                map_y.at<float>(j,i) = 2*( j - srcImage.rows*0.25 ) + 0.5 ;
            //            }
        }
    }
    //进行重映射操作
    remap(srcImage,dstImage,map_x,map_y,CV_INTER_LINEAR,BORDER_CONSTANT,Scalar(0,0,0));
    //显示效果图
    imshow("dst",dstImage);
    imshow("src",srcImage);
    //    imwrite("D:/q4.jpg", dstImage); //保存结果图片
    waitKey(0);
效果如下:






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值