Program_Light
KMS01 : 자작 Algorithm Tayo Algorithm
KMS studio
2021. 3. 27. 13:00
이번에는 옛날에 만든 알고리즘을 하나 올려보도록 하곘습니다. 참고로 제가 2019년에 주소창 최우수상 탄 알고리즘이 바로 이겁니다.
알고리즘 설명
이 알고리즘은 평면방정식과 원주각의 응용버전으로서 1대의 카메라의 높이, 설치각, 촬영각등이 주어졌을때 카메라의 사진상에 있는 점의 위치를 삼차원의 점의 위치를 계산할 수 있습니다.
이때 삼차원에서 카메라가 바라보는 방향을 -x, 높이성분을 y, 나머지 수평성분을 z라고 합니다. 카메라의 위치는 원점(0, 0, 0)입니다.
예를 들어, 카메라가 45도를 바라보게 설치되어있고, 카메라가 수직으로 60도, 수평으로 60도를 촬영할 수 있고,
설치높이가 10m일때를 가정한다면 물체가 카메라가 찍은 사진의 중앙에 위치한다면 물체의 위치는
라고 할 수 있습니다. (프로그램에서는 -5.7735, -10, 0으로 출력됨)
프로그램의 증명은 다음과 같습니다.
수학적인 증명
아래 워드에 알고리즘의 원리가 어느 정도 적혀있습니다.
KMS 1정리-tayo Algorithm.docx
0.24MB
소스코드
KMS01.c
#include "KMS01.h"
#include <stdio.h>
point MakePoint(const box Bbox) {
point V;
V.x = (Bbox.p1.x + Bbox.p2.x) / 2;
V.y = (Bbox.p1.y > Bbox.p2.y) ? Bbox.p2.y : Bbox.p1.y;
return V;
}
// ************************ Grapg Funntion Code ************************ //
point3D GetLocaion(const point P) {
point R;
point S;
point3D Val;
R = XY(P.y);
S = XZ(P.x, R.x);
//cout << "R : " << R.x << " " << R.y << endl;
//cout << "alpa : " << alpa.x << " " << alpa.y << endl;
Val.x = R.x;
Val.y = R.y;
Val.z = S.y;
return Val;
}
point XY(const double Pix) {
const double AngleV = Angle2 * Pix / MPY;
const double a = TAN(90 - (Angle1 - ((double)Angle2 / 2) + AngleV));
point Val;
/* y = ax, y = -H
-H = ax x = -H/a; */
Val.x = -1 * (double)(H - H3) / a;
Val.y = a * Val.x;
return Val;
}
point XZ(const double Pix, const double x1) {
const double AngleV = AngleII * Pix / MPX;
double a = TAN(fabs(AngleV - (((double)AngleII) / 2))) * (((AngleV - ((double)AngleII / 2)) > 0) ? -1 : 1);
point Val;
/* y = ax
x = x1
(x1, TAN(AngleV - 0.5AngleII)x1)
*/
Val.x = x1;
Val.y = a * Val.x;
return Val;
}
double GetDis(const point3D P) {
return sqrt(SQ(P.x) + SQ(P.z));
}
velocity getVelocity(point3D P) {
static point3D BP = { 0, 0, 0 };
velocity V;
V.x = (P.x - BP.x) / ((double)Trigt / 1000);
V.y = (P.z - BP.z) / ((double)Trigt / 1000);
BP = P;
return V;
}
/*velocity getValPer(velocity V) {
static velocity BV = { 0, 0 };
velocity Val;
Val.x = V.x / BV.x * 100; gfs
Val.y = V.y / BV.y * 100;
BV = V;
return Val;
}*/
point3D KMS01_BOX(const box B) {
point3D DP;
velocity V;
double D;
DP = GetLocaion(MakePoint(B));
printf("3D point(%f, %f, %f) \n", DP.x, DP.y, DP.z);
printf("distance : %f \n", GetDis(DP));
D = GetDis(DP);
V = getVelocity(DP);
printf("velocity : (%f, %f) \n", V.x, V.y);
printf("\n");
return DP;
}
point3D KMS01(const point P) {
point3D DP;
velocity V;
double D;
DP = GetLocaion(P);
//printf("3D point(%f, %f, %f) \n", DP.x, DP.y, DP.z);
//printf("distance : %f \n", GetDis(DP));
D = GetDis(DP);
V = getVelocity(DP);
//printf("velocity : (%f, %f) \n", V.x, V.y);
//printf("\n");
return DP;
}
KMS01.h
#pragma once
#ifndef __KMS01__
#define __KMS01__
#include <math.h>
//made by tomksnag BY-NC-SA
// ************************ base difines ************************ //
#define TRUE 1
#define FALSE 0
// ************************ Simple culculations ************************ //
#define PI 3.141592653589723238
#define SQ(a) ((a)*(a))
#define TAN(theta) (tan((theta) * PI / 180.0))
// ************************ Consts ************************ //
#define MPY 20 //사진 Y축 최댓값
#define MPX 20 //사진 X축 최갯값
#define Angle1 30 //카메라 설치각 (Angle) 호도각 아님
#define Angle2 60 //카메라 촬영각 (Angle)
#define H 12 //카메라 설치높이(m)
#define H3 2 //차량 높이(m)
#define AngleII 60 //카메라 y축 촬영각
#define Trigt 10 //트리그 시간(두 점 사이의 시간)
// ************************ Class ************************ //
typedef struct _point {
double x;
double y;
}point;
typedef struct _point3D {
double x;
double y;
double z;
}point3D;
typedef struct _box {
point p1;
point p2;
}box;
typedef struct _velocity {
double x;
double y;
}velocity;
// ************************ Base Valuable ************************ //
// ************************ Graph Function ************************ //
point MakePoint(const box Bbox);
point3D GetLocaion(const point P); //점의 위치를 통해 3D위치를 알아낸다. (원점 = CAM)
point XY(const double Pix); // GetLocation 하위함수
point XZ(const double Pix, const double x1); // GetLocation 하위함수
double GetDis(const point3D P); //점가 CAM사이의 위치를 알아낸다.
velocity getVelocity(point3D P); //속도를 알아낸다.
//velocity getValPer(velocity V); // acselation을 알아낸다.
int dicision( point3D P, const double D, const velocity VL);
point3D KMS01_BOX(const box B);
point3D KMS01(const point B);
#endif
main.c
#include <stdio.h>
#include "KMS01.h"
int main(void) {
int x, y;
point3D V;
point P;
while (1) {
printf("f1st loc : ");
scanf_s("%d %d", &x, &y);
P.x = x;
P.y = y;
V = KMS01(P);
printf("LOC(%f, %f, %f) \n \n", V.x, V.y, V.z);
}
}
중요한 함수들은 모두 설명이 붙어있기에 설명은 생략합니다. KMS01()은 사진상의 점의 위치 [point]를 인자로 받아 실제 점의 위치[3Dpoint]를 반환합니다.
다른 프로그램