opencv旋转图像
#include <opencv2\opencv.hpp>
/*
@param o The customer origin
@param x The customer x
@Note
The return matrix include translation
*/
cv::Mat ZRotationMatrix(const cv::Point2d o, const cv::Point2d x)
{
cv::Mat Rz = cv::Mat::zeros(3, 3, CV_32FC1);
Rz.at<float>(2, 2) = 1.0;
double theta = std::atan((x.y - o.y) / (x.x - o.x));
Rz.at<float>(0, 0) = std::cos(theta);
Rz.at<float>(1, 0) = std::sin(theta);
Rz.at<float>(0, 1) = -Rz.at<float>(1, 0);
Rz.at<float>(1, 1) = Rz.at<float>(0, 0);
// Adding Translation
Rz.at<float>(0, 2) = static_cast<float>(x.x);
Rz.at<float>(1, 2) = static_cast<float>(x.y);
Rz.at<float>(2, 2) = 0;
return Rz;
}
/*
Called by Rotation()
*/
std::pair<int, int> dstImageRegion(const cv::Mat points )
{
CV_Assert(points.size() == cv::Size(4, 3));
float maxRow(0.0), maxCol(0.0);
for (size_t i=0; i<4; ++i)
{
// x
maxCol = maxCol < points.at<float>(0, i) ? points.at<float>(0, i) : maxCol;
// y
maxRow = maxRow < points.at<float>(1, i) ? points.at<float>(1, i) : maxRow;
}
return {maxRow, maxCol};
}
/*
@Param Rz It includes the translation also!
*/
cv::Mat Rotation(const cv::Mat src, const cv::Mat Rz)
{
// get region of dst
cv::Mat Corners_src((cv::Mat_<float>(3,4) << 0, src.cols, 0, src.cols,
0, 0, src.rows, src.rows,
1, 1, 1, 1
));
cv::Mat Corners_dst = Rz * Corners_src;
std::pair<int, int> size_dst = dstImageRegion(Corners_dst);
cv::Mat dst = cv::Mat::zeros(size_dst.first, size_dst.second, src.type());
// Rz is the matrix from src to dst. The inverse matrix is needed to reconstruct dst.
cv::Mat Rz_inv = Rz.clone();
// The inverse matrix of Rotation is the same as its transpose matrix.
Rz_inv.at<float>(0, 1) = Rz.at<float>(1, 0);
Rz_inv.at<float>(1, 0) = Rz.at<float>(0, 1);
// Set pixels value
for (size_t j=0; j<dst.rows; ++j)
{
for (size_t i = 0; i < dst.cols; ++i)
{
cv::Mat tp_src = Rz_inv * cv::Mat((cv::Mat_<float>(3,1) << i,j,1));
int Idx_src(cvRound(tp_src.at<float>(0))), Idy_src(cvRound(tp_src.at<float>(1)));
if (Idx_src<0.0 || Idx_src>=src.cols || Idy_src<0.0 || Idy_src>=src.rows)
continue;
dst.at<float>(j, i) = src.at<float>(Idy_src, Idx_src);
}
}
return dst;
}
int main()
{
cv::Mat img = cv::imread("1.PNG", CV_LOAD_IMAGE_GRAYSCALE);
img.convertTo(img, CV_32FC1);
//
cv::Mat Rz = ZRotationMatrix(cv::Point2d(10,10), cv::Point2d(20, 5));
cv::Mat img_d = Rotation(img, Rz);
return 0;
}

浙公网安备 33010602011771号