版权声明:本文为博主原创文章,博主欢迎各位转载。 https://blog.csdn.net/tuwenqi2013/article/details/83592138
实现思路:最大外接矩阵边缘检测+旋转+选取ROI区域裁剪
代码:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <math.h>
#include <iostream>
using namespace std;
using namespace cv;
Mat img1, gray, canny_gray, dest;
double threshold_value = 180.0;
void RotateImg(void);
void GetTargetImg(Mat img);
int main(int argc, char * argv[])
{
img1 = imread("../img/11.png");
imshow("原始图像", img1);
RotateImg(); //旋转图片
GetTargetImg(img1); //裁剪图片
if (waitKey() == 27)
return 0;
}
void RotateImg(void)
{
Mat canny_output;
vector<vector<Point>> contours;
vector< Vec4i> hireachy;
Mat drawImg = Mat::zeros(img1.size(), CV_8UC3);
cvtColor(img1, gray, COLOR_BGR2BGRA);
Canny(gray, canny_output, threshold_value, threshold_value * 2, 3, false);
imshow("Canny算子图像", canny_output);
findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
float maxw = 0;
float maxh = 0;
int angle = 0;
for (int t = 0; t < contours.size(); t++)
{
RotatedRect rotate = minAreaRect(contours[t]);
angle = abs(rotate.angle);
if (angle > 0)
{
maxw = max(maxw, rotate.size.width);
maxh = max(maxh, rotate.size.height);
}
}
RNG rng(12345);
for (int t = 0; t < contours.size(); t++)
{
RotatedRect rota = minAreaRect(contours[t]);
if (maxw == rota.size.width && maxh == rota.size.height)
{
angle = rota.angle; //找到合适的旋转角度
}
}
Point2f center(img1.cols / 2, img1.rows / 2);
Mat rotaImg = getRotationMatrix2D(center, angle, 1.0); //找到旋转矩阵
warpAffine(img1, dest, rotaImg, img1.size(), INTER_LINEAR);
imshow("摆正后的图像", dest);
}
void GetTargetImg(Mat img)
{
Mat canny_output;
vector<vector<Point>> contours;
vector< Vec4i> hireachy;
Mat drawImg = Mat::zeros(dest.size(), CV_8UC3);
Rect box;
cvtColor(dest, gray, COLOR_BGR2BGRA);
Canny(gray, canny_output, threshold_value, threshold_value * 2, 3, false);
Mat drawImage = Mat::zeros(dest.size(), CV_8UC3);
findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
int maxw = dest.cols*0.5;
int maxh = dest.rows*0.5;
cout << "maxw: " << maxw << "maxh: " << maxh << endl;
RNG rng(12345);
int angle = 0;
for (int t = 0; t < contours.size(); t++)
{
RotatedRect rota = minAreaRect(contours[t]);
float angle = abs(rota.angle);
cout << "angle:" << angle << endl;
if (maxw < rota.size.width && maxh < rota.size.height)
{
cout << "最小外包矩形:" << box << endl;
box = rota.boundingRect(); //找到裁剪矩阵
}
}
if (box.width > 0 && box.height > 0)
{
Mat roiimg = dest(box);
imshow("结果图像", roiimg); //显示裁剪后的图像
imwrite("1.1.jpg",roiimg); //保存图片
}
}
原始图片:
摆正后的图片:
最后的处理结果: