(1)에서 환경을 마친 후

 

다음의 명령어로 train을 진행할 수 있다.

 

python balloon.py --dataset ../../model/balloon/datasets --weights coco  --logs ../../model/balloon/logs train

 

학습한 h5파일로 inference하기 위해서 다음과 같이 한다

python balloon.py --dataset ../../model/balloon/datasets --weights ../../model/balloon/logs/balloon20220207T1941/mask_rcnn_balloon_0008.h5 --logs ../../model/balloon/logs --image ../../model/balloon/datasets/val/3800636873_ace2c2795f_b.jpg splash

 

 

 

 

 

 

 

1. anaconda에서 가상환경 생성(python 3.7)

conda create -n tf115 python==3.7
conda activate tf115

 

2. mask rcnn 을 다운받는다

git clone https://github.com/matterport/Mask_RCNN

 

3. keras 2.1.2 

pip install keras==2.1.2

4. pip install tensorflow-gpu==1.15.5

pip install tensorflow-gpu==1.15.5

 

5. 버전 확인을 해본다

6. 다음과 같이 폴더를 만든다

Mask_RCNN - model - balloon - datasets

                                         - logs

 

7. 1) https://github.com/matterport/Mask_RCNN/releases/download/v2.1/mask_rcnn_balloon.h5 파일을 다운받아서 

Mask_RCNN 폴더로 복사

2) https://github.com/matterport/Mask_RCNN/releases/download/v1.0/mask_rcnn_coco.h5 파일도 다운 받아서 Mask_RCNN 폴더로 복사

3) https://github.com/matterport/Mask_RCNN/releases/download/v2.1/balloon_dataset.zip  파일을 다운받아서 Mask_RCNN/model/balloon/datasets 폴더에 해제

8.  다음의 명령어로 설치

pip install scikit-image
#train 시 문제때문에 다음과 같이 수정해야 한다
pip install -U scikit-image==0.16.2

 

8. samples/balloon  폴더로 이동한 뒤 다음의 명령어로 inference 실행

python balloon.py --dataset ../../model/balloon/datasets --weights ../../mask_rcnn_balloon.h5 --logs ../../model/balloon/logs --image ../../model/balloon/datasets/val/3800636873_ace2c2795f_b.jpg splash

9. inference할 이미지

inferernce 결과 이미지가 현재 폴더에 남는다

 

** 2022년 6월 17일 - 설치테스트 시 아래의 명령을 한번 더 줘야 한다

pip install protobuf==3.20.*

 

 

 

 

 

* 웹알못의 기록

* 예제 1

 

* 서버

mux.HandleFunc("/get-time", func(rw http.ResponseWriter, r *http.Request) {
    ctime := Response{
        CurrentTime: time.Now().Format(time.RFC3339),
    }
    byteArray, err := json.Marshal(ctime)
    if err != nil {
        fmt.Println(err)
    }
    rw.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    rw.Header().Set("Content-Type", "application/json; charset=UTF-8")
    rw.Header().Set("Access-Control-Allow-Origin", "*")
    rw.WriteHeader(http.StatusOK)
    rw.Write(byteArray)
})

 

* 클라이언트

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
	<button id="gt">get time1</button>
    <div id="res"></div>
    <script>
        document.getElementById("gt").onclick = async (e) => {
            var req = await fetch("http://localhost:3000/get-time").then(r => r.json())
            document.getElementById("res").innerHTML = req.CurrentTime
			//alert(req.CurrentTime)
        }
    </script>
</body>
</html>

 

* 창로드

* 버튼을 누르면

* 예제 2

 

* 서버

