opencv(12)---图像几何变换

xiaoxiao2021-02-28  92

图像缩放—resize()

函数原型

src: 输入图像,Mat类型即可 dst: 输出图像,当其非0时,由dsize确定尺寸 dsize: Size类型,指定输出图像大小,如果它等于0,由下式计算: dsize = Size(round(fx*src.cols), round(fy*src.rows)) fx: 沿水平方向的缩放系数,默认值0,等于0时,由下式计算: (double)dsize.width/src.cols fy: 沿垂直方向的缩放系数,默认值0,等于0时,由下式计算: (double)dsize.height/src.rows interpolation: 用于指定插值方式,默认为INTER_LINEAR(线性插值)

插值方式

使用方式

方式一 指定dstImage.size()

ex1 Mat dstImg = Mat::zeros(512, 512, CV_8UC3); Mat srcImg = imread(“1.jpg”); Resize(srcImg, dstImg, dstImg.size());

方式二 不指定dstImage.size(),直接使用缩放系数

Mat dstImg ; Mat srcImg = imread(“1.jpg”); Resize(srcImg, dstImg, Size(), 0.5, 0.5);

头文件

#include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; using namespace std;

代码

resize(img,dstImage,Size(300,300));

图像平移

图像平移,信息丢失

原理

代码

/*图像平移*/ Mat imgTranslate(Mat& srcImg,int xOffset,int yOffset){ 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=i+yOffset; int y=j+xOffset; if(x>=0 && y>=0 && x<rows && y<cols){ dstImg.at<Vec3b>(x,y)=srcImg.at<Vec3b>(i,j); } } } return dstImg; }

运行结果

srcImage dstImage

图像平移,信息不丢失

原理 代码

Mat imgTranslate1(Mat& srcImg,int xOffset,int yOffset){ int rows=srcImg.rows+yOffset; int cols=srcImg.cols+xOffset; Mat dstImg=Mat::zeros(rows,cols,srcImg.type()); for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ int x=i+yOffset; int y=j+xOffset; if(x>=0 && y>=0 && x<rows && y<cols) dstImg.at<Vec3b>(x,y)=srcImg.at<Vec3b>(i,j); } } return dstImg; }

运行结果

图像旋转

基本概念

OpenCV没有提供直接旋转图像的函数 图像旋转可能会造成图像信息丢失 图像旋转可以用仿射变换来实现

方式一

使用函数

CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale ); CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());

代码

Mat srcImg=imread("D:\\1\\1.png"); Mat dstImage; //Point2f的两个参数,第一个为x,第二个为y Point2f center=Point2f(srcImg.cols/2,srcImg.rows/2); double angle=30; double scale=0.5; Mat roateM; roateM=getRotationMatrix2D(center,angle,scale);//获得旋转矩阵 warpAffine(srcImg,dstImage,roateM,Size(1000,800));

运行结果

方式二 transpose()

代码

transpose(srcImg,dstImage);//将行和列进行颠倒

运行结果

方式三 flip()

函数原型

CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode);

flipCode = 0, 垂直翻转(沿X轴翻转); flipCode > 0, 水平翻转(沿Y轴翻转); flipCode < 0, 水平垂直翻转(180°中心对称

作用 可以实现转置和镜像变换,以及90°,180°旋转

代码

flip(srcImg,dstImage,0);

运行结果

重映射—remap()

基本概念

映射是指把一个图像中的一个位置的像素通过映射关系转换到另一图像的指定 位置。对于输入原图像f(x, y), 目标图像g(x, y), 映射关系为T, 则满足下式:

g(x, y) = T(f(x, y))

函数原型

CV_EXPORTS_W void remap( InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar()); map1: 表示(x, y)点的坐标或x坐标,CV_16SC2, CV_32FC1,CV_32FC2类型map2: 表示(x, y)点y坐标,如果map1为(x, y),map2可以选择不用,可以是 CV_16UC1, CV_32FC1interpolation: 表示插值方法borderMode: 表示边界插值类型borderValue: 表示插值数值

代码

Mat srcImg=imread("D:\\1\\1.png"); Mat dstImage; int rows=srcImg.rows; int cols=srcImg.cols; Mat xMapImg=Mat::zeros(srcImg.size(),CV_32FC1);//map1 Mat yMapImg=Mat::zeros(srcImg.size(),CV_32FC1);//map2 for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ xMapImg.at<float>(i,j)=j;//保持列不变 //yMapImg.at<float>(i,j)=i+sin(j/10.0);//行发生改变 yMapImg.at<float>(i,j)=rows-i; } } remap(srcImg,dstImage,xMapImg,yMapImg,CV_INTER_LINEAR); imshow("img",srcImg); imshow("dstImage",dstImage);
转载请注明原文地址: https://www.6miu.com/read-18020.html

最新回复(0)