zoukankan      html  css  js  c++  java
  • opencv旋转图像

    #include <opencv2opencv.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;
    }
    

      

     

  • 相关阅读:
    3B1B微分方程系列笔记(一)
    洛谷P1127 【词链】欧拉通路,欧拉回路+dfs
    龟速乘,快速乘法
    单调队列优化O(N)建BST P1377 [TJOI2011]树的序
    洛谷 p4302的dp中的细节讨论
    manacher(马拉车算法)
    博弈论(入门,持续更新)
    洛谷P1295 [TJOI2011]书架 线段树优化dp,单调栈
    洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化
    洛谷 P1131 [ZJOI2007]时态同步
  • 原文地址:https://www.cnblogs.com/alexYuin/p/9397476.html
Copyright © 2011-2022 走看看