func testHandler(w http.ResponseWriter, r *http.Request) {
	html := `<!DOCTYPE html>
	<html>
	<head>Title</head>
	<body>
	<fieldset style="width:670px">
	<legend>param1</legend>
	<label for="param1_id"  style="width:80px ">parameter1</label>
	<input id="param1_id" name="param1_id" type="text" style="width:550px"
	value="parameter1_value"/>
	<br/>
	<label for="param2_id"  style="width:80px ">parameter2</label>
	<input id="param2_id" name="param2_id" type="text" style="width:550px"
	value="parameter2_value"/>
	<br/>
	<button id="btn_send">send</button>
	<script>
	document.getElementById("btn_send").onclick = async (e) => {
		var obj = new Object();
		obj.argument1 = param1_id.value;
		obj.argument2 = param2_id.value;
		
		//alert(JSON.stringify(obj));
		
		var req = await fetch("test_send_func", {
			method: 'post',
			headers: {	'Content-Type': 'application/json;charset=utf-8', },
			body: JSON.stringify(obj)
		}).then(r => r.json())
		.then(function(json){
			//alert(JSON.stringify(json));
			document.getElementById("res").innerHTML = JSON.stringify(json)
		})
		


	}

	</script>
	</fieldset>

	<div id="res"></div>
	
	</body>
	</html>
	`

	fmt.Fprint(w, html)
}

type TestRecvObj struct {
	Arg1 string `json:"argument1"`
	Arg2 string `json:"argument2"`
}

func testSendHandler(w http.ResponseWriter, r *http.Request) {
	sendObj := new(TestRecvObj)
	//Client가 보낸 User
	err := json.NewDecoder(r.Body).Decode(sendObj)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprint(w, err)
		return
	}

	w.Header().Add("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	data, _ := json.Marshal(sendObj)
	fmt.Fprint(w, string(data))
}

//서버 등록
func NewHandler() http.Handler {
	mux := mux.NewRouter()
	mux.HandleFunc("/test_send_func", testSendHandler)
	mux.HandleFunc("/test", testHandler)
	return mux

}

 

* 화면 접속

* parameter 값을 바꾸고 버튼을 누르면

'기타' 카테고리의 다른 글

WPF 따라하기 - BackgroundWorker  (0) 2022.07.09
go언어 - Cross Compile (Windows -> Linux Arm)  (0) 2022.01.25
[javascript] 벽돌깨기 게임  (0) 2022.01.14
go언어 따라해보기(3) - slice  (0) 2021.12.13
go - web 따라해보기(1)  (0) 2021.12.12

* 윈도우에서 빌드 하고 Jetson TX2에서 실행하기위한 크로스컴파일 방법 기록

 

* hello.go

package main

import "fmt"

func main() {
	fmt.Print("Hello world")
}

* 기본적으로 빌드를 하면 윈도우용 실행화일이 생성된다(hello.exe)

 

* 빌드할 환경 변수를 설정

set GOOS=linux
set GOARCH=arm64

* 환경변수를 설정하고 나서 빌드하면 확장자 없는 hello 파일이 생성된다

 

* hello 파일을 WinSCP를 이용해서 파일을  Jetson TX2로 복사

 

* ssh로 접속

'기타' 카테고리의 다른 글

WPF 따라하기 - BackgroundWorker  (0) 2022.07.09
golang <-> javascript json통신  (0) 2022.01.27
[javascript] 벽돌깨기 게임  (0) 2022.01.14
go언어 따라해보기(3) - slice  (0) 2021.12.13
go - web 따라해보기(1)  (0) 2021.12.12

https://www.youtube.com/watch?v=1BeLiLwCS1c&list=PLy-g2fnSzUTDALoERcKDniql16SAaQYHF&index=3 참고

* 헤매는 바람에 기록으로 남겨둠

 

1. go언어 설치

  - 파일 설치(설치 과정 생략)

  - 설치 경로 : d:\Go

  - 다른 항목은 '다음'버튼을 눌러서 넘어감

 

2. 환경 변수 설정

  - GOPATH : d:\Work\golang\GoProject

  - GOROOT : d:\go

3. GOPATH\src 폴더에 다음과 같이 소스 복사

 

main.go
0.00MB
app.go
0.00MB
app_test.go
0.00MB

4. goconvey(실시간 테스트 도구 설치)

1) https://github.com/smartystreets/goconvey

command창을 열어서 다음의 명령을 수행한다(약간 시간이 걸린다)

go get github.com/smartystreets/goconvey

2) https://github.com/stretchr/testify

여기서 모든 항목을 가져오는 것이 아니라 assert만 가져올 것

> go get github.com/stretchr/testify/assert

 

5. GOPATH\bin폴더를 환경변수 Path에 추가한다

6. 테스트를 진행할 소스로 이동 후 goconvey를 실행한다

 

