WjExplor Story

02-1강 Point2f 기본 사용법 정리: 좌표 연산, 내적(dot), 크기(norm), 외적(cross) 본문

C++/C++ : openCV

02-1강 Point2f 기본 사용법 정리: 좌표 연산, 내적(dot), 크기(norm), 외적(cross)

더블유제이플로어 2026. 6. 15. 00:21

ex_1_2.cpp 원본 파일을 삭제하였습니다.
그리고 visual studio 를 실행하였을 때 실제 이미지처럼 오류가 발생한다고 합니다.

visual studio 는 해당 폴더에 파일이 없어도 솔루션 <프로젝트> 에는 소스로 파일이 남아있게 됩니다.
파일을 삭제했을 경우에는 솔루션 소스에도 삭제해야합니다.

그리고 소스파일에 여러 main 함수가 있게되면 컴파일 오류가 나옵니다.
프로젝트를 분리해야 하며,
프로젝트에 많은 파일들이 필요할 때나 리소스 외부 파일을 끌어오거나,
main 함수가 아닌 다른 함수를 연동해야하는 경우 등이 있을 수 있습니다.
다른 함수를 연동해야하는 이유는 몇 천줄의 코드가 될 수 있을때 관리하는 기밥으로
파일별로 나눠서 include 를 하듯이 작업을 해야합니다.

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

int main()
{
    Point2f pt1(1.0f, 1.0f);
    Point2f pt2(2.0f, 2.0f);

    Point2f pt3 = pt1 * 10.0f;
    Point2f pt4 = pt3 - pt2;

    cout << "pt1 : " << pt1 << endl;
    cout << "pt2.x : " << pt2.x << endl;

    Rect rect(5, 5, 10, 10);
    if (pt3.inside(rect))
        cout << "pt3 is inside the rect." << endl;

    if (pt3==pt4)
        cout << "pt3 and pt4 is a same point." << endl;
    else
        cout << "pt3 and pt4 is not a same point." << endl;

    cout << "dotproduct : " << pt1.dot(pt2) << endl;
    cout << "normal : " << norm(pt1) << endl;

}

Point2f 는 opencv 에서 정의된 포인트 클래스입니다.
영상에서 픽셀의 위치를 확인하고 업데이트를 할 때 자주 사용됩니다.
좌표의 덧셈, 뺄셈, 곱셈, 나눗셈 비교 또한 할 수 있게 됩니다.
좌표의 값들이랑 내적/외적 등을 계산하는 멤버 함수를 지원하게 됩니다.
Point2f 는 2D 입니다. 2D 좌표상에 변수를 선언하게 됩니다.

Point2f pt1(1.0f, 1.0f);
Point2f pt2(2.0f, 2.0f);

pt1, pt2 를 선언하고 기본값으로는
(1.0f, 1.0f), (2.0f, 2.0f) 으로 정의가 되어 기본값을 대입해 놓았습니다.
f는 숫자 리터럴을 float 타입으로 표현하기 위한 접미사입니다.
int, float , double 등 숫자를 표현하는 방법이 있습니다.
float 은 소숫값이 붙은 실수형 표현입니다.

Point2f pt3 = pt1 * 10.0f;
Point2f pt4 = pt3 - pt2;

pt3 은 pt1의 좌표값에서 x,y 값 모두 x(10.0f) 한 값입니다. (10.f, 10.f)
pt4 는 pt3에서 pt2 값을 뺀 값입니다.

Point2f 는 2D 값이기 때문에 x,y 좌표값을 의미합니다.
좌표 하나만 선언하게 되면 오류를 내보냅니다.

Rect 은 렉트라고 해서 변수를 정의해두는것입니다.
직사각형인데 Rectangle 의 약자라고 보면 됩니다.
직사각형의 변수 4개를 정의해서 사각형을 만드는겁니다.

Rect rect(x, y, width, height);

if (pt3.inside(rect))
    cout << "pt3 is inside the rect." << endl;

pt3 은 (10.f, 10.f) 입니다. 이 값이 rect 안에 들어오는지 확인한다면
(5,5) 에 가로 세로 10씩 이기 때문에 rect 안에 들어오는 True 값이 됩니다.

if (pt3==pt4)
    cout << "pt3 and pt4 is a same point." << endl;
else
    cout << "pt3 and pt4 is not a same point." << endl;

= 이 연산자는 오른쪽에 있는 변수가 왼쪽으로 가게 됩니다. <이건 ==연산자 말고도 많은 연산자들이 마찬가지입니다.>
= 은 대입 연산자이며 ==은 두 변수가 같은지 비교하는 연산자입니다.
!=은 같지 않음을 확인하는 연산자 입니다.

cout << "dotproduct : " << pt1.dot(pt2) << endl;
dotproduct : 각 성분끼리 곱한 값
cout << "normal : " << norm(pt1) << endl;
normal 은 그렇지 않은 값

