当前位置: 首页 > news >正文

opencv中旋转角度使用atan函数或atan2函数计算角度

atan 和 atan2 都是求反正切函数,如:有两个点 point(x1,y1), 和 point(x2,y2);

那么这两个点形成的斜率的角度计算方法分别是:

float angle = atan( (y2-y1)/(x2-x1) );

float angle = atan2( y2-y1, x2-x1 );

 atan 和 atan2 区别:

1:参数的填写方式不同;

2:atan2 的优点在于 如果 x2-x1等于0 依然可以计算,但是atan函数就会导致程序出错;

建议用 atan2函数;

方法1:

霍夫直线检测

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

反正切计算弧度,再转角度

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);}}}
static Mat RotateImage(Mat img, double angle){var (h, w) = (img.Rows, img.Cols);Point2f center = new Point2f(w / 2f, h / 2f);Mat rotMat = Cv2.GetRotationMatrix2D(center, angle, 1.0);Mat dst = new Mat();// Cv2.WarpAffine(img, dst, rotMat, new OpenCvSharp.Size(w, h),//InterpolationFlags.Linear, BorderTypes.Replicate);Cv2.WarpAffine(img, dst, rotMat, new OpenCvSharp.Size(w, h));return dst;}

方法2:

1.转灰度图

2.高斯平滑

3.边缘检测

4.查找轮廓

5.遍历矩形轮廓

6.计算最小外接矩形的角度获取

7.旋转

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>();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),需要统一为正向角度double angle = minRect.Angle;//if (angle < -45)//    angle = -(90 + angle);//else//    angle = -angle;if(angle>0 && angle<90){angle = -(90 - angle);}else{angle = 0;}// 6. 绘制结果(可视化)Point2f[] box = minRect.Points();// 使用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();}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;}

http://www.dtcms.com/a/461272.html

相关文章:

  • 做详情页到那个网站找模特素材《高性能网站建设指南
  • 【蓝牙协议栈】蓝牙核心规范6.0新特性学习
  • vue中的 watchEffect、watchAsyncEffect、watchPostEffect的区别
  • Python从入门到实战:全面学习指南2
  • 今天我们开始学习python3编程之python基础
  • jenkins更新了gitlab后出现报错
  • 【OS笔记06】:进程和线程4-进程调度的核心算法
  • 自助建网站工具网站建设与推广
  • 操作系统第二章(下)
  • UNIX下C语言编程与实践49-UNIX 信号量创建与控制:semget 与 semctl 函数的使用
  • 探索Playwright MCP和Claude的协作:智能网页操作新境界
  • Java-144 深入浅出 MongoDB BSON详解:MongoDB核心存储格式与JSON的区别与应用场景
  • 网站的流量是怎么算的双牌网站建设
  • TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 神经网络基础原理
  • Flink State V2 实战从同步到异步的跃迁
  • xml网站地图在线生成工具杭州城西做网站的公司
  • 怎样搭建个人网站wordpress farmer
  • 10.9 lpf|求凸包|正反扫描
  • HashMap 与 Hashtable 深度对比分析
  • 网站开始开发阶段的主要流程辽宁建设工程信息网工程业绩怎么上传
  • 缓存雪崩、击穿、穿透是什么与解决方案
  • 桌面图标又乱了?这个小神器,让你的桌面布局“一键复位”
  • mongodb慢查询优化 速度欻欻滴~
  • 从零开始的C++学习生活 6:string的入门使用
  • 风景网站模板济南seo关键词排名工具
  • UE5 测量 -1,长度测量:P2制作定位球与定位线,P3制作射线检测节点,P4在鼠标位置生成定位球
  • UE5 GAS GameAbility源码解析 EndAbility
  • 潍坊网站建设 潍坊做网站外贸网站服务器推荐
  • 第7章 n步时序差分(3) n 步离轨策略学习
  • 【Leetcode hot 100】35.搜索插入位置