7. 웹브라우저로 localhost:8080을 접속하면 다음과 같은 화면 확인이 가능하다

 

* 계속 업데이트 예정 : 버튼을 누르면 시작

 

 

Gamedev Canvas Workshop

 

* 의문사항

1) 단독으로 브라우저에서 실행할 때는 paddle이 마우스 따라 다녔는데, 블로그에서는 그게 안되네.

 

* 수정 사항

1) [소스코드] Ball 클래스 추가

 

 

참조)

https://developer.mozilla.org/ko/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it

 

 

 

* slice 이것저것

더보기
package main

import "fmt"

func main() {
	//빈 동적 배열(slice) 생성
	var a []int
	fmt.Println("len(a) = ", len(a))
	fmt.Println("cap(a) = ", cap(a))

	/*
		길이 : 쓰고 있는 공간
		Capacity : 확보한 공간
	*/
	//길이 : 5, capacity : 5 동적 배열(slice) 생성
	b := []int{1, 2, 3, 4, 5}
	fmt.Println("len(b) = ", len(b))
	fmt.Println("cap(b) = ", cap(b))

	//길이 : 0, capacity : 8 동적 배열(slice) 생성
	c := make([]int, 0, 8)
	fmt.Println("len(c) = ", len(c))
	fmt.Println("cap(c) = ", cap(c))

	c = append(c, 1)
	fmt.Println("len(c) = ", len(c))
	fmt.Println("cap(c) = ", cap(c))

	//append시 capacity에 따라서 같은 slice가 반환될수도 있고
	//복사 생성후 만들어진 다른 slice가 반환될수도 있다

	d := []int{1, 2}
	e := append(d, 3)
	//주소번지를 출력
	fmt.Printf("d : %p, e : %p", d, e)
	fmt.Println()

	for i := 0; i < len(d); i++ {
		fmt.Printf("c[%d} : %d, ", i, d[i])
	}
	fmt.Println()
	fmt.Println("len(d) : ", len(d), ", cap(d) : ", cap(d))
	fmt.Println()

	for i := 0; i < len(e); i++ {
		fmt.Printf("e[%d] : %d, ", i, e[i])
	}
	fmt.Println()
	fmt.Println("len(e) : ", len(e), ", cap(e) : ", cap(e))
	fmt.Println()

	//append시 Capacity가 여유가 있어서 다른 메모리를 할당받지 않으면
	//같은 주소에 추가만 한다
	f := make([]int, 2, 4)
	g := append(f, 1)
	fmt.Printf("%p %p\n", f, g)

	f[0] = 1
	f[1] = 2
	fmt.Println(f)
	fmt.Println(g)

	g[0] = 4
	g[1] = 5
	fmt.Println(f)
	fmt.Println(g)
}

 

더보기
package main

import "fmt"

func main() {
	a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	//4번째 인덱스부터 6번째 인덱스 전까지
	fmt.Println("a[4:6] : ", a[4:6])
	//4번째 인덱스부터
	fmt.Println("a[4:] : ", a[4:])
	//처음부터 4번째 인덱스까지
	fmt.Println("a[:4] : ", a[:4])

	//b는 원 배열을 가르키는 포인터이므로
	//변경하게 되면 원 배열을 변경한다
	b := a[1:3]
	b[0] = 0
	b[1] = 1
	fmt.Println("a : ", a)

	//가장 뒷자리 숫자를 없애면서 그 숫자가 무엇인지 출력
	var Num int
	a, Num = RemoveBack(a)
	fmt.Println(a, Num)
	a, Num = RemoveBack(a)
	fmt.Println(a, Num)

	a, Num = RemoveFront(a)
	fmt.Println(Num, a)

	a, Num = RemoveFront(a)
	fmt.Println(Num, a)
}

func RemoveBack(a []int) ([]int, int) {
	return a[:len(a)-1], a[len(a)-1]
}

func RemoveFront(a []int) ([]int, int) {
	return a[1:len(a)], a[0]
}

* slice는 3개의 property로 구성된 구조체이다

  1) Pointer : 시작주소

  2) len : 갯수

  3) capacity : 최대갯수

더보기
package main

import "fmt"

