opencv仿射变换

#include <opencv2/opencv.hpp>

/*

功能:对一系列坐标点进行平移仿射变换

参数:

srcPoints:输入点坐标

dstPoints:变换后的点坐标

x:x方向平移的距离

y:y方向平移的距离

*/

void tranlatePoints(std::vector<cv::Point2f>& srcPoints, std::vector<cv::Point2f>& dstPoints,double x,double y)

{

cv::Mat affineMatrix = (cv::Mat_<double>(2, 3) << 1, 0, x, 0, 1,y);

cv::transform(srcPoints, dstPoints, affineMatrix);

}

/*

功能:对一系列点进行旋转仿射变换

参数:

srcPoints:输入点坐标

dstPoints:变换后的点坐标

basePoint:旋转基准点

zoomRate:缩放比例,默认为1表示不缩放

*/

void rotatePoints(std::vector<cv::Point2f>& srcPoints, std::vector<cv::Point2f>& dstPoints, cv::Point& basePoint,int degree, float zoomRate=1)

{

cv::Mat affineMatrix = cv::getRotationMatrix2D(basePoint,degree,zoomRate);

cv::transform(srcPoints, dstPoints, affineMatrix);

}

/*

功能:对一系列点进行缩放仿射变换

参数:

srcPoints:输入点坐标

dstPoints:变换后的点坐标

basePoint:缩放基准点

zoomRate:缩放比例

*/

void zoomPoints(std::vector<cv::Point2f>& srcPoints, std::vector<cv::Point2f>& dstPoints, cv::Point& basePoint,float zoomRate)

{

cv::Mat affineMatrix = cv::getRotationMatrix2D(basePoint,0,zoomRate);

cv::transform(srcPoints, dstPoints, affineMatrix);

}

/*

功能:对一张图片进行平移

参数:

src:要平移的图片

dst:平移的结果

x:x方向平移的距离

y:y方向平移的距离

*/

void translateImage(cv::Mat& src, cv::Mat& dst, double x, double y)

{

cv::Mat M = (cv::Mat_<double>(2, 3) << 1, 0, x, 0, 1, y);

cv::warpAffine(src, dst, M, src.size());

}

/*

功能:对一张图片进行旋转

参数:

image:输入图像

imgOut:旋转后的图像

angle:旋转角度

*/

void rotateImage(cv::Mat& image, cv::Mat& imgOut, int angle)

{

/*

对旋转的进行改进,由于图形是一个矩形,旋转后的新图像的形状是一个原图像的外接矩形

因此需要重新计算出旋转后的图形的宽和高

*/

int width = image.cols;

int height = image.rows;

double radian = angle * CV_PI / 180.;//角度转换为弧度

double width_rotate = fabs(width*cos(radian)) + fabs(height*sin(radian));

double height_rotate = fabs(width*sin(radian)) + fabs(height*cos(radian));

//旋转中心 原图像中心点

cv::Point2f center((float)width / 2.0, (float)height / 2.0);

//旋转矩阵

cv::Mat m1 = cv::getRotationMatrix2D(center, angle, 1.0);

//m1为2行3列通道数为1的矩阵

//变换矩阵的中心点相当于平移一样 原图像的中心点与新图像的中心点的相对位置

m1.at<double>(0, 2) += (width_rotate - width) / 2.;

m1.at<double>(1, 2) += (height_rotate - height) / 2.;

if (image.channels() == 1)

{

cv::warpAffine(image, imgOut, m1, cv::Size(width_rotate, height_rotate), cv::INTER_LINEAR, 0, cv::Scalar(0));

}

else if (image.channels() == 3)

{

cv::warpAffine(image, imgOut, m1, cv::Size(width_rotate, height_rotate), cv::INTER_LINEAR, 0, cv::Scalar(0,0,0));

}

}

/*

功能:对一张图片进行缩放

参数:

src:输入图像

dst:缩放后的图像

basePoint:缩放基准点

zoomRate:缩放比例

*/

void zoomImage(cv::Mat& src, cv::Mat& dst, cv::Point& rotaPoint, float zoomRate)

{

cv::Mat M = cv::getRotationMatrix2D(rotaPoint, 0, zoomRate);

cv::warpAffine(src, dst, M, src.size());

}

//#define TESTPOINTS

#define TESTIMAGE

int main() {

#ifdef TESTPOINTS

// 创建原始点集

std::vector<cv::Point2f> srcPoints = { cv::Point2f(100, 100), cv::Point2f(200, 200), cv::Point2f(300, 300) };

//变换点集

std::vector<cv::Point2f> dstPoints;

//tranlatePoints(srcPoints, dstPoints, 10, 10);

cv::Point point(0, 0);

//rotatePoints(srcPoints, dstPoints, point,180);

//zoomPoints(srcPoints, dstPoints, point, 0.5);

// 输出结果

std::cout << "原始点集: ";

for (const auto& point : srcPoints) {

std::cout << point << " ";

}

std::cout << std::endl;

std::cout << "仿射变换后的点集: ";

for (const auto& point : dstPoints) {

std::cout << point << " ";

}

std::cout << std::endl;

#endif // TESTPOINTS

#ifdef TESTIMAGE

cv::Mat img1 = cv::imread("D:/20240103141532.png");

cv::Mat dst;

//translateImage(img1, dst, -50, 50);

//cv::imshow("src",img1);

//cv::imshow("1", dst);

//cv::waitKey(0);

//for (int i = 0; i < 36; i++)

//{

// rotateImage(img1, dst,i * 10);

// cv::imshow("1", dst);

// cv::waitKey(0);

//}

//int width = img1.cols;

//int height = img1.rows;

//cv::Point basePoint((float)width / 2.0, (float)height / 2.0);

//zoomImage(img1, dst, basePoint, 0.5);

//cv::imshow("src", img1);

//cv::imshow("1", dst);

//cv::waitKey(0);

#endif // TESTIMAGE

return 0;

}

相关推荐
zenRRan17 分钟前
Qwen2.5-VL Technical Report!!! 操作手机电脑、解析化学公式和乐谱、剪辑电影等,妥妥六边形战士 !...
人工智能
让我安静会25 分钟前
Obsidian·Copilot 插件配置(让AI根据Obsidian笔记内容进行对话)
人工智能·笔记·copilot
Allen_LVyingbo30 分钟前
Scrum方法论指导下的Deepseek R1医疗AI部署开发
人工智能·健康医疗·scrum
Watermelo6171 小时前
从DeepSeek大爆发看AI革命困局:大模型如何突破算力囚笼与信任危机?
人工智能·深度学习·神经网络·机器学习·ai·语言模型·自然语言处理
Donvink1 小时前
【DeepSeek-R1背后的技术】系列九:MLA(Multi-Head Latent Attention,多头潜在注意力)
人工智能·深度学习·语言模型·transformer
计算机软件程序设计1 小时前
深度学习在图像识别中的应用-以花卉分类系统为例
人工智能·深度学习·分类
Ainnle1 小时前
企业级RAG开源项目分享:Quivr、MaxKB、Dify、FastGPT、RagFlow
人工智能·开源
小天努力学java2 小时前
AI赋能传统系统:Spring AI Alibaba如何用大模型重构机票预订系统?
人工智能·spring
Fuweizn2 小时前
在工业生产中,物料搬运环节至关重要,搬运机器人开启新篇章
人工智能·智能机器人·复合机器人
技术员阿伟2 小时前
《AI赋能星际探索:机器人如何开启宇宙新征程!》
人工智能