오늘보다 더 나은 내일의 나에게_

비전공자의 IoT 국비 교육 수강일지 Day_85 본문

비전공자의 코딩일지

비전공자의 IoT 국비 교육 수강일지 Day_85

chan_96 2022. 4. 19. 18:08
728x90

머신러닝

# 분석용 서버 구축을 위한 flask 설치
!pip install flask
!pip install matplotlib
# 영상처리분야에서  많이 쓰는 라이브러리
!pip install opencv-python

from flask import Flask, request, Response, redirect
import io # 파이썬의 입출력을 도와주는 라이브러리
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import load_model # 딥러닝 모델 로딩 함수
import cv2 # opencv

# 플라스크 객체 생성
app = Flask(__name__)
# 학습된 모델 로딩
model = load_model('animal_keras_model.h5')

# 사용자 요청을 처리하기 위한 라우터 설정
@app.route('/', methods=['GET','POST'])
def index():
    return redirect("http://localhost:8081/Test/result.jsp")

@app.route('/predict', methods=['GET','POST'])
def predict():
    if request.method == 'POST':
        img = request.files['uploadImage']
        input_stream = io.BytesIO() #byte단위로 읽어들이는 통로
        img.save(input_stream) # 파일로부터 데이터를 읽기
        data = np.fromstring(input_stream.getvalue(),
                            dtype=np.uint8)
        real_img = cv2.imdecode(data,1) # 1 => 컬러사진
        real_img = cv2.cvtColor(real_img,cv2.COLOR_BGR2RGB) # BGR에서 RGB
        # 이미지 크기 조절하기
        resize_img = cv2.resize(real_img, dsize=(224,224), interpolation=cv2.INTER_AREA)
        
        # 이미지 확인하기
        #display(plt.imshow(real_img))
        #plt.show()
        
        # 이미지 정규화(-1 ~ 1)
        normalized_img = (np.array(resize_img,dtype=np.float32) / 127.0) - 1
        
        # 예측시킬 이미지 데이터를 넣을 변수
        data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
        
        # 불러온 numpy 타입의 이미지를 변수에 대입
        data[0] = normalized_img
        
        # 예측
        prediction = model.predict(data)
        index = np.argmax(prediction[0]) # 최대값의 인덱스
        
        
    return redirect("http://localhost:8081/Test/result.jsp?pre={}".format(index))

app.run() #서버 구동​
사진 업로드시 결과로 출력
=> opencv 기본 색상체계 BGR
코드 추가 후 출력 모습
real_img = cv2.cvtColor(real_img,cv2.COLOR_BGR2RGB) # BGR에서 RGB

이미지 크기 조절하기
resize_img = cv2.resize(real_img, dsize=(224,224), interpolation=cv2.INTER_AREA)​
사진 업로드 후 모델 예측 결과 출력
최종 결과 웹페이지 출력

OpenCV

  • opencv-python : main 모듈
  • opencv-contrib-python : 추가 extra 모듈

영상 불러오기

이미지 로딩 및 출력

# 라이브러리 import
import cv2

img = cv2.imread("./dog/10.png",cv2.IMREAD_COLOR) # 파일경로, 컬러 or 흑백 등으로 읽어들일 속성
#img = cv2.imread("./dog/1.png",cv2.IMREAD_GRAYSCALE) 흑백
cv2.imshow("image",img) # 새로운 창의 타이틀, 실제사진
cv2.waitKey(0) # 키보드 입력까지 대기 => 대기시간(ms)
cv2.destroyAllWindows()

실행 모습

matplotlib 활용 출력

import matplotlib.pyplot as plt

img = cv2.imread("./dog/1.png",
                 cv2.IMREAD_GRAYSCALE) # 파일경로, 컬러 or 흑백 등으로 읽어들일 속성
plt.imshow(img, cmap='gray')
plt.show()

흑백 출력 모습

img = cv2.imread("./dog/1.png",
                 cv2.IMREAD_COLOR) # 파일경로, 컬러 or 흑백 등으로 읽어들일 속성
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()

color 출력 모습