func main() {

	var s []int

	s = make([]int, 3)

	s[0] = 100
	s[1] = 200
	s[2] = 300

	//초기 3개 생성시 갯수 3개, capcity : 3개
	fmt.Println(s, len(s), cap(s))

	s = append(s, 400, 500, 600, 700)

	//4개 추가시 갯수 7개, capcity : 8개
	fmt.Println(s, len(s), cap(s))
}

* 메모리를 공유하다 보니 문제가 발생하기도 한다

더보기
package main

import "fmt"

func main() {

	var s []int

	s = make([]int, 3, 8)

	s[0] = 100
	s[1] = 200
	s[2] = 300

	//초기 3개 생성시 갯수 3개, capcity : 3개
	fmt.Println(s, len(s), cap(s))

	t := append(s, 400)

	//4개 추가시 갯수 7개, capcity : 8개
	fmt.Println(s, len(s), cap(s))
	fmt.Println(t, len(t), cap(t))
	t = append(t, 500)

	fmt.Println(s, "S", len(s), cap(s))
	fmt.Println(t, "T", len(t), cap(t))

	s = append(s, 600)

	fmt.Println(s, "S", len(s), cap(s))
	fmt.Println(t, "T", len(t), cap(t))
}

 

 

 

유튜브 보고 따라 친건데, 다음과 같이 하면 브라우저에서 저 문구들을 볼 수 있다(포트번호는 3000번)

더보기
더보기
package main

import (
	"fmt"
	"net/http"
)

type fooHandler struct{}

func (f *fooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello Foo!")
}

//핸들러 함수를 등록할 수 있다
func barHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello Bar!")
}
func main() {
	//어떤 경로의 요청이 들어왔을 때
	//어떤 일을 할 것인지
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		//fmt.Fprint : writer에 출력하라
		fmt.Fprint(w, "Hello World")
	})

	http.HandleFunc("/bar", barHandler)

	http.Handle("/foo", &fooHandler{})

	http.ListenAndServe(":3000", nil)
}

서버 포트를 열어야 하므로 다음과 같이 보안 관련 다이얼로그가 뜨긴 한다

 

 

 

 

* http객체 대신 mux를 이용하여 똑같은 기능(아직 왜 다른지는 모름)

package main

import (
	"fmt"
	"net/http"
)

type fooHandler struct{}

func (f *fooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello Foo!")
}

func barHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello Bar!")
}
func main() {
	//어떤 경로의 요청이 들어왔을 때
	//어떤 일을 할 것인지
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		//fmt.Fprint : writer에 출력하라
		fmt.Fprint(w, "Hello World")
	})

	mux.HandleFunc("/bar", barHandler)

	mux.Handle("/foo", &fooHandler{})

	http.ListenAndServe(":3000", mux)
}

 

* http 클라이언트 request의 argument를 받아서 처리

func barHandler(w http.ResponseWriter, r *http.Request) {

	name := r.URL.Query().Get("name")
	if name == "" {
		name = "Empty"
	}

	fmt.Fprintf(w, "Hello %s!", name)
}

 

 

 

1. activity_main.xml

  - Layout : LinearLayout

  - orientaion : vertical

2. Containers > TabLayout을 붙여넣는다

  - height : wrap_content로 변경

  - 3개의 탭이 기본적으로 생성되어 있는데 각각의 텍스트를 '즐겨찾기', '노선', '정류장'으로 바꾼다

* 탭 레이아웃이 위로 올려붙는다

3. 탭 레이아웃 하단에는 FrameLayout을 붙인다

  - id : container

> 지금까지의 화면은 다음과 같이 표현된다

 

  4. Fragment생성

    1) Bookmark 

2) 경로

3) StationFragment 

* 탭 관련 초기 코드

더보기
	//선언
    enum eFragment{ Bookmark, Route, Station, FragMax};
    Fragment [] fragments = new Fragment[3];
    public int tabIndex = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	//.....

        tabIndex = eFragment.Bookmark.ordinal();
        fragments[eFragment.Bookmark.ordinal()] = new BookmarkFragment();
        fragments[eFragment.Route.ordinal()]    = new RouteFragment();
        fragments[eFragment.Station.ordinal()]  = new StationFragment();

        getSupportFragmentManager().beginTransaction().replace(R.id.container, fragments[tabIndex]).commit();

        TabLayout tabs = findViewById(R.id.tabs);
        tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int idx = tabs.getSelectedTabPosition();
                getSupportFragmentManager().beginTransaction().replace(R.id.container, fragments[idx]).commit();
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
	}

