校正 + 旋转校正 OpenCV (C++)
详细见:https://blog.youkuaiyun.com/Aquamarine__/article/details/115756475
视觉检查见:https://blog.youkuaiyun.com/Aquamarine__/article/details/115757527
旋转校正:
vector<Rect> boundRect(contours.size());
vector<RotatedRect> box(contours.size());
Point2f rect[4]; //定义数组存放四个顶点
for (int i = 0; i < contours.size(); i++) {
box[i] = minAreaRect(Mat(contours[i]));
boundRect[i] = boundingRect(Mat(contours[i])); //计算轮廓的最小外接矩形
if (box[i].size.width < 100 || box[i].size.height < 100)//筛选
continue;
//画一个矩形
rectangle(img_new, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
circle(img_new, Point(box[i].center.x, box[i].center.y), 5, Scalar(0, 255, 0), -1, 8);
box[i].points(rect);
for (int j = 0; j < 4; j++) {
line(img_new, rect[j], rect[(j + 1) % 4], Scalar(0, 0, 255), 2, 8);
}
float angle;
angle = box[i].angle;
char width[20], height[20];
//利用仿射变换进行旋转
if (0 < abs(angle) && abs(angle) <= 45)
angle = angle;//负数,顺时针旋转
else if (45 < abs(angle) && abs(angle) < 90)
angle = 90 - abs(angle);//正数,逆时针旋转
Point2f center = box[i].center; //定义旋转中心坐标
double angle0 = angle;
double scale = 1;
Mat roateM = getRotationMatrix2D(center, angle0, scale); //获得旋转矩阵,顺时针为负,逆时针为正
warpAffine(img_new, img_new, roateM, img_new.size()); //仿射变换
imshow("11", img_new);
校正:
Point2f srcTri[3];
Point2f dstTri[3];
//设置源图像和目标图像上的三组点以计算仿射变换
srcTri[0] = Point2f(0, 0);
srcTri[1] = Point2f(img_new.cols - 1, 0);
srcTri[2] = Point2f(0, img_new.rows - 1);
dstTri[0] = Point2f(img_new.cols*0.0, img_new.rows*0.33);
dstTri[1] = Point2f(img_new.cols*0.85, img_new.rows*0.25);
dstTri[2] = Point2f(img_new.cols*0.15, img_new.rows*0.7);
// 设置目标图像的大小和类型与源图像一致
Mat warp_dst = Mat::zeros(img_new.rows, img_new.cols, img_new.type());
//求得仿射变换
Mat warp_mat = getAffineTransform(srcTri, dstTri);
//对源图像应用上求得的仿射变换
warpAffine(img_new, warp_dst, warp_mat, warp_dst.size());
// 对图像扭曲后再旋转
// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵
Point center = Point(warp_dst.cols / 2, warp_dst.rows / 2);
double angle = -50.0;
double scale = 0.6;
// 通过上面的旋转细节信息求得旋转矩阵
Mat rot_mat = getRotationMatrix2D(center, angle, scale);
// 旋转已扭曲图像
Mat warp_rotate_dst;
warpAffine(warp_dst, warp_rotate_dst, rot_mat, warp_dst.size());
// 显示结果
imshow("source_window", img_new);
imshow("warp_window", warp_dst);
imshow("warp_rotate_window", warp_rotate_dst);