c++代码
//旋转图像保证图像信息不丢失
bool rota_mat(cv::Mat inputMat, cv::Mat objectMask, cv::Mat &rotationMat){
vector<vector<cv::Point> > contours;
cv::findContours(objectMask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
double max_area = 0;
vector<cv::Point> max_contour;
for (size_t i=0; i<contours.size(); i++){
double contour_area = cv::contourArea(contours[i]);
if (contour_area > max_area){
max_area = contour_area;
max_contour = contours[i];
}
}
cv::RotatedRect minBox = cv::minAreaRect(max_contour);
cout << minBox.angle << " " << minBox.center << " " << minBox.size << endl;
//旋转校正
float angle_rotation;
if ((minBox.size.width / minBox.size.height) < 1)
angle_rotation = 90 + minBox.angle;//正数,逆时针旋转
else
angle_rotation = minBox.angle; //负数,顺时针旋转
// get rotation matrix for rotating the image around its center in pixel coordinates
// cv::Point2f center((inputMat.cols-1)/2.0, (inputMat.rows-1)/2.0);
cv::Point2f center(static_cast<float>(inputMat.cols /2.), static_cast<float>(inputMat.rows /2.));
cv::Mat rot = cv::getRotationMatrix2D(center, angle_rotation, 1.0);
// determine bounding rectangle, center not relevant
cv::Rect2f bbox = cv::RotatedRect(cv::Point2f(), inputMat.size(), angle_rotation).boundingRect2f();
// adjust transformation matrix
rot.at<double>(0,2) += bbox.width/2.0 - inputMat.cols/2.0;
rot.at<double>(1,2) += bbox.height/2.0 - inputMat.rows/2.0;
cv::warpAffine(inputMat, rotationMat, rot, bbox.size());
cv::imwrite("rotated_im.png", rotationMat);
return true;
}
c++
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
//旋转函数
Mat RotateImg(Mat image, double angle);
int main()
{
Mat image(101, 201, CV_8UC3, Scalar(0,0,255));
Mat imgOut = RotateImg(image, 45);
imshow("test", imgOut);
waitKey(0);
getchar();
return 0;
}
//旋转函数 旋转方向为逆时针为正
Mat RotateImg(Mat image, double 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);
//旋转矩阵
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.;
Mat imgOut;
if (image.channels() == 1)
{
cv::warpAffine(image, imgOut, m1,cv::Size(width_rotate,height_rotate), cv::INTER_LINEAR, 0, Scalar(255));
}
else if (image.channels() == 3)
{
cv::warpAffine(image, imgOut, m1,cv::Size(width_rotate, height_rotate), cv::INTER_LINEAR, 0, Scalar(255, 255, 255));
}
return imgOut;
}
opencv代码
import cv2
from math import *
def remote(img,degree):
#degree左转
img = cv2.imread(img)
height, width = img.shape[:2]
heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
matRotation = cv2.getRotationMatrix2D((width / 2, height / 2), degree, 1)
matRotation[0, 2] += (widthNew - width) / 2
matRotation[1, 2] += (heightNew - height) / 2
imgRotation = cv2.warpAffine(img, matRotation, (widthNew, heightNew), borderValue=(255, 255, 255))
cv2.imshow("img", img)
cv2.imshow("imgRotation", imgRotation)
cv2.waitKey(0)
remote('1.jpg',90)