728x90
반응형

1. 목적 

- [프로젝트> 그룹> 커뮤니케이션] 중 화상 회의/영상 채팅 기술을 구현하기 위한 연습코드

- TCP/IP 연결이 성립된 상태에서 1:1로 실시간 단방향 영상 전송을 구현

 

2. 구성

- 노트북 카메라 연결 -> 영상 캡쳐 후 파일 저장 -> 저장된 이미지 파일을 TCP/IP 소켓으로 전송해줌 -> 클라이언트에서는 파일로 받은 후 이미지를 보여줌

- 언어는 C/C++, 네트워크는 윈도우 소켓, 형식은 윈도우 실행파일(exe), 라이브러리는 동적로딩으로 활용(DLL 파일 따로 필요)

- 베이스 코드 : https://hwan001.tistory.com/54?category=747955

 

3. 코드

// windows socket
#include <winsock2.h>

// windows
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// opencv 
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;

#pragma comment(lib, "ws2_32.lib")

// Socket
#define IP "127.0.0.1"
#define PORT 6667
#define BUFSIZE 44000

void server();
void client(char *server_ip);
void client_send(SOCKET *sock);
void server_recv(SOCKET *client_sock);

int main() {
    int sel;
    char server_ip[21];
    printf("1: server\n2:client\n3.tmp file clear >");
    scanf_s("%d", &sel);
    switch (sel)
    {
    case 1: // 서버로 수신
        server();
        break;
    case 2: // 클라이언트로 전송
        printf("Server IP : ");
        scanf_s("%s", server_ip, 21);
        if (!strcmp(server_ip, "test")) {
            strcpy(server_ip, IP);
        }
        printf("%s\n", server_ip);
        client(server_ip);
        break;
    case 3: // 임시 파일 삭제
        remove("recv.jpg");
        remove("tmp.jpg");
        break;
    default:
        break;
    }
    return 0;
}

