旋转图形效果,旋转后按步骤一再处理一次即可
#include<opencv2/opencv.hpp>
#include<math.h>
#include<iostream>
using namespace cv;
using namespace std;
Mat src2;
Mat src,dst,gray_src,temp,dst1;
const char* output_win = "output_img";
RNG rng(12345);
int threshold_v = 100;
int threshold_max = 255;
void Demo_Moments(int, void*);
//当图片有旋转角度时的处理函数
void Check_Skew(int, void*);
int main(int argc, char** argv) {
src = imread("C:/Users/18929/Desktop/博客项目/项目图片/12.jpg");
if (src.empty()) {
printf("could not load image");
return -1;
}
imshow("input_img", src);
src2 = imread("C:/Users/18929/Desktop/博客项目/项目图片/13.jpg");
if (src2.empty()) {
printf("could not load image");
return -1;
}
imshow("input_img", src2);
//namedWindow(output_win, WINDOW_AUTOSIZE);
//createTrackbar("Threshold value is:", output_win, &threshold_v, threshold_max, Demo_Moments);
//Demo_Moments(0, 0);
Check_Skew(0, 0);
waitKey(0);
return 0;
}
void Check_Skew(int, void*) {
//边缘提取
cvtColor(src2, gray_src, COLOR_BGR2GRAY);
Mat canny_out;
Canny(gray_src, canny_out, threshold_v, threshold_v * 2, 3, false);
imshow("canny_img", canny_out);
//寻找轮廓并绘制
vector<vector<Point>> contours;
vector<Vec4i> hierachy;
findContours(canny_out, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
float maxw = 0;
float maxh = 0;
double degree = 0;
RNG rng(12345);
Mat drawImage = Mat::zeros(src2.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); i++)
{
//找出最小的长方形轮廓
RotatedRect minRect = minAreaRect(contours[i]);
//因为角度可能是负,所以要加绝对值
float degree = abs(minRect.angle);
if (degree>0)
{
//如果有倾斜角度,找到最大的边框对象,然后进行旋转,转回正常角度
maxw = max(maxw, minRect.size.width);
maxh = max(maxh, minRect.size.height);
}
}
//画出边框
for (size_t t = 0; t < contours.size(); t++)
{
RotatedRect minRect = minAreaRect(contours[t]);
//找到正确矩形时才华
if (maxw == minRect.size.width && maxh == minRect.size.height)
{
degree = minRect.angle;
Point2f pts[4];
minRect.points(pts);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
for (int j = 0; j < 4; j++)
{
line(drawImage, pts[j], pts[(j + 1) % 4], color, 2, 8, 0);
}
}
}
imshow("line", drawImage);
//旋转图形
//1.获取中心点
Point2f center(src2.cols / 2, src.rows / 2);
//2.以倾斜图形和旋转角度获取需要旋转的矩阵
Mat rotm = getRotationMatrix2D(center, degree, 1.0);
Mat dst;
//3.使用仿射变换旋转图形
warpAffine(src2, dst, rotm, src2.size(), INTER_LINEAR, 0, Scalar(255,255,255));
imshow("normal_result", dst);
}
void Demo_Moments(int, void*) {
//边缘提取
cvtColor(src, gray_src, COLOR_BGR2GRAY);
Mat canny_out;
Canny(gray_src, canny_out, threshold_v, threshold_v * 3, 3, false);
imshow("canny_img", canny_out);
//寻找轮廓并绘制
vector<vector<Point>> contours;
vector<Vec4i> hierachy;
findContours(canny_out, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
//限制轮廓大小,如果太小的不绘制
int minw = src.cols * 0.75;
int minh = src.rows * 0.75;
RNG rng(12345);
//设置一个矩形对象,仅装轮廓内图形,然后显示
Rect bbox;
Mat drawImage = Mat::zeros(src.size(), CV_8UC3);
for (size_t t = 0; t < contours.size(); t++) {
//找出最小的长方形轮廓
RotatedRect minRect = minAreaRect(contours[t]);
//找出倾斜角度,有倾斜再处理
float degree = abs(minRect.angle);
printf("current angle is:%f", degree);
//画轮廓
if (minRect.size.width>minw&&minRect.size.height>minh &&minRect.size.width<(src.cols))
{
//找出矩形的四个点连线
Point2f pts[4];
minRect.points(pts);
//存储矩形区域,以边框为界
bbox = minRect.boundingRect();
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
for (int i = 0; i < 4; i++)
{
line(drawImage, pts[i], pts[(i + 1) % 4], color, 2, 8, 0);
}
}
}
imshow("contours", drawImage);
if (bbox.width>0&&bbox.height>0)
{
//获取了bbox的区域后,再src中截取出相应部分
Mat roiImg = src(bbox);
imshow("final result", roiImg);
}
}