步骤是灰度化、二值化、寻找轮廓、最小外接矩形、图像调整。
比较简单,欢迎探讨,下面是代码
int main()
{
Mat srcImage = imread("D://test1.jpg");
Mat srcGray, threImage,dstImage;
cvtColor(srcImage, srcGray, CV_RGB2GRAY);
imshow("srcImage", srcImage);
threshold(srcGray, threImage, 130, 255, 0);
//imshow("threshold", threImage);
dstImage = threImage < 100;//反色
//imshow("reverse", dstImage);
std::vector<Point> contours;
std::vector<std::vector<cv::Point>> f_contours;
cv::findContours(dstImage,f_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//找到目标轮廓
int max_area = 0;
int index;
for (int i = 0; i < f_contours.size(); i++)
{
double tmparea = fabs(contourArea(f_contours[i]));
if (tmparea > max_area)
{
index = i;
max_area = tmparea;
}
}
Mat box_contours(dstImage.size(), CV_8U,Scalar(0));
contours = f_contours[index];
//显示轮廓
Mat contoursMat(dstImage.size(), CV_8U, Scalar(0));
for (int i = 0; i < contours.size(); i++)
{
circle(contoursMat, contours[i], 3, Scalar(255, 0, 0), -1);
}
imshow("contours", contoursMat);
//获得最小矩形
RotatedRect box = minAreaRect(Mat(contours));
Point2f center, vtx[4];
box.points(vtx);
for (int i = 0; i < 4; i++)
{
line(box_contours, vtx[i], vtx[(i + 1) % 4], Scalar(255, 0, 0), 1, CV_AA);
}
cv::imshow("Contoursbox", box_contours);
Mat warpMat(Size(2, 3), CV_32F);
warpMat = getRotationMatrix2D(vtx[1], box.angle, 1);
warpAffine(srcImage, dstImage, warpMat, dstImage.size());
float x, y;//旋转后的坐标
x = vtx[1].x*cos(box.angle) - vtx[1].y*sin(box.angle);
y= vtx[1].x*sin(box.angle) + vtx[1].y*cos(box.angle);
//定义平移矩阵
cv::Mat t_mat = cv::Mat::zeros(2, 3, CV_32FC1);
t_mat.at<float>(0, 0) = 1;
t_mat.at<float>(0, 2) = 100-x; //水平平移量
t_mat.at<float>(1, 1) = 1;
t_mat.at<float>(1, 2) = 100-y; //竖直平移量
//根据平移矩阵进行仿射变换
cv::warpAffine(dstImage, dstImage, t_mat, dstImage.size());
imshow("warp", dstImage);
waitKey(100000);
return 0;
}