void client(char *server_ip) {
    // WSA  초기화
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    // 소켓 만들기
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addr;
    // 소켓 설정
    ZeroMemory(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(server_ip);
    addr.sin_port = htons(PORT);
    
    // TCP 연결 시도
    connect(sock, (SOCKADDR *)&addr, sizeof(addr));
    // 영상 전송
    client_send(&sock);
    // 마무리
    closesocket(sock);
    WSACleanup();
    remove("tmp.jpg");
}

void server() {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    // 소켓 만들기
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addr;
    // 소켓 설정
    ZeroMemory(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(PORT);
    
    bind(sock, (SOCKADDR *)&addr, sizeof(addr));
    listen(sock, 2);
    printf("listen ok\n");
    // 클라이언트 연결 요청 수락
    SOCKADDR_IN client_addr;
    ZeroMemory(&client_addr, sizeof(client_addr));
    int nlen = sizeof(client_addr);
    SOCKET client_sock = accept(sock, (SOCKADDR *)&client_addr, &nlen);
    // TCP 연결 수립
    printf("clinet IP : %s\n", inet_ntoa(client_addr.sin_addr));
    // 영상 수신
    server_recv(&client_sock);
    // 마무리
    closesocket(sock);
    WSACleanup();
    remove("recv.jpg");
}

// server function
void server_recv(SOCKET *client_sock) {
    FILE *fp = NULL;
    char buf[BUFSIZE];
    char buf2[BUFSIZE];
    Mat image;
    while (1) {
        // 이미지 파일 수신
        ZeroMemory(buf, NULL);
        fopen_s(&fp, "recv.jpg", "wb");
        // 버퍼 채우기
        recv(*client_sock, buf, sizeof(buf), 0);
        fwrite(buf, BUFSIZE, 1, fp);
        // 버퍼를 두번 받으면 딜레이가 사라진다??
        recv(*client_sock, buf2, sizeof(buf2), 0);
        fwrite(buf2, BUFSIZE, 1, fp);
        fclose(fp);
        // 이미지 보여주기
        image = imread("recv.jpg");
        if (image.empty()) { continue; }
        else imshow("recv", image);
        // esc 누르면 종료
        if (waitKey(33) > 0) break;
    }
}

// client fuction
void client_send(SOCKET *sock) {
    FILE *fp = NULL;
    Mat image;
    VideoCapture cap(0);
    char buf[BUFSIZE];
    while (1) {
        // 카메라 접근 후 파일로 작성
        cap.read(image);
        resize(image, image, Size(300, 400));
        imwrite("tmp.jpg", image);
        // 파일 열어서 읽고 전송
        ZeroMemory(buf, NULL);
        fopen_s(&fp, "tmp.jpg", "rb");
        fread(buf, BUFSIZE, 1, fp);
        send(*sock, buf, sizeof(buf), 0);
        fclose(fp);
    }
}
 

4. 결과

 

 

5. 추가 기능

- 양방향 영상 송수신, IOCP, P2P, 코덱

728x90
반응형
728x90
반응형

 

** UiPath 연습용 프로젝트, 현재 포스팅 정리 중

목표 : 매일 정해진 시간에 구독자에게 네이버 오늘의 회화를 보내주는 로봇 제작

 

 

1. 네이버 오늘의 회화 사이트

https://learn.dict.naver.com/conversation#/endic/

 

 

2. 프로세스 만들기

 

3. 플로우 차트 구성 

 

 

 

 

4. 느낀점 

- 작동은 되지만 딜레이는 어시스턴트나 오케스트레이터의 스케줄 기능을 활용하는 게 더 나음

 

 

 

 

 

 

728x90
반응형
728x90
반응형


** 개인 공부용, 내용 중 잘못된 부분이나 시간이 지나면서 변경된 부분이 있을 수 있음


1. 시작 (환경 설정)


Step 1. UiPath Studio Download -> https://www.uipath.com/ko/ 


Step 2. 커뮤니티 클라우드 에디션 선택 (무료)


Step 3. Sign up (아무거나 편한걸로 로그인 하면 됨.)


Step 4. 입력하다보면 나오는 화면. (블로그 글 작성 전에 만들어서 로그인시 앞에 내용이 생략됨, 대충 적어달라는 내용 적어주면 됨)



Step 5.  UiPath Studio 설치 

  


Step 6. UiPath Studio UI

** 오케스트레이터, 커뮤니티, 아카데미 둥 많은 유혹이 있지만 일단 스튜디오 설치부터 하기








2. UiPath Academy


Step 1. 자체적으로 운영하는 교육용 사이트로 검색으로 통해서 들어가도 좋고, 스튜디오 실행시 뜨는 팝업 창에서 들어가도 됨. (동영상 시청, 자습서, 아카데미 중 아카데미 클릭)


Step 2. 1번 (Learning Plan)클릭 후 2번, 3번 순으로 학습 (RPA Developer Foundation -> RPA Developer Advanced)


Step 3. Foundation 내부 자료들.


** 기초 문법 공부 하려면 하나씩 봐주면 됨.

728x90
반응형
728x90
반응형

 (size : 300) / (size : 640)


** 마지막 수정일 : 2020-12-19

** 찾아가면서 공부하는 중이라 정확하지 않은 정보가 있을 수 있음. (#F15F5F)

** 주석 (#22741C)


1. 용어 해설 (size : 12/ 10)

- RPA : Robotic Process Automation  https://namu.wiki/w/RPA

- UIPath Studio : UiPath 사의 RPA 툴  https://www.uipath.com/ko/

- UiPath Studio X : 컴퓨터 비전공자 버전

- Attended Robot : 유인로봇, 사람과 소통하면서 작업 시행 

- Unattended Robot : 무인로봇, 사람과 소통하지 않아도 알아서 정해진 작업 시행 

- Orchestrator : 로봇 관리, 모니터링, 원격 실행, 패키지/라이브러리 배포 등의 역할을 하는 서버



2. 해볼거

- 유인 로봇(Attended) : 웹에서 데이터 가져와서 파일로 저장, 파일 읽어서 데이터 정리

- 무인 로봇(Unattended) : 

- 오케스트레이터 : 서버 구축, 대량 데이터 처리(Queue 활용 병렬 처리), 패키지 배포, 라이브러리 배포, 프로세스 원격 실행 및 스케줄링

- 기타 : 카카오톡 자동응답, 리스트에 있는 사람들에게 메일 보내주기, 주식관련 정보 수집, 자동 수강신청(예매 등), OCR 기능



3. 느낀점 

- 윈도우에서만 작동하는게 아쉬움 

- 활용도는 개발자 역량에 따라 다름

- 회사 업무가 반복적이고 비효율적이라면  업무 효율을 올릴 수 있을 듯

- 툴에 코드가 거의 없음. (컴퓨터 비전공자도 쉽게 접근 가능 -> VB/ C# 코드 활용하긴 함)

728x90
반응형
728x90
반응형

http://shephexd.github.io/2018/06/21/Tensorflow_install.html


https://stackoverflow.com/questions/6622454/cuda-incompatible-with-my-gcc-version


http://noota.tistory.com/entry/우분투에서-gcc-손쉽게-설치하기



# 작성 중 - 20181215

728x90
반응형
728x90
반응형

 

 

 

1. OpenCV 다운로드 받기 [https://opencv.org/releases/]

- C드라이브에 설치해주면 'c:\\opencv' 가 기본 위치가 됨 

 

 

2. 프로젝트에 연결해주기 (프로젝트 클릭 후 Alt+Enter)

 

- VC++ 라이브러리> 포함 디렉터리 (include 폴더 선택), 

- VC++ 라이브러리> 라이브러리 디렉터리 (lib 폴더 선택) 

 

 

- 디버깅 > 환경   :   PATH=C:\opencv\build\x64\vc15\bin;%PATH%

 

 

-링커 > 입력> 추가 종속성   :    C:\opencv\build\x64\vc15\lib\opencv_world430d.lib   

 

 

** 추가 종속성 파일 입력 시 주의사항 : opencv_world430d.lib 파일은 디버그 모드로 컴파일 시 사용, 릴리즈에서 사용을 원하면 opencv_world430.lib 파일 경로 입력, 뒤에 숫자는 라이브러리 버전 별로 다름.

*** 위에 구성과 플랫폼을 변경해서 '디버그/ x86', '디버그/ x64', '릴리즈/x86', '릴리즈/ x64' 다 설정해주면 빌드 시 편함

 

 

 

3. 코드 내 라이브러리 호출

#include <stdio.h>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;

#pragma comment(lib, "ws2_32.lib")

int main() {
	return 0;
}
728x90
반응형
728x90
반응형

[Anaconda3] 


1. 아나콘다 리눅스 인스톨러(최신버전) 다운로드 (.sh 파일)

 링크 : https://www.anaconda.com/download/#linux


 


2. 설치된 폴더로 이동하여 설치 진행

 

 - 설치 : sudo bash Anaconda3-5.0.0.1-Linux-x86_64.sh

 - 설치시 설명은 ctrl-c, 대답은 전부 yes, 디렉토리는 본인 계정의 홈디렉토리로 해주면됨. ( ex) /home/hwan ) 

 - 홈 디렉토리로 설정 시 본인의 계정에서만 사용가능


3. 설치 확인 (python 실행)

 

 - 빨간색 줄처럼 뜨면 설치 완료

 - 뜨지 않는다면..

   export PYTHON_BIN_PATH = /home/'User Name'/ anaconda3/bin/python '

   명령어를 쳐주면됨. (아니면 개인 프로필 파일에(~/.profile) 직접 주가해줘도 됨)


4. Tensorflow 설치

 - cd ~/anaconda3/bin/ 

   :  설치된 아나콘다 디렉토리의 bin 디렉토리로 이동 (아나콘다 안에 tensorflow 라이브러리를 추가하기 위함)

 - sudo ./pip install tensorflow 

   : 아나콘다가 설치된 디렉토리 내에있는 pip를 사용하여 cpu 버전 텐서플로우를 설치


5. 설치 확인

 - python 실행후 import tensorflow

728x90
반응형
728x90
반응형

1. 파이썬 프로젝트를 만든다


2. python 환경 추가


3. Anaconda 4.2.0 체크 


4. import 하고 실행 -> 에러 안나면 성공



728x90
반응형
728x90
반응형


--------------------------------------------------------------------------------

 OS : Windows 10 64bits

  툴 : Visual Studio 2017 Community + Python, Anaconda3-4.2.0(64bits), TensorFlow (CPU)

--------------------------------------------------------------------------------


[ Visual Studio 2017 Community + Python ]


1. https://www.visualstudio.com/ko/vs/python




2. Community




3.  3개 체크, python 네이티브 개발 도구 선택


 



[ Anaconda3-4.2.0-Windows ]


1. Older version 설치 : https://www.continuum.io/downloads




2.  Anaconda3-4.2.0-Windows-x86_64 설치



3. 아나콘다 설치 : 둘 다 체크


[ Tensor Flow ]


 cmd -> pip install tensorflow





728x90
반응형
728x90
반응형

1. 라즈비안 OS 다운로드

- 링크 : https://www.raspberrypi.org/downloads/raspbian/

 

 

2. 이미지 기록용 툴 다운로드 (Win32Disklmager or UltraISO)

- 링크 : https://sourceforge.net/projects/win32diskimager/

 

3. 이미지 파일 기록

  1) 이미지 파일 선택

  2) Device 선택 (SD카드)

  3) write

 

 

4. 부팅 후 로그인

  - ID : pi

  - PW : raspberry

 

 

728x90
반응형
728x90
반응형

1. 목적

 esp8266을 사용하여 아두이노와 PC가 WiFi, Socket을 사용하여 TCP로 데이터를 주고 받음

 

2. 설명

 1) 만들 것 : 와이파이로 연결된 TCP/IP Client (Python)와 Server (esp8266)

 2) 재료 : esp8266, 아두이노 UNO, FTDI

