图像几何变换:
1.图像缩放:resize()函数
2.图像平移:
(1)大小不变,信息丢失;
(2)大小改变,信息保留
3.图像旋转:getRotationMatrix2D()函数和warpAffine()函数
4.转置:transpose()函数
5.镜像:flip()函数
6.重映射:remap()函数
一,图像缩放
void resize( InputArray src, OutputArray dst,Size dsize, double fx = 0, double fy = 0,
int interpolation = INTER_LINEAR );
src:输入,原图像,即待改变大小的图像;
dst:输出,改变大小之后的图像
dsize:输出图像的大小。如果这个参数不为0,那么就代表将原图像缩放到这个Size(width,height)指定的大小;如果这个参数为0,指定好fx和fy的值,比如fx=fy=0.5,那么就相当于把原图两个方向缩小一倍!
interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:
INTER_NEAREST - 最邻近插值
INTER_LINEAR - 双线性插值
INTER_CUBIC - 4x4像素邻域内的双立方插值
INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值
图像缩放代码如下:
#include
#include <cv.h>
#include <highgui.h>
#include <windows.h>using namespace std;
using namespace cv;int main(int argc, char** argv)
{
Mat img1 = imread(“1.jpg”,CV_LOAD_IMAGE_COLOR);
Mat img2;
namedWindow(“img1”); //创建窗口
imshow(“img1”, img1);
namedWindow(“img2”); //创建窗口
resize(img1, img2, Size(0, 0),0.5,0.5);//定义Size就不要定义fx和fy
imshow(“img2”, img2);
waitKey(0);
}
运行结果如下:
二、图像平移:
(1)大小不变,信息丢失;
代码如下:
#include
#include <cv.h>
#include <highgui.h>
#include <windows.h>
using namespace std;
using namespace cv;Mat imgTranslate1(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 = j + xOffset;
int y = i + yOffset;
if (x >= 0 && y >= 0 && x < cols && y < rows)//溢出保护
{
dstImg.at(y, x) = srcImg.at(i, j);
}
}
}
运行结果如下:
(2)大小改变,信息保留
代码如下:
#include
#include <cv.h>
#include <highgui.h>
#include <windows.h>
using namespace std;
using namespace cv;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 = j + xOffset;
int y = i + yOffset;
if (x >= 0 && y >= 0 && x < cols && y < rows)//溢出保护
{
dstImg.at(y, x) = srcImg.at(i, j);
}
}
}
return dstImg;
}
int main(int argc, char** argv)
{
Mat img1 = imread(“1.jpg”, CV_LOAD_IMAGE_COLOR);
Mat dstImg = imgTranslate1(img1, 20, 30);
Mat img2;
namedWindow(“img1”); //创建窗口
imshow(“img1”, img1);
imshow(“dstImg”, dstImg);
waitKey(0);
}
运行结果如下:
3.图像旋转:
主要用于获得图像绕着 某一点的旋转矩阵
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
参数详解:
Point2f center:表示旋转的中心点
double angle:表示旋转的角度
double scale:图像缩放因子
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
参数详解:
src为输入图像
dst为变换后图像,类型与src一致。
M为变换矩阵,需要通过其它函数获得,当然也可以手动输入。
dsize为输出图像的大小
flags,插值算法
实例代码如下:
#include
#include <cv.h>
#include <highgui.h>
#include <windows.h>using namespace std;
using namespace cv;int main(int argc, char** argv)
{
Mat img1 = imread(“1.jpg”, CV_LOAD_IMAGE_COLOR);
Point2f center = Point2f(img1.cols / 2, img1.rows / 2); //定义旋转中心坐标
double angle = 30; //旋转角度
double scale = 0.5; //缩放比例
Mat roateM;
roateM = getRotationMatrix2D(center, angle, scale); // 获得旋转矩阵
Mat dstImg;
warpAffine(img1, dstImg, roateM, Size(600, 600)); // 仿射变换
imshow(“img1”, img1);
imshow(“dst”, dstImg);
waitKey(0);
}
运行结果如下:
4.转置:
5.镜像:
代码如下:
#include
#include <cv.h>
#include <highgui.h>
#include <windows.h>
using namespace std;
using namespace cv;int main(int argc, char** argv)
{
Mat img1 = imread(“1.jpg”, CV_LOAD_IMAGE_COLOR);
Mat dstImg;
transpose(img1, dstImg); //转置(行列互换)
flip(dstImg, dstImg, 0); //镜像,0代表沿X轴翻转;>0代表沿Y轴反转;<0代表沿中心翻转
imshow(“img1”, img1);
imshow(“dst”, dstImg);
waitKey(0);
}
运行结果如下:
6.重映射 :
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, intborderMode = BORDER_CONSTANT,const Scalar& borderValue = Scalar())
参数详解:
第一个参数:输入图像,即原图像,需要单通道8位或者浮点类型的图像
第二个参数:输出图像,即目标图像,需和原图形一样的尺寸和类型
第三个参数:它有两种可能表示的对象:(1)表示点(x,y)的第一个映射;(2)表示CV_16SC2,CV_32FC1等
第四个参数:它有两种可能表示的对象:(1)若map1表示点(x,y)时,这个参数不代表任何值;(2)表示 CV_16UC1,CV_32FC1类型的Y值
第五个参数:插值方式,有四中插值方式:
(1)INTER_NEAREST——最近邻插值
(2)INTER_LINEAR——双线性插值(默认)
(3)INTER_CUBIC——双三样条插值(默认)
(4)INTER_LANCZOS4——lanczos插值(默认)
第六个参数:边界模式,默认BORDER_CONSTANT
第七个参数:边界颜色,默认Scalar()黑色
实例代码如下:
#include
#include <cv.h>
#include <highgui.h>
#include <windows.h>using namespace std;
using namespace cv;int main(int argc, char** argv)
{
Mat img1 = imread(“1.jpg”, CV_LOAD_IMAGE_COLOR);
Mat dstImg;
int rows = img1.rows;
int cols = img1.cols;
Mat xMapImg = Mat::zeros(img1.size(), CV_32FC1); //map1
Mat yMapImg = Mat::zeros(img1.size(), CV_32FC1); //map2
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
xMapImg.at(i, j) = j; //X坐标.保持列不变,
yMapImg.at(i, j) = i + 5 * sin(j/10.0);//Y坐标.波浪效果.
//yMapImg.at(i, j) = rows - i;//这样实现的是关于x轴对称的效果
}
remap(img1, dstImg, xMapImg, yMapImg, CV_INTER_LINEAR);
imshow(“img1”, img1);
imshow(“dst”, dstImg);
waitKey(0);
}
运行结果如下: