判断点是否在不规则矩形区域opencv demo
来源:互联网 发布:国家顶级域名有哪些 编辑:程序博客网 时间:2024/06/05 02:20
Point in Polygon 问题 opencv3.2 demo
一、Background
最近做相关项目检测某一点是否在划定的一个区域内,百度之后发现了这类问题属于Point in Polygon。主要有两种方法解决:
1、Crossing Number (cn) 方法
测试点作为起点画一条射线穿过不规则区域,与区域相交的点为奇数则此点在区域内,为偶数则在区域外,此种情况不准确(射线穿过不规则矩形框顶点时)。
2、Winding Number (wn)方法
这种方法是一种环绕算法,可参考这里。
二、DEMO
用opencv实现了一个demo(由于某些原因使用的opencv c接口),即手动点不规则矩形的点,自动画线生成不规则矩形框。之后可在图片任意区域内鼠标左键点点,如果点在区域内,则显示为红点;若不在区域内则显示为蓝点。如图下图所示。代码主要参考了http://geomalgorithms.com/a03-_inclusion.html;
三、CODE
#include "opencv2\highgui\highgui_c.h"#include "opencv2\imgproc\imgproc_c.h"#include "opencv2\core\core_c.h"#include "opencv2\imgcodecs\imgcodecs_c.h"#include "opencv2\core\types_c.h"#include <stdio.h>#define POINT_NUM 6//不规则矩形顶点数int wn_PnPoly(CvPoint P, CvPoint* V, int n);CvPoint vertex_point[POINT_NUM],testpoint;IplImage *org;void on_mouse(int EVENT, int x, int y, int flags, void* userdata){ static int i = 0,ii=1; CvScalar color_b = CV_RGB(0, 0, 255); CvScalar color_r = CV_RGB(255, 0, 0); switch (EVENT) { case CV_EVENT_LBUTTONDOWN: if (ii) { vertex_point[i] = cvPoint(x, y); cvCircle(org, vertex_point[i], 1, color_r,2,4,0); printf("vertex_point[%d]->(%d,%d)\n", i, vertex_point[i].x, vertex_point[i].y); if (i >= 1) { cvLine(org, vertex_point[i - 1], vertex_point[i], color_r, 3, 4, 0); if (i == POINT_NUM - 1) { cvLine(org, vertex_point[i], vertex_point[0], color_r, 3, 4, 0); vertex_point[POINT_NUM] = vertex_point[0]; ii = 0; } } i++; } else { testpoint=cvPoint(x, y); int out_in=wn_PnPoly(testpoint, vertex_point, POINT_NUM); if (out_in==0)//outside { cvCircle(org, testpoint, 2, color_b, 2, 4, 0); printf("outside!\n"); } else//inside { cvCircle(org, testpoint, 2, color_r, 2, 4, 0); printf("inside!\n"); } // printf("result:%d", out_in); } break; default: break; }}inline int isLeft(CvPoint P0, CvPoint P1, CvPoint P2){ return ((P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y));}int cn_PnPoly(CvPoint P, CvPoint* V, int n){ int cn = 0; // the crossing number counter // loop through all edges of the polygon for (int i = 0; i<n; i++) { // edge from V[i] to V[i+1] if (((V[i].y <= P.y) && (V[i + 1].y > P.y)) // an upward crossing || ((V[i].y > P.y) && (V[i + 1].y <= P.y))) { // a downward crossing // compute the actual edge-ray intersect x-coordinate float vt = (float)(P.y - V[i].y) / (V[i + 1].y - V[i].y); if (P.x < V[i].x + vt * (V[i + 1].x - V[i].x)) // P.x < intersect ++cn; // a valid crossing of y=P.y right of P.x } } return (cn & 1); // 0 if even (out), and 1 if odd (in)}int wn_PnPoly(CvPoint P, CvPoint* V, int n){ int wn = 0; // the winding number counter // loop through all edges of the polygon for (int i = 0; i<n; i++) { // edge from V[i] to V[i+1] if (V[i].y <= P.y) { // start y <= P.y if (V[i + 1].y > P.y) // an upward crossing if (isLeft(V[i], V[i + 1], P) > 0) // P left of edge ++wn; // have a valid up intersect } else { // start y > P.y (no test needed) if (V[i + 1].y <= P.y) // a downward crossing if (isLeft(V[i], V[i + 1], P) < 0) // P right of edge --wn; // have a valid down intersect } } return wn;}int main(){ org = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_COLOR); cvNamedWindow("lena", CV_WINDOW_AUTOSIZE); cvSetMouseCallback("lena", on_mouse, 0); while (true) { cvShowImage("lena", org); if (cvWaitKey(20) ==13)break; } cvReleaseImage(&org); cvDestroyAllWindows();}
四、References
1.https://www.zhihu.com/question/26551754
2.http://geomalgorithms.com/a03-_inclusion.html
阅读全文
1 0
- 判断点是否在不规则矩形区域opencv demo
- 判断点是否在不规则区域范围内
- 如何判断鼠标按下的点是否在指定矩形区域CRect
- 判断点是否在矩形的里面
- 点是否在矩形中判断
- 判断点是否在矩形内
- 点是否在矩形中判断
- c#判断点是否在矩形上
- 判断点是否在矩形内
- 点是否在矩形中判断
- 判断点是否在矩形内
- 判断点是否在封闭区域里面
- 判断点是否在多边形区域里面
- 如何判断一个点是否在不规则图形内部?
- [几何]判断点是否在不规则多边形内
- 判断点或者坐标是否在不规则区域内
- PHP判断点是否在不规则多边形中
- [几何]判断点是否在不规则多边形内
- jstree的增删改
- Ajax与Jquery
- CAD图纸批量转换成PDF的常用方法
- B+ tree 删除算法
- Phone List——Trie树
- 判断点是否在不规则矩形区域opencv demo
- 静态代理、JDK与CGLIB动态代理
- JavaScript学习之路<八>
- JavaScript学习之路<九>
- Java基础
- JavaScript学习之路<十>
- Jquery 中 ajaxSubmit使用讲解
- netty学习(三)ChannelInboundHandler和ChannelOutboundHandler
- JavaScript学习之路<十一> JS面向对象程序设计