esp8266
아두이노 UNO
FTDI

 

  3) 회로

    - 펌웨어 업로드 : esp8266의 통신속도를 늦춰주기 위해서 115200 -> 9600 (SoftwareSerial 라이브러리 사용위함)

1. esp의 RX는 FTDI의 TX와 TX는 RX와 연결

2. vcc는 3.3v

3. 펌웨어와 업로드 프로그램은 아래 참고 링크 참조.

 참고 : http://kocoafab.cc/tutorial/view/592

 

- UNO-esp8266 : arduino-esp8266-master 라이브러리 사용

1. 코드 내에서 Rx, Tx 할당한 핀에 연결, (RX-TX, TX-RX로 연결하면됨)

2. vcc는 3.3v

라이브러리 다운 : https://github.com/Diaoul/arduino-ESP8266

참고 : http://m.blog.naver.com/damtaja/220311412393

 

3. 코드

<Client>

# python 버전은 2.7.13
import socket

HOST = '' # esp8266에 접속후 ipconfig 명령을 통해 알아낸 게이트웨이의 주소를 입력하면됨. ex) 192.168.4.1
PORT = 4000 # 정해둔 포트 사용

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
print 'socket created'

HOST = raw_input("IP: ")

s.connect((HOST, PORT))
print 'connet success'