이진이미지

  • 컬러 이미지 : RGB 등의 색상으로 이루어진 이미지
  • 그레이 이미지 : 0 ~ 255사이의 흑백톤으로 이루어진 이미지
  • 이진 이미지 : 0 or 255 / 0 or 1로 구성된 이미지

이진 이미지 예시

동영상 로딩 및 출력

#반복문 이용해서 영상 출력하기
try : 
    print("영상로딩을 시작합니다..")
    video_cap = cv2.VideoCapture("./movie2.mp4")
    
    while True:
        ret,frame = video_cap.read()
        
        if ret :
            gray_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
            cv2.imshow("video",gray_frame)
            k = cv2.waitKey(33) # 초당 프레임수를 맞추기 위함 : 1000/24
        else:
            break;
            
        if k == 27 : #27번은 ESC
            break;
            
    cv2.destroyAllWindows()
    video_cap.release()
except :
    print("영상로딩 실패")


안드로이드

Volley, JSON

 

Volley

: Android App의 네트워킹을 더 쉽고, 무엇보다 더 빠르게 하는 HTTP 라이브러리

Volley 사용법

=> 프로젝트 Gradle Scripts 폴더에 build.gradle

링크

인터넷 권한 설정

=> AndroidManifest.xml에 아래 코드 추가

HTTP프로토콜 사용에 대한 속성

android:usesCleartextTraffic="true"

 

//RequestQueue객체 초기화
queue = Volley.newRequestQueue(MainActivity.this);

btnRequest.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

        //edtURL 객체로부터 사용자가 입력한 URL 데이터를 받아온 후
        //request객체에 요청주소로 전달해보기
        String url = "https://"+edtURL.getText().toString();

        //StringRequest객체 생성
        //new StringRequest(데이터전송방식, 요청주소, 응답리스너, 에러리스너)
        //데이터전송방식: GET or POST
        //요청주소: 요청할 주소 ex) http:~ or https:~
        //응답리스너: 서버에서 응답이 왔을 때 실행하는 리스너
        //오류리스너: 요청 or 응답에서 오류가 발생했을 때 실행하는 리스너
        request = new StringRequest(
                Request.Method.GET,
                url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        tvResult.setText(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(MainActivity.this,
                                error.toString(),
                                Toast.LENGTH_SHORT).show();
                    }
                }
        );

        //★★★
        //서버에 요청을 보내는 메소드
        queue.add(request);

    }
});

영화진흥위원회 오픈API를 활용한 JSON

링크

package com.example.ex0419;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class JsonActivity extends AppCompatActivity {

    TextView tvJSON;

    RequestQueue queue;
    StringRequest request;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_json);

        tvJSON = findViewById(R.id.tvJSON);
        queue = Volley.newRequestQueue(JsonActivity.this);

        int method = Request.Method.GET;
        String url = "http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt=20220418";

        request = new StringRequest(
                method,
                url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        //1. 문자열데이터 -> JSON객체로 변환
                        //2. JSON객체에서 "boxOfficeResult"로 데이터 접근
                        //3. 접근한 데이터(JSONObject)에서 "dailyBoxOfficeList"로 JSAONArray 데이터 접근
                        //4. 영화순위(rank), 영화명(movieNm)를 텍스트뷰에 출력

                        try {
                            JSONObject obj = new JSONObject(response);
                            JSONObject result = obj.getJSONObject("boxOfficeResult");
                            JSONArray jsonArr = result.getJSONArray("dailyBoxOfficeList");

                            String data = "";

                            //대량의 텍스트를 다룰 때 사용하는 객체
                            StringBuffer sb = new StringBuffer();

                            for(int i = 0;i < jsonArr.length();i++){
                                JSONObject movie = jsonArr.getJSONObject(i);
                                String rank = movie.getString("rank");
                                String movieNm = movie.getString("movieNm");

                                //data += rank + "." + movieNm + "\n";
                                sb.append(rank).append(".").append(movieNm).append("\n");
                            }
                            tvJSON.setText(sb.toString());
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }


                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(JsonActivity.this,
                                        error.toString(),
                                        Toast.LENGTH_SHORT).show();
                    }
                }
        );

        queue.add(request);

    }
}

 

728x90
Comments