opencv c#获取矩形的4个点OpenCV中RotatedRect的角度
Mat gray = new Mat();
Cv2.CvtColor(ori_mat, gray, ColorConversionCodes.BGR2GRAY);
Cv2.GaussianBlur(gray, gray, new OpenCvSharp.Size(5, 5), 0);
// 3. Canny 边缘检测
Mat edges = new Mat();
Cv2.Canny(gray, edges, 50, 150); // 阈值可根据实际情况调节
// 4. 查找轮廓
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(edges, out contours, out hierarchy,
RetrievalModes.External, ContourApproximationModes.ApproxSimple);
foreach (var contour in contours)
{
double area = Cv2.ContourArea(contour);
if (area < 1000) continue; // 根据实际图像调整
// 计算最小外接矩形(可能带旋转)
RotatedRect minRect = Cv2.MinAreaRect(contour);
Point2f[] box = minRect.Points();
}
OpenCV中RotatedRect的角度
public static int AngleAnalyse(string img_path) { int i_angle = 0; Mat ori_mat = Cv2.ImRead(img_path); Mat ori_mat2 = ori_mat; //ori_mat = ori_mat.CvtColor(ColorConversionCodes.BGR2GRAY); Mat edge2 = ori_mat.Canny(50,150,3); LineSegmentPoint[] lines = Cv2.HoughLinesP(edge2,1,Math.PI / 180, 200, 100, 10); List<double> list_d = new List<double>(); float box_max_angle = 0.01f; double box_max_side = 0.01d; int max_x = 0; int max_y = 0; if (true) { Mat gray = new Mat(); Cv2.CvtColor(ori_mat, gray, ColorConversionCodes.BGR2GRAY); Cv2.GaussianBlur(gray, gray, new OpenCvSharp.Size(5, 5), 0); // 3. Canny 边缘检测 Mat edges = new Mat(); Cv2.Canny(gray, edges, 50, 150); // 阈值可根据实际情况调节 // 4. 查找轮廓 OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(edges, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple); // 5. 逐个轮廓处理,找出矩形(面积阈值可自行设定) foreach (var contour in contours) { // 过滤掉太小的噪声轮廓 double area = Cv2.ContourArea(contour); if (area < 1000) continue; // 根据实际图像调整 // 计算最小外接矩形(可能带旋转) RotatedRect minRect = Cv2.MinAreaRect(contour); // 角度的取值范围为 [-90, 0),需要统一为正向角度 float angle = minRect.Angle; //if (angle < -45) // angle = 90 + angle; //else //angle = -(90 - angle); //if(angle>0 && angle<90) { // angle = -(90 - angle); } //else if() //else { //angle = 0; } // 6. 绘制结果(可视化) Point2f[] box = minRect.Points(); float box_max_side2 = 0.0f; double dis1 = Math.Sqrt( Math.Pow((box[1].X - box[0].X),2)+ Math.Pow((box[1].Y - box[0].Y), 2)); double dis2 = Math.Sqrt(Math.Pow((box[2].X - box[1].X), 2) + Math.Pow((box[2].Y - box[1].Y), 2)); double area1 = dis1 * dis2; if (area1 > box_max_side) { box_max_side = area1;//box_max_side2; box_max_angle = angle; max_x = (int)minRect.Center.X; max_y = (int)minRect.Center.Y; } // 使用LINQ将Point2f数组转换为Point数组 Point[] points66 = box.Select(p => new Point((int)Math.Round(p.X), (int)Math.Round(p.Y))).ToArray(); Point point3 = new Point() { X=1,Y=2 }; Point2f point2F = new Point2f() { X=11.0f, Y=22.3f }; // 定义三角形顶点 Point[] triangle = new Point[] { new Point(100, 50), new Point(200, 300), new Point(50, 300) }; //Cv2.Polylines(ori_mat, new[] { points66 } , true, Scalar.Red, 2); // Cv2.PutText(ori_mat, $"Angle={angle:F1}", new Point((int)minRect.Center.X, (int)minRect.Center.Y), // HersheyFonts.HersheySimplex, 0.6, Scalar.Yellow, 2); // 7. (可选)对图像进行旋转校正 //Mat rotated = RotateImage(ori_mat, angle); //Cv2.ImWrite($"rotated_{angle:F0}.jpg", rotated); //break; } // 保存并显示最终结果 //Cv2.ImWrite("result.jpg", ori_mat); //Cv2.ImShow("Result", ori_mat); //Cv2.WaitKey(); } Cv2.PutText(ori_mat, $"LastAngle={box_max_angle:F1}", new Point(max_x, max_y+20), HersheyFonts.HersheySimplex, 0.6, Scalar.Yellow, 2); if (box_max_angle>45) { box_max_angle = -(90 - box_max_angle); } Mat rotated = RotateImage(ori_mat, box_max_angle); Cv2.ImWrite($"rotated_{box_max_angle:F0}.jpg", rotated); // 保存并显示最终结果 Cv2.ImWrite("result.jpg", ori_mat); foreach (var line in lines) { double aa = Math.Atan2(line.P2.Y-line.P1.Y,line.P2.X-line.P1.X); double angle2 = 0.0; angle2 = aa * (180 / Math.PI); //弧度转角度 //if(aa > 0.2 && aa <0.3) { list_d.Add(angle2); if(angle2>80)// && angle2 <10) { Cv2.Line(ori_mat2, line.P1, line.P2, new Scalar(0, 0, 255), 2); } } } // Cv2.ImShow("img", ori_mat2); Cv2.WaitKey(0); return i_angle; }