while 1:
    data = raw_input("data :")
    s.send(data)
    print 'send success'

s.close()

 

<Server>

#include <SoftwareSerial.h>
#include "ESP8266.h"

SoftwareSerial esp8266Serial = SoftwareSerial(10, 11); // 10번 11번을 rx tx로 설정함. (TIMEOUT 뜨면 아두이노에 연결한 rx tx 핀을 바꿔서 껴볼 것)
ESP8266 wifi = ESP8266(esp8266Serial);

void setup()
{
    Serial.begin(9600);

    // ESP8266
    esp8266Serial.begin(9600);
    wifi.begin();
    wifi.setTimeout(1000);

    /******        WiFi commands       ******/
    // setWifiMode
    Serial.print("setWifiMode: ");
    Serial.println(getStatus(wifi.setMode(ESP8266_WIFI_ACCESSPOINT))); // ESP를 AP로 사용

    // setAPConfiguration
    Serial.print("setAPConfiguration: ");
    Serial.println(getStatus(wifi.setAPConfiguration("ESP8266", "awesomelib", 10, ESP8266_ENCRYPTION_WPA_WPA2_PSK))); // SSID 이름, 비밀번호, 채널, 암호화방식 설정
    wifi.restart();

    // getAPConfiguration
    char ssid[32] = {};
    char password[63] = {};
    uint8_t channel;
    ESP8266Encryption encryption;

    wifi.getAPConfiguration(ssid, password, channel, encryption);
    
    Serial.print("getAPConfiguration: ");
    Serial.print(ssid);
    Serial.print(", pw: ");
    Serial.print(password);
    Serial.print(", ch: ");
    Serial.print(channel);
    Serial.print(", encrypt: ");
    Serial.println(encryption);//*/

    // setDHCP
    Serial.print("setDHCP STA: ");
    Serial.println(getStatus(wifi.setDHCP(ESP8266_WIFI_STATION, false)));
    Serial.print("setDHCP AP: ");
    Serial.println(getStatus(wifi.setDHCP(ESP8266_WIFI_ACCESSPOINT, true)));//*/

    // getIP
    IPAddress ip;
    Serial.print("getIP STA: ");
    Serial.print(getStatus(wifi.getIP(ESP8266_WIFI_STATION, ip)));
    Serial.print(" : ");
    Serial.println(ip);
    Serial.print("getIP AP: ");
    Serial.print(getStatus(wifi.getIP(ESP8266_WIFI_ACCESSPOINT, ip)));
    Serial.print(" : ");
    Serial.println(ip);//*/

    /****************************************/
    /******       TCP/IP commands      ******/
    /****************************************/
    // setMultipleConnections
    Serial.print("setMultipleConnections: ");
    Serial.println(getStatus(wifi.setMultipleConnections(true)));

    // createServer
    Serial.print("createServer: ");
    Serial.println(getStatus(wifi.createServer(4000)));
}

