화살표를 사진 위에 띄워서 이동가능하게 해줌
위치 관계 표를 좌표를 받으면 자동으로 만들기 위해 기능 추가 중
// STREET VIEW ver0.1 :: HANDONG
//
// Created by Seongho Hong / Mihyun Wendy Yang / on 2015. 7. 16..
// Copyright (c) 2015년 Seongho Hong. All rights reserved.
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <fstream> // 텍스트 파일 읽기
#include <conio.h> // 방향키 읽기
#include <math.h>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#define MAX_PICTURE 5
#define MAX_DIRECTION 4
#define MAX_TEXT 128
using namespace std;
using namespace cv;
//입력받은 점의 인덱스와 좌표값
typedef struct pts_info{
int index[4];
double direc[4]; //0=동, 1=서, 2=남, 3=북
double x, y;
}PTS_INFO;
// 마우스 이벤트 처리
typedef struct MouseChange{
int direction = -1;
int change = 0;
}MOUSECHANGE;
// 위치 관계표 만들 때 사용
double F_dist(double x1, double y1, double x2, double y2); // 두점 거리
double F_ang(double x1, double y1, double x2, double y2); // 두점 각도
// 스트리트 뷰 화면 구현에 사용
void showRelation(int(*map)[MAX_DIRECTION]); // 콘솔창에 사진간의 관계 보여주기
int getDirection(int inputKey); // eswn 으로 동서남북 이동
int getAsciiDirection(int inputKey); // 방향키로 동서남북 이동
String getFileName(int fileIndex); // 숫자 넣으면 .jpg로 만들어주기
int loadRelationTxt(); // 텍스트 파일에서 사진 관계 불러오기
// 스트리트 뷰 화면 컨트롤
void drawArrow(Mat img, int map[MAX_DIRECTION]); // 화살표 그리기
void callBackFunc(int event, int x, int y, int flags, void* userdata); // 마우스 클릭 이벤트
// 창 이름
const char* win_name = "STREET VIEW ver0.1 :: HANDONG";
int main(){
//위치 관계 정보 초기화
//int map[MAX_PICTURE][4] = { { -1, -1, -1, 1 }, { 5, -1, 0, 2 }, { -1, -1, 1, 3 }, { -1, -1, 2, 4 }, { -1, -1, 3, -1 }, { 6, 1, -1, -1 }, { 7, 5, -1, -1 }, { -1, 6, -1, -1 } }; //실외 관계도
int map[MAX_PICTURE][MAX_DIRECTION] = { { 1, -1, -1, -1 }, { -1, 0, 2, -1 }, { -1, -1, 3, 1 }, { -1, -1, 4, 2 }, { -1, -1, -1, 3 } }; //실내 관계도
//loadRelationTxt();
//변수 초기화
int index = 0;
showRelation(map);
int indexNum = 0;
//char keyDirection = ' ';
//인덱스 받고 첫화면
cout << "input index number : ";
cin >> indexNum;
if ((MAX_PICTURE < indexNum) || (indexNum < 0)){
cout << "Error : out of range !" << endl;
cout << "You have to input 0 < input < " << MAX_PICTURE << endl;
return -1;
}
Mat streetImage = imread(getFileName(indexNum)); //사진 불러오기
//방향으로 이동하기
//int dir = -1;
//int tempDir = -1;
MOUSECHANGE mouse;
namedWindow(win_name, 1);
setMouseCallback(win_name, callBackFunc, &mouse); // 마우스 클릭 이벤트 설정
drawArrow(streetImage, map[indexNum]);// 화살표 생성
imshow(win_name, streetImage);
while ((mouse.change == 0) || (map[indexNum][mouse.direction] == -1)){
waitKey(20);
}
//dir = getAsciiDirection(waitKey(0));
Mat temp = streetImage.clone();
while (mouse.direction != -1){
//system("cls"); //화면 지우기
//showRelation(map); // 관계표 띄워주기
//cout << "current index : " << indexNum << endl;
//cout << "input direction (e/w/s/n) ";
//cin >> keyDirection;
//dir = getAsciiDirection(waitKey(0));
if ((mouse.change==1)&&(map[indexNum][mouse.direction] != -1)){ // 가고자 하는 방향에 사진이 있을 때만
//mouse.change = 0;
indexNum = map[indexNum][mouse.direction]; //indexNUm에 그 사진 index 넣어주기
streetImage = imread(getFileName(indexNum), 1); // 사진 불러오기
drawArrow(streetImage, map[indexNum]); // 화살표 생성
imshow(win_name, streetImage);
//system("cls"); //화면 지우기
//showRelation(map); // 관계표 띄워주기
}
/*else{
cout << "그 방향으로 갈수없음" << endl;
}*/
mouse.change = 0;
if (mouse.change == 0){
waitKey(200);
}
}
//종료
destroyWindow(win_name);
return 0;
}
///////////////////////////////////
//////스트리트 뷰 화면 컨트롤//////
///////////////////////////////////
// jpg 파일 이름 받아오기
String getFileName(int fileIndex){
char temp[64];
char buf[128];
char extension[5] = ".jpg";
itoa(fileIndex, buf, 10);
strcat(buf, extension);
String dst = buf;
//cout << buf << endl;
return dst;
}
// index들의 관계 보여주기
void showRelation(int(*map)[MAX_DIRECTION]){
cout << "########### STREET VIEW ver1.0 ##########" << endl;
cout << "#index\t동\t서\t남\t북\t#" << endl;
for (int i = 0; i < MAX_PICTURE; i++){
cout << "# " << i << '\t';
for (int j = 0; j < MAX_DIRECTION; j++){
cout << map[i][j] << '\t';
}
cout << "#" << endl;
}
cout << "#########################################" << endl;
}
// ewsn 받아서 방향으로 바꿔주기
int getDirection(int inputKey){
int dir;
switch (inputKey)
{
case 'e':
dir = 0;
break;
case 'w':
dir = 1;
break;
case 's':
dir = 2;
break;
case 'n':
dir = 3;
break;
default:
dir = NULL;
break;
}
return dir;
}
// 방향키로 방향 받아오기
int getAsciiDirection(int inputKey){
int dir;
switch (inputKey)
{
case 2555904: // 동 2555904
dir = 0;
break;
case 2424832: //서 2424832
dir = 1;
break;
case 2621440: //남 2621440
dir = 2;
break;
case 2490368: //북 2490368
dir = 3;
break;
case 27: //esc
dir = -1;
break;
default:
dir = NULL;
break;
}
return dir;
}
int loadRelationTxt(){
ifstream inFile("relation.txt");
int index = 0;
int map[MAX_PICTURE][MAX_DIRECTION];
char inputString[MAX_TEXT];
char temp[MAX_TEXT];
char reset[MAX_TEXT];
while (!inFile.eof()){
inFile.getline(inputString, 100);
int i = 0;
int tempIndex = 0;
int direction = 0;
while (inputString[i] != '\0'){
i++;
}
index++;
}
for (int i = 0; i < MAX_PICTURE; i++){
for (int j = 0; j < MAX_DIRECTION; j++){
cout << map[MAX_PICTURE][MAX_DIRECTION];
}
cout << endl;
}
inFile.close();
return 0;
}
// 마우스 클릭 이벤트
void callBackFunc(int event, int x, int y, int flags, void* userdata){
MOUSECHANGE* mouse = (MOUSECHANGE*)userdata;
if (event == EVENT_LBUTTONDOWN){
cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
// if 화살표 위를 클릭하면 동, 서, 남, 북
if (((x>315) && (x < 355)) && (y>235) && (y < 245)){
mouse->direction = 0; //동
mouse->change = 1;
}
else if (((x>275) && (x < 315)) && (y>235) && (y < 245)){
mouse->direction = 1; //서
mouse->change = 1;
}
else if (((x>317) && (x < 325)) && (y>242) && (y < 273)){
mouse->direction = 2; //남
mouse->change = 1;
}
else if (((x>315) && (x < 355)) && (y>208) && (y < 238)){
mouse->direction = 3; //북
mouse->change = 1;
}
}
else if (event == EVENT_RBUTTONDOWN){
cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
}
else if (event == EVENT_MBUTTONDOWN){
cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
}
else if (event == EVENT_MOUSEMOVE){
cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;
}
}
//화살표 그려주기
void drawArrow(Mat img,int map[MAX_DIRECTION]){
if (map[0] != -1){ // 동쪽 있을 때
arrowedLine(img, Point(img.cols / 2, img.rows / 2), Point(img.cols / 2 +30, img.rows / 2 ), Scalar(0, 255, 0),5);
}
if (map[1] != -1){ // 서
arrowedLine(img, Point(img.cols / 2, img.rows / 2), Point(img.cols / 2 - 30, img.rows / 2), Scalar(0, 255, 0), 5);
}
if (map[2] != -1){ // 남
arrowedLine(img, Point(img.cols / 2, img.rows / 2), Point(img.cols / 2, img.rows / 2 + 30), Scalar(0, 255, 0), 5);
}
if (map[3] != -1){ // 북
arrowedLine(img, Point(img.cols / 2, img.rows / 2), Point(img.cols / 2, img.rows / 2 - 30), Scalar(0, 255, 0), 5);
}
}
/////////////////////////////////////
//////좌표로 부터 관계표 만들기//////
/////////////////////////////////////
//두 점의 거리 계산
double F_dist(double x1, double y1, double x2, double y2){
return sqrt(((x1 - x2)*(x1 - x2)) + ((y1 - y2)*(y1 - y2)));
}
//두 점의 각도 계산
double F_ang(double x1, double y1, double x2, double y2){
return (atan2((double)(y2 - y1), (double)(x2 - x1))*180.0f / 3.14159265);
}