图像缩放—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_32FC1 - interpolation: 表示插值方法
- 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);