int power=0;

void loop()
{
	// Wi-Fi Command
    // getConnectedStations -> esp8266이 AP모드일 때 연결된 장비들 보여줌
    /*
    ESP8266Station stations[5];
    unsigned int stationCount;
    
    Serial.print("getConnectedStations: ");
    Serial.print(getStatus(wifi.getConnectedStations(stations, stationCount, 5)));
    Serial.print(" : ");
    Serial.println(stationCount);
    
    for (uint8_t i = 0; i < stationCount; i++) {
      Serial.print(" - ");
      Serial.print(stations[i].ip);
      Serial.print(" - ");
      for (uint8_t j = 0; j < 6; j++) {
        Serial.print(stations[i].mac[j], HEX);
        if (j < 5)
          Serial.print(":");
      }
      Serial.println();
    }
    delay(1000);
    */

    /****************************************/
    /******       TCP/IP commands      ******/
    /****************************************/
    // getConnectionStatus -> TCP 연결된 기기들 주소 보여줌
    /*
    ESP8266Connection connections[5];
    unsigned int connectionCount;
    
    Serial.print("getConnectionStatus: ");
    Serial.print(getStatus(wifi.getConnectionStatus(connectionStatus, connections, connectionCount)));
    Serial.print(" : ");
    Serial.println(connectionCount);
    
    for (int i = 0; i < connectionCount; i++) {
      Serial.print(" - Connection: ");
      Serial.print(connections[i].id);
      Serial.print(" - ");
      Serial.print(getProtocol(connections[i].protocol));
      Serial.print(" - ");
      Serial.print(connections[i].ip);
      Serial.print(":");
      Serial.print(connections[i].port);
      Serial.print(" - ");
      Serial.println(getRole(connections[i].role));
    }
    
    delay(5000);
    
    // 데이터 읽어옴
    unsigned int id;
    int length;
    int totalRead;
    char buffer[11] = {};

    if ((length = wifi.available()) > 0) {
      id = wifi.getId();
      totalRead = wifi.read(buffer, 10);

      if (length > 0) {
        Serial.print("Received ");
        Serial.print(totalRead);
        Serial.print("/");
        Serial.print(length);
        Serial.print(" bytes from client ");
        Serial.print(id);
        Serial.print(": ");
        Serial.println((char*)buffer);
      }
    }*/
}