여기까지 하면 기본적으로 탭이 보이고 탭으로 Fragment가 바뀌는 것은 볼수 있다

* UTF8 문자열 한글자씩 출력하기

 

더보기
    s := "Hello 월드"

	s2 := []rune(s)
	for i := 0; i < len(s2); i++ {
		fmt.Print(string(s2[i], ","))
	}

결과

H,e,l,l,o, ,월,드,

 

* 배열 역순으로 놓기

더보기
arr := [5]int{1, 2, 3, 4, 5}

	for i := 0; i < len(arr)/2; i++ {
		arr[i], arr[4-i] = arr[4-i], arr[i]
	}

	fmt.Println(arr)

* swap (a와 b를 바꾸기)

더보기
a := 1
	b := 2

	a, b = b, a

	fmt.Print("a : ", a, ", b : ", b)

 

* 구조체 선언 및 할당

더보기
package main

import "fmt"

//구조체 선언
type Person struct {
	name string
	age  int
}

//구조체 멤버 함수
func (p Person) PrintName() {
	fmt.Print(p.name)
}

func main() {
	//초기화
	var p Person
	p1 := Person{"Name1", 15}
	p2 := Person{name: "Name2", age: 11}
	p3 := Person{name: "Name3"}
	p4 := Person{}

	fmt.Println(p, p1, p2, p3, p4)

	//멤버 변수 할당
	p.name = "new Name"
	p.age = 100

	fmt.Println(p)

	//멤버 함수 실행
	p.PrintName()
}

* 포인터 타입으로 선언

var p* Person

p := *Person{"Name", 20}

 

 

* 구조체를 멤버로 가지는 구조체

  - 일반함수와 멤버함수의 호출방법

더보기
package main

import "fmt"

//구조체 선언
type Student struct {
	name  string
	class int

	sungjuk Sungjuk
}

type Sungjuk struct {
	name  string
	grade string
}

//멤버함수
func (s Student) ViewSungjuk() {
	fmt.Println(s.sungjuk)
}

//멤버함수 : 입력
func (s Student) InputSungjuk(name string, grade string) {
	s.sungjuk.name = name
	s.sungjuk.grade = grade
}

//일반함수
func ViewSungjuk(s Student) {
	fmt.Println(s.sungjuk)
}

func main() {
	var s Student
	s.name = "철수"
	s.class = 1

	s.sungjuk.name = "수학"
	s.sungjuk.grade = "C"

	//멤버함수 호출
	s.ViewSungjuk()
	//일반함수 호출
	ViewSungjuk(s)

	//아래와 깉이 입력해도 바뀌지 않는다
	s.InputSungjuk("과학", "A")
	s.ViewSungjuk()
}

 

* 그런데, golang에서 구조체의 멤버함수라 해도 Call by Value 방식으로 구조체 인스턴스를 복사하는 방식이라 그냥 대입해서는 값이 바뀌지 않는다

 

* 포인터 기본 사용법

더보기
func main() {
	var a int
	var b int
	var p *int

	p = &a
	a = 3
	b = 2

	fmt.Println("a : ", a)
	fmt.Println("p : ", p)
	fmt.Println("*p : ", *p)

	p = &b

	fmt.Println("a : ", b)
	fmt.Println("p : ", p)
	fmt.Println("*p : ", *p)

}

 

* 포인터의 성질

더보기
func main() {
	var a int
	var b int

	a = 1
	b = 1

	IncVal(a)
	IncPointer(&b)

	fmt.Println("a : ", a)
	fmt.Println("b : ", b)
}

func IncVal(x int) {
	x++
}

func IncPointer(x *int) {
	*x = *x + 1
}

 

 

* 가비지 콜렉터 또는 허상참조(dangling reference) : C/C++과 달리 참조 값이 0이 될때까지 메모리 해제가 안된다

더보기
package main

import "fmt"

func main() {
	var p *int
	p = f1()
	fmt.Printf("P : %d", *p)
}

func f1() *int {
	a := 3
	return &a
}

 

 

 

 

 

 

+ Recent posts