opencv c#获取矩形的4个点OpenCV中RotatedRect的角度

image

 

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();

}

 

image

OpenCV中RotatedRect的角度

image

 

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;

        }

 

posted @ 2025-09-30 23:24  txwtech  阅读(17)  评论(1)    收藏  举报