-
앵커찾기 (With OpenCV)c# Winform 개발/UI 2021. 6. 21. 09:31
마우스로 클릭할때 OpenCV로 그린오브젝트(네모,폴리곤)에 포함되는지 확인하고할 때 썼었다.
OpenCVOjbect = 그려진 오브젝트(네모,폴리곤).
각 꼭지점은 앵커라고 부르며 앵커의 경우 BLK로 조금 더 진하게 보이도록 UI에서 변경한 다음
마우스 클릭 이벤트에서 아래 함수를 호출하도록 해서 사용함.
ex)
TL = Top Left
TM = Top Middle
TR = Top Right
BL = Bottom Left
...
public class Constant
{
public const int ANCHOR_LOC_TL = 1;
public const int ANCHOR_LOC_TM = 2;
public const int ANCHOR_LOC_TR = 3;
public const int ANCHOR_LOC_LM = 4;
public const int ANCHOR_LOC_RM = 5;
public const int ANCHOR_LOC_BL = 6;
public const int ANCHOR_LOC_BM = 7;
public const int ANCHOR_LOC_BR = 8;
public const int BLK = 4;
}#region 네모 앵커 찾기
public bool pointInBoundRectangle(int x, int y, OpenCVOjbect dragObj)
{
bool isFind = false;
if (pointInRect(x, y, dragObj.outRect.X - Constant.BLK, dragObj.outRect.Y - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_TL;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X + dragObj.outRect.Width - Constant.BLK, dragObj.outRect.Y - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_TR;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X - Constant.BLK, dragObj.outRect.Y + dragObj.outRect.Height - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_BL;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X + dragObj.outRect.Width - Constant.BLK, dragObj.outRect.Y + dragObj.outRect.Height - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_BR;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X + dragObj.outRect.Width / 2 - Constant.BLK, dragObj.outRect.Y - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_TM;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X + dragObj.outRect.Width / 2 - Constant.BLK, dragObj.outRect.Y + dragObj.outRect.Height - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_BM;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X - Constant.BLK, dragObj.outRect.Y + dragObj.outRect.Height / 2 - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_LM;
isFind = true;
}
// endif
if (pointInRect(x, y, dragObj.outRect.X + dragObj.outRect.Width - Constant.BLK, dragObj.outRect.Y + dragObj.outRect.Height / 2 - Constant.BLK, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectRectangleAnchor = Constant.ANCHOR_LOC_RM;
isFind = true;
}
return isFind;
}
#endregion 네모 앵커 찾기
#region 네모안에 포함되는지 찾기
// 주의 : rx,ry,rw,rh는 음수가 되면 안됨. 2020.12.28
public bool pointInRect(
int pX,
int pY,
int rX,
int rY,
int rW,
int rH)
{
if (((rX <= pX) && pX <= (rX + rW)) && ((rY <= pY) && pY <= (rY + rH)))
{
return true;
}
else
{
return false;
}
}
#endregion 네모안에 포함되는지 찾기 끝
#region 폴리곤 안에 포함되는지 찾기
// Given three colinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
bool onSegment(OpenCvSharp.Point p, OpenCvSharp.Point q, OpenCvSharp.Point r)
{
if (q.X <= Math.Max(p.X, r.X) && q.X >= Math.Min(p.X, r.X) &&
q.Y <= Math.Max(p.Y, r.Y) && q.Y >= Math.Min(p.Y, r.Y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are colinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(OpenCvSharp.Point p, OpenCvSharp.Point q, OpenCvSharp.Point r)
{
int val = (q.Y - p.Y) * (r.X - q.X) -
(q.X - p.X) * (r.Y - q.Y);
if (val == 0) return 0; // colinear
return (val > 0) ? 1 : 2; // clock or counterclock wise
}
bool doIntersect(OpenCvSharp.Point p1, OpenCvSharp.Point q1, OpenCvSharp.Point p2, OpenCvSharp.Point q2)
{
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are colinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and p2 are colinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are colinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are colinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
public bool isInside(List<Point> polygon, int n, Point p)
{
// There must be at least 3 vertices in polygon[]
if (n < 3) return false;
// Create a point for line segment from p to infinite
Point extreme = new Point(Constant.INF, p.Y);
// Count intersections of the above line with sides of polygon
int count = 0, i = 0;
do
{
int next = (i + 1) % n;
// Check if the line segment from 'p' to 'extreme' intersects
// with the line segment from 'polygon[i]' to 'polygon[next]'
if (doIntersect(polygon[i], polygon[next], p, extreme))
{
// If the point 'p' is colinear with line segment 'i-next',
// then check if it lies on segment. If it lies, return true,
// otherwise false
if (orientation(polygon[i], p, polygon[next]) == 0)
return onSegment(polygon[i], p, polygon[next]);
count++;
}
i = next;
} while (i != 0);
// Return true if count is odd, false otherwise
return (count % 2 == 1);
}
#endregion 폴리곤 안에 포함되는지 찾기 끝
#region 폴리곤 앵커 찾기
public bool pointInBoundPolygon(int x, int y, OpenCVOjbect dragObj)
{
bool isFind = false;
int polygonidx = 0;
foreach (Point point in dragObj.polygonPoints)
{
if (pointInRect(x, y, point.X - Constant.BLK*2, point.Y - Constant.BLK*2, Constant.BLK * 4, Constant.BLK * 4))
{
dragObj.selectPolygonAnchor = polygonidx;
isFind = true;
break;
}
polygonidx++;
}
return isFind;
}
#endregion 폴리곤 앵커 찾기300x250'c# Winform 개발 > UI' 카테고리의 다른 글
picturebox에 휠이벤트로 확대,축소하기( With openCV ) (0) 2021.06.22 TreeView 에 폴더추가 ( 폴더탐색기 ) (0) 2021.06.15 TreeView 전체경로(Full Path)로 찾아서 트리뷰에 표시하기 (0) 2021.06.15