String getStatus(bool status)
{
    if (status)
        return "OK";

    return "KO";
}

String getStatus(ESP8266CommandStatus status)
{
    switch (status) {
    case ESP8266_COMMAND_INVALID:
        return "INVALID";

    case ESP8266_COMMAND_TIMEOUT:
        return "TIMEOUT";

    case ESP8266_COMMAND_OK:
        return "OK";

    case ESP8266_COMMAND_NO_CHANGE:
        return "NO CHANGE";

    case ESP8266_COMMAND_ERROR:
        return "ERROR";

    case ESP8266_COMMAND_NO_LINK:
        return "NO LINK";

    case ESP8266_COMMAND_TOO_LONG:
        return "TOO LONG";

    case ESP8266_COMMAND_FAIL:
        return "FAIL";

    default:
        return "UNKNOWN COMMAND STATUS";
    }
}

String getRole(ESP8266Role role)
{
    switch (role) {
    case ESP8266_ROLE_CLIENT:
        return "CLIENT";

    case ESP8266_ROLE_SERVER:
        return "SERVER";

    default:
        return "UNKNOWN ROLE";
    }
}

String getProtocol(ESP8266Protocol protocol)
{
    switch (protocol) {
    case ESP8266_PROTOCOL_TCP:
        return "TCP";

    case ESP8266_PROTOCOL_UDP:
        return "UDP";

    default:
        return "UNKNOWN PROTOCOL";
    }
}

 

 cf. 라이브러리 기본 샘플 코드를 그대로 사용함, 라이브러리는 내부적으로 AT 커맨드를 사용함.

728x90
반응형
728x90
반응형

[살거]

1. 라즈베리 파이 3 세트 라즈베리파이3 + 공식 정품 엔클로져 + 방열판 세트

 

[사진 출처] 아이씨뱅큐 (https://www.icbanq.com/P007115238//?catg_code=120)

 

[특징]

- 블루투스, 와이파이 기능 추가됨. -> 무선 랜 카드 구입할 필요 x

- 64bit CPU -> 라즈비안 OS는 64bits가 없음 (32bits 설치해서 사용 중)

 

2.  파이카메라 : 라즈베리파이 카메라모듈 V2, 8MP (RPI 8MP CAMERA BOARD)

 

[사진 출처] 디바이스 마트 (http://www.devicemart.co.kr/1077951)

 

[특징]

- CSI 인터페이스 사용

 

[주의]

- 라즈베리 파이는 충전기 연결 시 바로 부팅됨.

- Micro SD 카드에 운영체제를 넣어서 사용하므로 마이크로SD 필요함. (이미 있어서 구입 안 함, 16GB 사용 중, class 10 이상 권장)

cf. UHS도 class 10 이상임, MLC 방식 추천 -> 잘 모르겠으면 링크

- 카메라와 파이를 원활하게 사용하려면 정격 출력 5V, 2A 이상은 되어야 할 듯.

cf. VEGA 스마트폰 충전기 사용 중 (정격 출력 5V, 2A)

- HDMI 포트 하나 있음 -> 모니터 연결은 알아서 잘할 것!

 

[링크]

- 디바이스 마트 : 파이 카메라 (약 3만원)

- 아이씨뱅큐 : 라즈베리 파이3 (약 5만원)

 

728x90
반응형

+ Recent posts