仿射变换,又称仿射映射。对图像的坐标向量进行一次线性变换和平移。特点是变换前后图像保持平直性(直线变换后任然是直线)和平行性(平行线变换后任然是平行线)。也就是二维平面上点的相对位置保持不变。
常见的仿射变换有:
具体的原理和公式推导都不难,详细可见一下博客,写得逻辑清楚,通俗易懂。
opencv学习(三十五)之仿射变换warpAffine
OpenCV2:图像的几何变换,平移、镜像、缩放、旋转(2)
OpenCV仿射变换+投射变换+单应性矩阵
OpenCV探索之路(八):重映射与仿射变换
opencv之仿射变换
opencv相关函数
void cv::warpAffine (
InputArray src,
OutputArray dst,
InputArray M,
Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
Mat getAffineTransform(
const Point2f src[],
const Point2f dst[] );
Mat cv::getRotationMatrix2D ( Point2f center,
double angle,
double scale
)
void remap(
InputArray src,
OutputArray dst,
InputArray map2,
int interpolation,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());
相关函数的用法和解释见一下博客:
opencv学习(三十五)之仿射变换warpAffine
OpenCV探索之路(八):重映射与仿射变换
/**************
旋转和缩放变换
srcimg,dstimg,offset 必须大小相同
offset 为CV_32F2C
**************/
void ImageTransform::rotationAndScale_form(Mat &srcimg, Mat &dstimg, Mat &offset, double angle, double scale)
{
Point center = Point2f(float(srcimg.cols / 2), float(srcimg.rows / 2));
Mat rotMat = getRotationMatrix2D(center, angle, scale);
warpAffine(srcimg, dstimg, rotMat, dstimg.size());
double *data = rotMat.ptr<double>(0, 0);
for (int row = 0; row < srcimg.rows; row++)
{
for (int col = 0; col < srcimg.cols; col++)
{
float x = static_cast<float>(col*data[0] + row*data[1] + data[2]);
float y = static_cast<float>(col*data[3] + row*data[4] + data[5]);
float dx = x - col;
float dy = y - row;
offset.at(row, col) = Vec2f(dy, dx);
}
}
return;
}
/**************
仿射变换
srcimg,dstimg,offset 必须大小相同
offset 为CV_32F2C
**************/
void ImageTransform::warp_form(Mat &srcimg, Mat &dstimg, Mat &offset)
{
Point2f srcTri[3];
Point2f dstTri[3];
srcTri[0] = Point2f(0.0, 0.0);
srcTri[1] = Point2f(static_cast<float>(srcimg.cols - 1), 0.0);
srcTri[2] = Point2f(0.0, static_cast<float>(srcimg.rows - 1));
dstTri[0] = Point2f(static_cast<float>(srcimg.cols * 0.0), static_cast<float>(srcimg.rows * 0.33));
dstTri[1] = Point2f(static_cast<float>(srcimg.cols * 0.65), static_cast<float>(srcimg.rows * 0.35));
dstTri[2] = Point2f(static_cast<float>(srcimg.cols * 0.15), static_cast<float>(srcimg.rows * 0.6));
Mat matWarp = getAffineTransform(srcTri, dstTri);
warpAffine(srcimg, dstimg, matWarp, dstimg.size());
double *data = matWarp.ptr<double>(0, 0);
for (int row = 0; row < srcimg.rows; row++)
{
for (int col = 0; col < srcimg.cols; col++)
{
float x = static_cast<float>(col*data[0] + row*data[1] + data[2]);
float y = static_cast<float>(col*data[3] + row*data[4] + data[5]);
float dx = x - col;
float dy = y - row;
offset.at(row, col) = Vec2f(dy, dx);
}
}
return;
}