dot 두 벡터의 내적을 계산해서 숫자 하나를 반환합니다.

// 예시
pt1 = (3, 4)
pt2 = (5, 2)

dot = 3 * 5 + 4 * 2
    = 15 + 8
    = 23

pt1 좌표와 pt2 좌표의 내접을 구하게 됩니다.

벡터는 방향을 가리키고 있기 때문에 .dot을 통해서 두 벡터가 방향이 얼마나 비슷한지도 알게 됩니다.

dot > 0  → 두 벡터가 비슷한 방향
dot = 0  → 두 벡터가 직각
dot < 0  → 두 벡터가 반대 방향

norm은 벡터 하나의 길이입니다.
내접 Norm 벡터의 길이, 즉 크기를 구하는 함수입니다.

pt1 = (3, 4)

norm = sqrt(3*3 + 4*4)
     = sqrt(9 + 16)
     = sqrt(25)
     = 5

즉 피타고라스 정리와 비슷합니다.

길이 = √(x² + y²)

cout << "cross product : " << pt1.cross(pt2) << endl;

cross 메소드는 좌표의 외적을 구하는것입니다.


<GPT 에게 cross 메소드에 대해서 자세히 물어보았습니다.>

cross product (외적) 은 벡터의 외적을 구하는 연산입니다.

다만 OpenCV에서 Point를 다룰 때는 2차원 좌표라서, 우리가 수학에서 배우는 3차원 외적과 조금 다르게 생각해야 합니다.

1. dot vs cross 비교

dot (내적)

a.dot(b)

공식:
$$
a \cdot b = a_x b_x + a_y b_y
$$

결과: 스칼라<숫자 하나>

의미:

  • 얼마나 같은 방향인가?
  • 각도 계산

cross (외적)

3차원에서 공식:

$$
a \times b = a_x b_y - a_y b_x
$$

결과: 벡터

즉 3D에서는:

벡터 × 벡터 = 새로운 벡터

입니다.


2. 2D OpenCV Point는?

예를 들어:

Point a(3, 2);
Point b(1, 4);

2D에서는 외적 결과가 벡터가 아니라 보통 z축 성분 하나만 남습니다.

공식:

$$
a \times b = a_x b_y - a_y b_x
$$

계산:

3*4 - 2*1
= 12 - 2
= 10

즉 결과는:

10

숫자 하나입니다.


3. 왜 숫자 하나만 남을까?

원래 2D 벡터를 억지로 3D로 확장해서 생각합니다.

(3,2) → (3,2,0)
(1,4) → (1,4,0)

외적 계산하면:

(0,0,10)

x, y 성분은 0이고
z만 남습니다.

그래서 2D에서는 보통 z값만 씁니다.


4. cross product의 의미 ⭐

이게 OpenCV에서 진짜 많이 쓰입니다.

(1) 회전 방향 판별

점 3개가 있을 때

A → B → C

이 방향이

  • 반시계 (CCW)
  • 시계 (CW)

인지 판별합니다.

cross > 0  → 반시계
cross < 0  → 시계
cross = 0  → 일직선

예시:

Point a(1,0);
Point b(0,1);

cross:

1*1 - 0*0 = 1

양수 → 반시계 방향

이걸 orientation test라고 합니다.


(2) 삼각형 면적

외적 절댓값의 절반이 면적입니다.

삼각형 넓이:

$$
A = \frac{1}{2}bh
$$

컴퓨터 비전에서 contour 면적 계산할 때 연결됩니다.


5. OpenCV Point에 cross가 있나?

cv::Point2f, cv::Point3f 계열에는 있습니다.

예:

Point2f a(3,2);
Point2f b(1,4);

double c = a.cross(b);

결과:

10

6. 외적과 삼각형 넓이

외적은 삼각형 넓이를 구할 때도 사용할 수 있습니다.
두 벡터 a, b가 만드는 평행사변형의 넓이는 외적의 절댓값이고, 삼각형은 그 절반입니다.

$$
A = \frac{|a \times b|}{2}
$$

점 3개 A, B, C로 이루어진 삼각형의 넓이는 다음과 같이 구할 수 있습니다.

$$
A = \frac{|(B - A) \times (C - A)|}{2}
$$

OpenCV 코드로 표현하면 다음과 같습니다.

double area = std::abs((B - A).cross(C - A)) / 2.0;


정리하면:

  • dot (내적) → 방향 유사도, 길이 투영
  • cross (외적) → 회전 방향, 면적

기억하기 쉽게 말하면:

dot은 “얼마나 같은 방향?”

cross는 “왼쪽으로 꺾였나 오른쪽으로 꺾였나?”

라고 생각하시면 됩니다.

'C++ > C++ : openCV' 카테고리의 다른 글

01강 opencv 자료형 공부하기  (0) 2026.06.14
opencv (c++) 연동하기  (0) 2026.06.14