使用C++编写一个程序,不能调用opencv,实现对输入图像进行仿射变换的功能。 要求: 1. 使用C++语言来实现程序。 2. 程序需提供平移、旋转、缩放、剪切,对图像进行仿射变换。 3. 程序应该显示变换后的图像。 4.调整变换参数并观察结果。
时间: 2024-02-27 22:52:41 浏览: 132
基于OpenCV与C++实现仿射变换,包括旋转,平移,缩放,偏移、组合变换
以下是一个使用 C++ 编写的程序,实现对输入图像进行仿射变换的功能,不调用 OpenCV 库。该程序可以实现平移、旋转、缩放、剪切等仿射变换,并显示变换后的图像。您可以根据自己的需求进行调整变换参数并观察结果。
```c++
#include <iostream>
#include <cmath>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
// 仿射变换函数
void AffineTransform(Mat& src, Mat& dst, double a, double b, double c, double d, double tx, double ty)
{
// 获取输入图像的大小
int rows = src.rows;
int cols = src.cols;
// 计算仿射变换矩阵
double m[2][3] = { {a, b, tx}, {c, d, ty} };
// 计算输出图像的大小
int new_rows = ceil(abs(d) * rows + abs(b) * cols);
int new_cols = ceil(abs(a) * cols + abs(c) * rows);
// 创建输出图像
dst = Mat::zeros(new_rows, new_cols, src.type());
// 对每个像素进行仿射变换
for (int i = 0; i < new_rows; i++)
{
for (int j = 0; j < new_cols; j++)
{
// 计算对应输入图像的坐标
double x = m[0][0] * j + m[0][1] * i + m[0][2];
double y = m[1][0] * j + m[1][1] * i + m[1][2];
// 判断坐标是否越界
if (x >= 0 && x < cols && y >= 0 && y < rows)
{
// 双线性插值计算像素值
int x1 = floor(x);
int x2 = x1 + 1;
int y1 = floor(y);
int y2 = y1 + 1;
double u = x - x1;
double v = y - y1;
uchar* p1 = src.ptr<uchar>(y1);
uchar* p2 = src.ptr<uchar>(y2);
double val1 = (1 - u) * p1[x1] + u * p1[x2];
double val2 = (1 - u) * p2[x1] + u * p2[x2];
dst.at<uchar>(i, j) = (uchar)((1 - v) * val1 + v * val2);
}
}
}
}
int main()
{
// 读取输入图像
Mat src = imread("input.jpg", IMREAD_GRAYSCALE);
if (src.empty())
{
cout << "无法读取输入图像" << endl;
return -1;
}
// 显示原始图像
imshow("原始图像", src);
// 仿射变换参数
double a = 1.0, b = 0.0, c = 0.0, d = 1.0, tx = 0.0, ty = 0.0;
// 平移变换
tx = src.cols * 0.2;
ty = src.rows * 0.2;
Mat shift_dst;
AffineTransform(src, shift_dst, a, b, c, d, tx, ty);
imshow("平移变换", shift_dst);
// 旋转变换
double angle = -30.0;
double scale = 1.0;
Point center = Point(src.cols / 2, src.rows / 2);
Mat rot_mat = getRotationMatrix2D(center, angle, scale);
Mat rot_dst;
warpAffine(src, rot_dst, rot_mat, src.size());
a = rot_mat.at<double>(0, 0);
b = rot_mat.at<double>(0, 1);
c = rot_mat.at<double>(1, 0);
d = rot_mat.at<double>(1, 1);
tx = rot_mat.at<double>(0, 2);
ty = rot_mat.at<double>(1, 2);
AffineTransform(rot_dst, rot_dst, a, b, c, d, tx, ty);
imshow("旋转变换", rot_dst);
// 缩放变换
scale = 2.0;
Mat scale_dst;
resize(src, scale_dst, Size(), scale, scale);
a = scale;
b = 0.0;
c = 0.0;
d = scale;
tx = 0.0;
ty = 0.0;
AffineTransform(scale_dst, scale_dst, a, b, c, d, tx, ty);
imshow("缩放变换", scale_dst);
// 剪切变换
a = 1.0;
b = 0.5;
c = 0.3;
d = 1.0;
tx = 0.0;
ty = 0.0;
Mat shear_dst;
AffineTransform(src, shear_dst, a, b, c, d, tx, ty);
imshow("剪切变换", shear_dst);
waitKey(0);
return 0;
}
```
注意:程序中的输入图像为 "input.jpg",需根据实际情况进行修改。
阅读全文